skytells 1.0.4 → 1.0.5

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 CHANGED
@@ -4,7 +4,7 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE)
5
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
6
6
  [![Docs](https://img.shields.io/badge/docs-skytells.ai-blueviolet?style=flat-square)](https://docs.skytells.ai/sdks/ts/)
7
- [![Skytells Learn | Docs](https://img.shields.io/badge/docs-skytells-learn-blueviolet?style=flat-square)](https://learn.skytells.ai/sdks/ts/)
7
+ [![Skytells Learn | Docs](https://img.shields.io/badge/skytells-learn-blue?style=flat-square)](https://learn.skytells.ai/sdks/ts/)
8
8
  [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square)](docs/Architecture.md)
9
9
 
10
10
  The official JavaScript/TypeScript SDK for interacting with the [Skytells](https://skytells.ai) API. Edge-compatible with Cloudflare Workers, Vercel Edge Functions, Netlify Edge Functions, and more.
@@ -126,6 +126,27 @@ console.log(response.id, response.status); // "pred_..." "pending"
126
126
  // Poll until complete
127
127
  const result = await skytells.wait(response);
128
128
  console.log(result.output);
129
+ ```
130
+
131
+ ### Server-side Await
132
+
133
+ For image models, pass `await: true` to have the server block and return the final output in one request — no polling required:
134
+
135
+ ```typescript
136
+ // Explicit server-side wait (image models only; video models ignore this)
137
+ const response = await skytells.predictions.create({
138
+ model: 'flux-pro',
139
+ input: { prompt: 'A cat' },
140
+ await: true,
141
+ });
142
+ console.log(response.output); // already populated
143
+
144
+ // Or let the SDK detect the model type automatically:
145
+ const response = await skytells.predictions.create(
146
+ { model: 'flux-pro', input: { prompt: 'A cat' } },
147
+ { compatibilityCheck: true, autoAwait: true }, // sets await:true only for image models
148
+ );
149
+ console.log(response.output);
129
150
 
130
151
  // Or with a timeout and progress (first GET is immediate; then every interval)
131
152
  const result = await skytells.wait(response, {
@@ -319,6 +340,8 @@ import type {
319
340
 
320
341
  Inference guard: pass **`{ compatibilityCheck: true }`** as the **second** argument to **`predict`** / **`predictions.create`**, **fourth** to **`run`** (use `undefined` for `onProgress` if unused), or **second** to **`queue`** — never inside the JSON body.
321
342
 
343
+ Auto server-side await for image models: also pass **`autoAwait: true`** alongside `compatibilityCheck: true` in `predictions.create()`.
344
+
322
345
  ## Safety
323
346
 
324
347
  Proactive content moderation and response parsing via `client.safety`:
package/dist/client.cjs CHANGED
@@ -24,7 +24,7 @@ const { Chat } = require("./chat.js");
24
24
  const { Responses } = require("./responses.js");
25
25
  const { Embeddings } = require("./embeddings.js");
26
26
  const { Safety } = require("./safety.js");
27
- const { PredictionStatus } = require("./types/index.js");
27
+ const { PredictionStatus, ModelType } = require("./types/index.js");
28
28
  const { Webhook, createWebhookListener } = require("./webhooks.js");
29
29
  const { SkytellsError } = require("./types/shared.types.js");
30
30
  const DEFAULT_POLL_INTERVAL = 5000;
@@ -287,28 +287,41 @@ export class PredictionsAPI {
287
287
  * @param payload.input - Key-value input parameters for the model.
288
288
  * @param payload.webhook - Optional webhook to receive events.
289
289
  * @param payload.stream - Enable streaming (default: `false`).
290
+ * @param payload.await - When `true`, the server blocks until the prediction completes and returns
291
+ * the final result in one response. Ignored by the server for video predictions (returns
292
+ * immediately regardless). Defaults to `false`.
290
293
  * @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'`.
294
+ * @returns The prediction response with final `output` when `payload.await` is `true`,
295
+ * or `status: 'pending'` / `'starting'` when `false`.
292
296
  * @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits).
293
297
  *
294
298
  * @example
295
299
  * ```ts
300
+ * // Fire and poll manually
296
301
  * const prediction = await client.predictions.create({
297
302
  * model: "flux-pro",
298
303
  * input: { prompt: "An astronaut riding a unicorn" },
299
304
  * });
300
- * console.log(prediction.id, prediction.status); // "pending"
301
- *
302
- * // Wait for it to finish
303
305
  * const result = await client.wait(prediction);
304
306
  * console.log(result.output);
307
+ *
308
+ * // Server-side wait — returns final output immediately (not supported for video models)
309
+ * const prediction = await client.predictions.create({
310
+ * model: "flux-pro",
311
+ * input: { prompt: "An astronaut riding a unicorn" },
312
+ * await: true,
313
+ * });
314
+ * console.log(prediction.output);
305
315
  * ```
306
316
  */
307
317
  async create(payload, sdk) {
318
+ let shouldAutoAwait = false;
308
319
  if (this.onBeforePredict) {
309
- await this.onBeforePredict(payload, sdk);
320
+ ({ shouldAutoAwait } = await this.onBeforePredict(payload, sdk));
310
321
  }
311
- return this.http.request('POST', ENDPOINTS.PREDICT, predictionBodyForHttp(payload, { await: false }));
322
+ // payload.await takes explicit priority; autoAwait only applies when await is not set by the caller
323
+ const awaitValue = payload.await !== undefined ? payload.await : shouldAutoAwait || false;
324
+ return this.http.request('POST', ENDPOINTS.PREDICT, predictionBodyForHttp(payload, { await: awaitValue }));
312
325
  }
313
326
  /**
314
327
  * Fetches a prediction by its ID.
@@ -493,7 +506,7 @@ export class SkytellsClient {
493
506
  */
494
507
  get predictions() {
495
508
  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));
509
+ this._predictions = new PredictionsAPI(this.http, (p, sdk) => this._resolveBeforePredict(p, sdk));
497
510
  }
498
511
  return this._predictions;
499
512
  }
@@ -806,6 +819,24 @@ export class SkytellsClient {
806
819
  }
807
820
  return model;
808
821
  }
822
+ /**
823
+ * @internal Runs compatibility guard and resolves autoAwait from model type.
824
+ * Returns `{ shouldAutoAwait }` for use by `PredictionsAPI.create`.
825
+ */
826
+ async _resolveBeforePredict(payload, sdk) {
827
+ await this._maybeCompatibilityGuard(payload.model, sdk === null || sdk === void 0 ? void 0 : sdk.compatibilityCheck);
828
+ if ((sdk === null || sdk === void 0 ? void 0 : sdk.autoAwait) !== true || (sdk === null || sdk === void 0 ? void 0 : sdk.compatibilityCheck) !== true) {
829
+ return { shouldAutoAwait: false };
830
+ }
831
+ try {
832
+ const modelData = await this._getModelForCompatibilityCheck(payload.model);
833
+ const isImage = modelData.type === ModelType.IMAGE;
834
+ return { shouldAutoAwait: isImage };
835
+ }
836
+ catch (_a) {
837
+ return { shouldAutoAwait: false };
838
+ }
839
+ }
809
840
  /**
810
841
  * @internal When `compatibilityCheck === true`, throws SDK_ERROR if the model is chat-only here.
811
842
  */
package/dist/client.d.ts CHANGED
@@ -191,7 +191,9 @@ export declare class PredictionsAPI {
191
191
  private http;
192
192
  private onBeforePredict?;
193
193
  /** @internal */
194
- constructor(http: HTTP, onBeforePredict?: (payload: PredictionRequest, sdk?: PredictionSdkOptions) => Promise<void>);
194
+ constructor(http: HTTP, onBeforePredict?: (payload: PredictionRequest, sdk?: PredictionSdkOptions) => Promise<{
195
+ shouldAutoAwait: boolean;
196
+ }>);
195
197
  /**
196
198
  * Creates a prediction in the background (does not wait for completion).
197
199
  *
@@ -203,21 +205,31 @@ export declare class PredictionsAPI {
203
205
  * @param payload.input - Key-value input parameters for the model.
204
206
  * @param payload.webhook - Optional webhook to receive events.
205
207
  * @param payload.stream - Enable streaming (default: `false`).
208
+ * @param payload.await - When `true`, the server blocks until the prediction completes and returns
209
+ * the final result in one response. Ignored by the server for video predictions (returns
210
+ * immediately regardless). Defaults to `false`.
206
211
  * @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'`.
212
+ * @returns The prediction response with final `output` when `payload.await` is `true`,
213
+ * or `status: 'pending'` / `'starting'` when `false`.
208
214
  * @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits).
209
215
  *
210
216
  * @example
211
217
  * ```ts
218
+ * // Fire and poll manually
212
219
  * const prediction = await client.predictions.create({
213
220
  * model: "flux-pro",
214
221
  * input: { prompt: "An astronaut riding a unicorn" },
215
222
  * });
216
- * console.log(prediction.id, prediction.status); // "pending"
217
- *
218
- * // Wait for it to finish
219
223
  * const result = await client.wait(prediction);
220
224
  * console.log(result.output);
225
+ *
226
+ * // Server-side wait — returns final output immediately (not supported for video models)
227
+ * const prediction = await client.predictions.create({
228
+ * model: "flux-pro",
229
+ * input: { prompt: "An astronaut riding a unicorn" },
230
+ * await: true,
231
+ * });
232
+ * console.log(prediction.output);
221
233
  * ```
222
234
  */
223
235
  create(payload: PredictionRequest, sdk?: PredictionSdkOptions): Promise<PredictionResponse>;
@@ -565,6 +577,11 @@ export declare class SkytellsClient {
565
577
  * Returns model metadata for the inference compatibility check, using {@link _prefetchedModelCache} when fresh.
566
578
  */
567
579
  private _getModelForCompatibilityCheck;
580
+ /**
581
+ * @internal Runs compatibility guard and resolves autoAwait from model type.
582
+ * Returns `{ shouldAutoAwait }` for use by `PredictionsAPI.create`.
583
+ */
584
+ private _resolveBeforePredict;
568
585
  /**
569
586
  * @internal When `compatibilityCheck === true`, throws SDK_ERROR if the model is chat-only here.
570
587
  */
package/dist/client.js CHANGED
@@ -24,7 +24,7 @@ import { Chat } from './chat.js';
24
24
  import { Responses } from './responses.js';
25
25
  import { Embeddings } from './embeddings.js';
26
26
  import { Safety } from './safety.js';
27
- import { PredictionStatus } from './types/index.js';
27
+ import { PredictionStatus, ModelType } from './types/index.js';
28
28
  import { Webhook, createWebhookListener } from './webhooks.js';
29
29
  import { SkytellsError } from './types/shared.types.js';
30
30
  const DEFAULT_POLL_INTERVAL = 5000;
@@ -287,28 +287,41 @@ export class PredictionsAPI {
287
287
  * @param payload.input - Key-value input parameters for the model.
288
288
  * @param payload.webhook - Optional webhook to receive events.
289
289
  * @param payload.stream - Enable streaming (default: `false`).
290
+ * @param payload.await - When `true`, the server blocks until the prediction completes and returns
291
+ * the final result in one response. Ignored by the server for video predictions (returns
292
+ * immediately regardless). Defaults to `false`.
290
293
  * @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'`.
294
+ * @returns The prediction response with final `output` when `payload.await` is `true`,
295
+ * or `status: 'pending'` / `'starting'` when `false`.
292
296
  * @throws {SkytellsError} On API errors (invalid input, model not found, insufficient credits).
293
297
  *
294
298
  * @example
295
299
  * ```ts
300
+ * // Fire and poll manually
296
301
  * const prediction = await client.predictions.create({
297
302
  * model: "flux-pro",
298
303
  * input: { prompt: "An astronaut riding a unicorn" },
299
304
  * });
300
- * console.log(prediction.id, prediction.status); // "pending"
301
- *
302
- * // Wait for it to finish
303
305
  * const result = await client.wait(prediction);
304
306
  * console.log(result.output);
307
+ *
308
+ * // Server-side wait — returns final output immediately (not supported for video models)
309
+ * const prediction = await client.predictions.create({
310
+ * model: "flux-pro",
311
+ * input: { prompt: "An astronaut riding a unicorn" },
312
+ * await: true,
313
+ * });
314
+ * console.log(prediction.output);
305
315
  * ```
306
316
  */
307
317
  async create(payload, sdk) {
318
+ let shouldAutoAwait = false;
308
319
  if (this.onBeforePredict) {
309
- await this.onBeforePredict(payload, sdk);
320
+ ({ shouldAutoAwait } = await this.onBeforePredict(payload, sdk));
310
321
  }
311
- return this.http.request('POST', ENDPOINTS.PREDICT, predictionBodyForHttp(payload, { await: false }));
322
+ // payload.await takes explicit priority; autoAwait only applies when await is not set by the caller
323
+ const awaitValue = payload.await !== undefined ? payload.await : shouldAutoAwait || false;
324
+ return this.http.request('POST', ENDPOINTS.PREDICT, predictionBodyForHttp(payload, { await: awaitValue }));
312
325
  }
313
326
  /**
314
327
  * Fetches a prediction by its ID.
@@ -493,7 +506,7 @@ export class SkytellsClient {
493
506
  */
494
507
  get predictions() {
495
508
  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));
509
+ this._predictions = new PredictionsAPI(this.http, (p, sdk) => this._resolveBeforePredict(p, sdk));
497
510
  }
498
511
  return this._predictions;
499
512
  }
@@ -806,6 +819,24 @@ export class SkytellsClient {
806
819
  }
807
820
  return model;
808
821
  }
822
+ /**
823
+ * @internal Runs compatibility guard and resolves autoAwait from model type.
824
+ * Returns `{ shouldAutoAwait }` for use by `PredictionsAPI.create`.
825
+ */
826
+ async _resolveBeforePredict(payload, sdk) {
827
+ await this._maybeCompatibilityGuard(payload.model, sdk === null || sdk === void 0 ? void 0 : sdk.compatibilityCheck);
828
+ if ((sdk === null || sdk === void 0 ? void 0 : sdk.autoAwait) !== true || (sdk === null || sdk === void 0 ? void 0 : sdk.compatibilityCheck) !== true) {
829
+ return { shouldAutoAwait: false };
830
+ }
831
+ try {
832
+ const modelData = await this._getModelForCompatibilityCheck(payload.model);
833
+ const isImage = modelData.type === ModelType.IMAGE;
834
+ return { shouldAutoAwait: isImage };
835
+ }
836
+ catch (_a) {
837
+ return { shouldAutoAwait: false };
838
+ }
839
+ }
809
840
  /**
810
841
  * @internal When `compatibilityCheck === true`, throws SDK_ERROR if the model is chat-only here.
811
842
  */
@@ -53,6 +53,28 @@ export interface PredictionSdkOptions {
53
53
  * (smaller when `runtime: "edge"`).
54
54
  */
55
55
  compatibilityCheck?: boolean;
56
+ /**
57
+ * When `true`, automatically sets `await: true` on the request if the model type is `image`
58
+ * (or `image_megapixel`), causing the server to block and return the final output in one response.
59
+ *
60
+ * **Requires `compatibilityCheck: true`** — the model type is read from the same cached `GET /model/{slug}`
61
+ * call made by the compatibility guard. Silently falls back to `await: false` if the model fetch fails
62
+ * or the type is not an image type (e.g. video models ignore server-side await).
63
+ *
64
+ * `payload.await` always takes priority: if you explicitly set `await: true` or `await: false` on the
65
+ * request, `autoAwait` is ignored.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * const prediction = await client.predictions.create(
70
+ * { model: 'flux-pro', input: { prompt: '...' } },
71
+ * { compatibilityCheck: true, autoAwait: true },
72
+ * );
73
+ * // For image models: prediction.output is already populated
74
+ * // For video/audio models: prediction.status is 'pending', poll with client.wait()
75
+ * ```
76
+ */
77
+ autoAwait?: boolean;
56
78
  }
57
79
  /**
58
80
  * Options for {@link SkytellsClient.run}.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skytells",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Official Skytells JavaScript/TypeScript SDK - Edge compatible",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",