skytells 1.0.3 → 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 (45) hide show
  1. package/README.md +136 -28
  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 +553 -61
  6. package/dist/client.d.ts +247 -22
  7. package/dist/client.js +553 -61
  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 -9
  12. package/dist/endpoints.d.ts +16 -0
  13. package/dist/endpoints.js +25 -9
  14. package/dist/http.cjs +612 -60
  15. package/dist/http.d.ts +131 -3
  16. package/dist/http.js +612 -60
  17. package/dist/index.cjs +51 -8
  18. package/dist/index.d.ts +45 -9
  19. package/dist/index.js +51 -8
  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 +1 -1
  37. package/dist/types/orchestrator.types.d.ts +61 -0
  38. package/dist/types/orchestrator.types.js +7 -0
  39. package/dist/types/predict.types.d.ts +48 -11
  40. package/dist/types/shared.types.d.ts +119 -6
  41. package/dist/types/shared.types.js +58 -2
  42. package/dist/webhooks.cjs +310 -0
  43. package/dist/webhooks.d.ts +171 -0
  44. package/dist/webhooks.js +310 -0
  45. package/package.json +26 -2
package/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Skytells JavaScript/TypeScript SDK
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/skytells.svg?style=flat-square)](https://www.npmjs.com/package/skytells)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
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/)
8
+ [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square)](docs/Architecture.md)
9
+
3
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.
4
11
 
5
12
  Generate text, photos, videos, avatars, audio, music, and more using Skytells' own models and partner models — all through a single API. [Explore models →](https://skytells.ai/explore/models)
@@ -14,6 +21,28 @@ yarn add skytells
14
21
  pnpm add skytells
15
22
  ```
16
23
 
24
+ ## Import
25
+
26
+ ```ts
27
+ // Recommended: factory (default export)
28
+ import Skytells from 'skytells';
29
+
30
+ // Direct class import
31
+ import { SkytellsClient } from 'skytells';
32
+
33
+ // Both in one import
34
+ import Skytells, { SkytellsClient } from 'skytells';
35
+ ```
36
+
37
+ Optionally, you may use the named factory:
38
+
39
+ ```ts
40
+ import { createClient } from 'skytells';
41
+
42
+ const client = createClient('sk-your-api-key');
43
+ // equivalent to: Skytells('sk-your-api-key') and new SkytellsClient('sk-your-api-key')
44
+ ```
45
+
17
46
  ## Quick Start
18
47
 
19
48
  ```typescript
@@ -29,6 +58,13 @@ const prediction = await skytells.run('truefusion', {
29
58
  console.log(prediction.outputs()); // "https://delivery.skytells.cloud/..."
30
59
  ```
31
60
 
61
+ **Orchestrator** (workflows / webhook triggers) uses a separate `wfb_…` key. Optional **`orchestratorApiKey`** on the same client keeps both products in one place — the SDK applies the right auth per API ([Orchestrator.md](docs/Orchestrator.md)):
62
+
63
+ ```typescript
64
+ const client = Skytells('sk-…', { orchestratorApiKey: 'wfb_…' });
65
+ await client.orchestrator.webhooks.execute(workflowId, { /* JSON body */ });
66
+ ```
67
+
32
68
  ### Obtaining an API Key
33
69
 
34
70
  1. Log in at [Skytells Portal](https://www.skytells.ai/auth/signin) or [Create an Account](https://www.skytells.ai/auth/signup)
@@ -91,10 +127,11 @@ console.log(response.id, response.status); // "pred_..." "pending"
91
127
  const result = await skytells.wait(response);
92
128
  console.log(result.output);
93
129
 
94
- // Or with a timeout and progress
130
+ // Or with a timeout and progress (first GET is immediate; then every interval)
95
131
  const result = await skytells.wait(response, {
96
- interval: 2000, // poll every 2s
97
- maxWait: 120000, // timeout after 2 min
132
+ interval: 2000, // delay between polls after the first refresh
133
+ maxWait: 120000, // wall-clock limit WAIT_TIMEOUT
134
+ // signal: ac.signal, // optional AbortSignal → ABORTED
98
135
  }, (p) => console.log(p.status));
99
136
  ```
100
137
 
@@ -120,18 +157,14 @@ const completed = await Promise.all(results.map(r => skytells.wait(r)));
120
157
  ### Prediction Lifecycle
121
158
 
122
159
  ```typescript
123
- // Cancel a running prediction
160
+ // Cancel a running prediction (works while status is pending/starting/processing)
124
161
  await prediction.cancel();
125
- // or by ID
126
- await skytells.cancelPrediction('pred_abc123');
127
162
 
128
- // Delete a prediction and its assets
163
+ // Delete a prediction and all its output assets from storage
129
164
  await prediction.delete();
130
- // or by ID
131
- await skytells.deletePrediction('pred_abc123');
132
165
 
133
- // Stream endpoint
134
- const stream = await skytells.streamPrediction('pred_abc123');
166
+ // Fetch stream metadata for a prediction
167
+ const stream = await prediction.stream();
135
168
  console.log(stream.urls?.stream);
136
169
  ```
137
170
 
@@ -175,18 +208,20 @@ import Skytells from 'skytells';
175
208
 
176
209
  const skytells = Skytells('your-api-key', {
177
210
  baseUrl: 'https://your-proxy.example.com/v1', // Custom API URL
178
- timeout: 30000, // Request timeout in ms (default: 60000)
179
- headers: { 'X-Custom-Header': 'value' }, // Extra headers on every request
211
+ timeout: 30000, // Omit for defaults: 60000 normally, 25000 when runtime: 'edge'
212
+ headers: { 'X-Custom-Header': 'value' }, // Extra headers on every request
180
213
  retry: {
181
- retries: 3, // Retry failed requests (default: 0)
182
- retryDelay: 1000, // Delay between retries in ms (default: 1000)
183
- retryOn: [429, 500, 502, 503, 504], // Status codes to retry (default)
214
+ retries: 3, // Retry failed requests (default: 0)
215
+ retryDelay: 1000, // Base delay; actual wait is retryDelay * (attempt + 1) per retry
216
+ retryOn: [429, 500, 502, 503, 504],
184
217
  },
185
- fetch: (url, opts) => // Custom fetch (e.g. Next.js cache workaround)
186
- fetch(url, { ...opts, cache: 'no-store' }),
218
+ fetch: (url, opts) => fetch(url, { ...opts, cache: 'no-store' }),
219
+ // runtime: 'edge', // Vercel Edge / Workers: shorter default timeout, smaller compat cache, one-time hints
187
220
  });
188
221
  ```
189
222
 
223
+ Inspect resolved settings: **`skytells.config`** (`requestTimeoutMs`, `prefetchMaxSlugs`, `runtime`) and **`skytells.runtime`**.
224
+
190
225
  ## The Prediction Object
191
226
 
192
227
  When you call `skytells.run()`, you get a `Prediction` object:
@@ -213,15 +248,17 @@ When you call `skytells.run()`, you get a `Prediction` object:
213
248
 
214
249
  ## Edge Compatibility
215
250
 
216
- This SDK works in any environment with Fetch API support:
251
+ This SDK works in any environment with **Fetch** and (for **webhook HMAC verification**) **`crypto.subtle`** (Web Crypto):
217
252
 
218
253
  - **Cloudflare Workers & Pages**
219
254
  - **Vercel Edge Functions**
220
255
  - **Netlify Edge Functions**
221
256
  - **Deno Deploy**
222
- - **Node.js 18+**
257
+ - **Node.js** — use **19+** for global `crypto.subtle`, or verify webhooks in an environment that provides it
223
258
  - **Browsers**
224
259
 
260
+ Pass **`{ runtime: 'edge' }`** when constructing the client on edge/serverless so the SDK uses a **25s default request timeout** (if you don’t set `timeout`) and a **smaller** inference-compat model cache; see **`EDGE_DEFAULT_REQUEST_TIMEOUT_MS`** / **`EDGE_PREFETCH_MAX_SLUGS`** in the package exports.
261
+
225
262
  ## Error Handling
226
263
 
227
264
  All methods throw `SkytellsError` on failure:
@@ -254,10 +291,12 @@ try {
254
291
  | `RATE_LIMIT_EXCEEDED` | Too many requests |
255
292
  | `PREDICTION_FAILED` | Prediction completed with failure |
256
293
  | `WAIT_TIMEOUT` | Polling exceeded `maxWait` |
294
+ | `ABORTED` | `wait()` / `run` polling stopped via `AbortSignal` |
295
+ | `SDK_ERROR` | Client guard (OpenAI-compat model + `compatibilityCheck`, missing `prediction.id`, webhook crypto unavailable, …) |
257
296
  | `REQUEST_TIMEOUT` | HTTP request timed out |
258
297
  | `NETWORK_ERROR` | Connection issue |
259
298
  | `SERVER_ERROR` | Non-JSON response from server |
260
- | `INVALID_JSON` | Server returned invalid JSON |
299
+ | `INVALID_JSON` | Declared JSON but body failed `JSON.parse` |
261
300
 
262
301
  ## TypeScript
263
302
 
@@ -266,16 +305,55 @@ Full type definitions are included. Key types:
266
305
  ```typescript
267
306
  import type {
268
307
  PredictionRequest,
308
+ PredictionSdkOptions,
269
309
  PredictionResponse,
270
310
  PredictionStatus,
271
311
  RunOptions,
272
312
  WaitOptions,
273
313
  Model,
274
314
  ClientOptions,
315
+ SkytellsRuntime,
275
316
  PaginatedResponse,
276
317
  } from 'skytells';
277
318
  ```
278
319
 
320
+ 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
+
322
+ ## Safety
323
+
324
+ Proactive content moderation and response parsing via `client.safety`:
325
+
326
+ ```typescript
327
+ import Skytells, { SafetyTemplates } from 'skytells';
328
+
329
+ const client = Skytells(process.env.SKYTELLS_API_KEY);
330
+
331
+ // Check user input before sending to a model
332
+ const check = await client.safety.checkText(userInput, {
333
+ template: SafetyTemplates.MODERATE,
334
+ });
335
+ if (!check.passed) {
336
+ throw new Error(`Blocked: ${check.failedCategories.join(', ')}`);
337
+ }
338
+
339
+ // Evaluate generated prediction output (image URLs are auto-detected)
340
+ const prediction = await client.run('flux-pro', { input: { prompt: userInput } });
341
+ const eval = await client.safety.evaluate(prediction.output, SafetyTemplates.STRICT);
342
+ if (!eval.passed) {
343
+ await prediction.delete();
344
+ throw new Error(`Output blocked: ${eval.failedCategories.join(', ')}`);
345
+ }
346
+
347
+ // Parse content_filter_results from an existing chat completion (no extra API call)
348
+ const completion = await client.chat.completions.create({ ... });
349
+ if (client.safety.wasFiltered(completion)) {
350
+ const categories = client.safety.getFilteredCategories(completion);
351
+ console.warn('Filtered:', categories);
352
+ }
353
+ ```
354
+
355
+ See [Safety.md](docs/Safety.md) for templates, all input types, and integration patterns.
356
+
279
357
  ## Migration from v1.0.2
280
358
 
281
359
  ```diff
@@ -294,13 +372,26 @@ import type {
294
372
  + const pred = await skytells.predictions.get(id);
295
373
  ```
296
374
 
375
+ `createClient` is still exported for compatibility; the first call logs a console hint to prefer `import Skytells from 'skytells'`.
376
+
297
377
  > The old method names still work but log deprecation warnings and will be removed in a future version.
298
378
 
299
379
  ## Documentation
300
380
 
301
- - See [Official Docs](https://docs.skytells.ai/sdks/ts/) for the latest documentation.
302
- - [SDK API Reference](docs/SDK.md) — Full method signatures, parameter tables, and examples
303
- - [Developer Guide](docs/Guide.md) — Step-by-step walkthroughs and patterns
381
+ - See [Official Docs](https://docs.skytells.ai/sdks/ts/) for hosted documentation.
382
+ - **[Client.md](docs/Client.md)**`SkytellsClient` in full: options, every method, sub-APIs
383
+ - **[SDKReference.md](docs/SDKReference.md)**Low-level reference: every class, method, type, constant
384
+ - [Guide.md](docs/Guide.md) — Getting started walkthroughs
385
+ - [Architecture.md](docs/Architecture.md) — Request pipeline, retries, streams, model cache
386
+ - [Reliability.md](docs/Reliability.md) — Timeouts, retries, AbortSignal, edge/serverless patterns
387
+ - [Errors.md](docs/Errors.md) — `SkytellsError` catalog
388
+ - [Prediction.md](docs/Prediction.md) — Predictions: run, wait, queue, cancel, delete
389
+ - [Chat.md](docs/Chat.md) — Chat completions (streaming + tools)
390
+ - [Responses.md](docs/Responses.md) — Responses API (SSE events, multi-turn)
391
+ - [Embeddings.md](docs/Embeddings.md) — Embeddings, semantic search, RAG
392
+ - [Safety.md](docs/Safety.md) — Content moderation, templates, prediction evaluation
393
+ - [Webhooks.md](docs/Webhooks.md) — Inbound webhooks, framework integrations, HMAC
394
+ - [Orchestrator.md](docs/Orchestrator.md) — Orchestrator workflows (`wfb_…` key)
304
395
 
305
396
  ### Non-JSON Response Handling
306
397
 
@@ -308,7 +399,7 @@ The SDK automatically handles cases when the server doesn't respond with valid J
308
399
 
309
400
  ```typescript
310
401
  try {
311
- const models = await skytells.listModels();
402
+ const models = await skytells.models.list();
312
403
  } catch (error) {
313
404
  if (error instanceof SkytellsError) {
314
405
  if (error.errorId === 'SERVER_ERROR') {
@@ -344,9 +435,26 @@ npm run lint
344
435
 
345
436
  See [CHANGELOG.md](CHANGELOG.md) for the latest changes.
346
437
 
347
- ## SDK Docs
348
-
349
- See [SDK Docs](https://docs.skytells.ai/sdks/ts/) for the latest documentation.
438
+ ## Documentation in this repo
439
+
440
+ | File | Description |
441
+ |------|-------------|
442
+ | [docs/Client.md](docs/Client.md) | `SkytellsClient`: options, methods, sub-APIs, best practices |
443
+ | [docs/SDKReference.md](docs/SDKReference.md) | Low-level reference: every export, class, type, and constant |
444
+ | [docs/Guide.md](docs/Guide.md) | Getting started — first prediction, chat, embeddings |
445
+ | [docs/Architecture.md](docs/Architecture.md) | Request pipeline, retries, streaming, model cache |
446
+ | [docs/Reliability.md](docs/Reliability.md) | Timeouts, retries, AbortSignal, edge/serverless |
447
+ | [docs/Errors.md](docs/Errors.md) | `SkytellsError` fields and all `errorId` values |
448
+ | [docs/Prediction.md](docs/Prediction.md) | Predictions: run, wait, queue, dispatch, cancel, webhooks |
449
+ | [docs/Chat.md](docs/Chat.md) | Chat completions, streaming, tools, vision |
450
+ | [docs/Responses.md](docs/Responses.md) | Responses API, SSE events, multi-turn |
451
+ | [docs/Embeddings.md](docs/Embeddings.md) | Embeddings, semantic search, RAG |
452
+ | [docs/Safety.md](docs/Safety.md) | Safety checks, templates, prediction output evaluation |
453
+ | [docs/Webhooks.md](docs/Webhooks.md) | Inbound webhooks, HMAC verification, framework integrations |
454
+ | [docs/Orchestrator.md](docs/Orchestrator.md) | Orchestrator: workflows, executions, integrations |
455
+ | [docs/.env.example](docs/.env.example) | All environment variables for local dev and CI |
456
+
457
+ Hosted: [Skytells TS SDK docs](https://docs.skytells.ai/sdks/ts/).
350
458
 
351
459
  ## License
352
460
 
package/dist/chat.cjs ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Chat API — OpenAI-compatible chat completions.
3
+ * Same API surface as OpenAI: client.chat.completions.create()
4
+ *
5
+ * @module chat
6
+ */
7
+ const { ENDPOINTS } = require("./endpoints.js");
8
+ const { Responses } = require("./responses.js");
9
+ /**
10
+ * Completions sub-resource. Exposes create() for chat completions.
11
+ * Mirrors OpenAI's client.chat.completions API.
12
+ */
13
+ export class Completions {
14
+ constructor(http) {
15
+ this.http = http;
16
+ }
17
+ create(params) {
18
+ if (params.stream === true) {
19
+ return this.http.requestStream(ENDPOINTS.CHAT_COMPLETIONS, params);
20
+ }
21
+ return this.http.request('POST', ENDPOINTS.CHAT_COMPLETIONS, params);
22
+ }
23
+ }
24
+ /**
25
+ * Chat resource. Exposes completions and responses sub-APIs.
26
+ * Mirrors OpenAI's client.chat structure.
27
+ */
28
+ export class Chat {
29
+ constructor(http) {
30
+ this.completions = new Completions(http);
31
+ this.responses = new Responses(http);
32
+ }
33
+ }
package/dist/chat.d.ts ADDED
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Chat API — OpenAI-compatible chat completions.
3
+ * Same API surface as OpenAI: client.chat.completions.create()
4
+ *
5
+ * @module chat
6
+ */
7
+ import type { HTTP } from './http.js';
8
+ import { Responses } from './responses.js';
9
+ import type { ChatCompletion, ChatCompletionChunk, ChatCompletionCreateParamsNonStreaming, ChatCompletionCreateParamsStreaming } from './types/inference.types.js';
10
+ /**
11
+ * Completions sub-resource. Exposes create() for chat completions.
12
+ * Mirrors OpenAI's client.chat.completions API.
13
+ */
14
+ export declare class Completions {
15
+ private readonly http;
16
+ constructor(http: HTTP);
17
+ /**
18
+ * Creates a chat completion. Same as OpenAI's `client.chat.completions.create()`.
19
+ *
20
+ * When `stream` is `false` or omitted: returns `Promise<ChatCompletion>`.
21
+ * When `stream` is `true`: returns an `AsyncIterable<ChatCompletionChunk>` directly;
22
+ * consume with `for await…of` — no extra `await` needed.
23
+ *
24
+ * @param params - model, messages, and optional stream, tools, max_tokens, temperature, etc.
25
+ * @returns `Promise<ChatCompletion>` or `AsyncIterable<ChatCompletionChunk>`.
26
+ *
27
+ * @example Non-streaming:
28
+ * ```ts
29
+ * const completion = await client.chat.completions.create({
30
+ * model: 'deepbrain-router',
31
+ * messages: [{ role: 'user', content: 'Hello' }],
32
+ * });
33
+ * console.log(completion.choices[0].message.content);
34
+ * ```
35
+ *
36
+ * @example Streaming:
37
+ * ```ts
38
+ * for await (const chunk of client.chat.completions.create({
39
+ * model: 'deepbrain-router',
40
+ * messages: [{ role: 'user', content: 'Hello' }],
41
+ * stream: true,
42
+ * })) {
43
+ * process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
44
+ * }
45
+ * ```
46
+ *
47
+ * @example Tool calling:
48
+ * ```ts
49
+ * const result = await client.chat.completions.create({
50
+ * model: 'deepbrain-router',
51
+ * messages: [{ role: 'user', content: 'What is the weather in London?' }],
52
+ * tools: [{
53
+ * type: 'function',
54
+ * function: {
55
+ * name: 'get_weather',
56
+ * description: 'Get current weather for a location.',
57
+ * parameters: {
58
+ * type: 'object',
59
+ * properties: { location: { type: 'string' } },
60
+ * required: ['location'],
61
+ * },
62
+ * },
63
+ * }],
64
+ * tool_choice: 'auto',
65
+ * });
66
+ * const toolCall = result.choices[0].message.tool_calls?.[0];
67
+ * ```
68
+ */
69
+ create(params: ChatCompletionCreateParamsStreaming): AsyncIterable<ChatCompletionChunk>;
70
+ create(params: ChatCompletionCreateParamsNonStreaming): Promise<ChatCompletion>;
71
+ }
72
+ /**
73
+ * Chat resource. Exposes completions and responses sub-APIs.
74
+ * Mirrors OpenAI's client.chat structure.
75
+ */
76
+ export declare class Chat {
77
+ /** Chat completions. Same as OpenAI's `client.chat.completions` */
78
+ readonly completions: Completions;
79
+ /** Responses API (`POST /v1/responses`). Same surface as OpenAI-style `client.responses`. */
80
+ readonly responses: Responses;
81
+ constructor(http: HTTP);
82
+ }
package/dist/chat.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Chat API — OpenAI-compatible chat completions.
3
+ * Same API surface as OpenAI: client.chat.completions.create()
4
+ *
5
+ * @module chat
6
+ */
7
+ import { ENDPOINTS } from './endpoints.js';
8
+ import { Responses } from './responses.js';
9
+ /**
10
+ * Completions sub-resource. Exposes create() for chat completions.
11
+ * Mirrors OpenAI's client.chat.completions API.
12
+ */
13
+ export class Completions {
14
+ constructor(http) {
15
+ this.http = http;
16
+ }
17
+ create(params) {
18
+ if (params.stream === true) {
19
+ return this.http.requestStream(ENDPOINTS.CHAT_COMPLETIONS, params);
20
+ }
21
+ return this.http.request('POST', ENDPOINTS.CHAT_COMPLETIONS, params);
22
+ }
23
+ }
24
+ /**
25
+ * Chat resource. Exposes completions and responses sub-APIs.
26
+ * Mirrors OpenAI's client.chat structure.
27
+ */
28
+ export class Chat {
29
+ constructor(http) {
30
+ this.completions = new Completions(http);
31
+ this.responses = new Responses(http);
32
+ }
33
+ }