skytells 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +332 -121
  2. package/dist/chat.cjs +33 -0
  3. package/dist/chat.d.ts +82 -0
  4. package/dist/chat.js +33 -0
  5. package/dist/client.cjs +1151 -35
  6. package/dist/client.d.ts +776 -27
  7. package/dist/client.js +1151 -35
  8. package/dist/embeddings.cjs +40 -0
  9. package/dist/embeddings.d.ts +38 -0
  10. package/dist/embeddings.js +40 -0
  11. package/dist/endpoints.cjs +25 -7
  12. package/dist/endpoints.d.ts +18 -0
  13. package/dist/endpoints.js +25 -7
  14. package/dist/http.cjs +638 -53
  15. package/dist/http.d.ts +136 -2
  16. package/dist/http.js +638 -53
  17. package/dist/index.cjs +52 -6
  18. package/dist/index.d.ts +46 -7
  19. package/dist/index.js +52 -6
  20. package/dist/orchestrator.cjs +202 -0
  21. package/dist/orchestrator.d.ts +142 -0
  22. package/dist/orchestrator.js +202 -0
  23. package/dist/prediction-urls.cjs +38 -0
  24. package/dist/prediction-urls.d.ts +18 -0
  25. package/dist/prediction-urls.js +38 -0
  26. package/dist/responses.cjs +23 -0
  27. package/dist/responses.d.ts +60 -0
  28. package/dist/responses.js +23 -0
  29. package/dist/safety.cjs +323 -0
  30. package/dist/safety.d.ts +91 -0
  31. package/dist/safety.js +323 -0
  32. package/dist/types/index.d.ts +2 -0
  33. package/dist/types/index.js +2 -0
  34. package/dist/types/inference.types.d.ts +583 -0
  35. package/dist/types/inference.types.js +65 -0
  36. package/dist/types/model.types.d.ts +58 -4
  37. package/dist/types/model.types.js +13 -0
  38. package/dist/types/orchestrator.types.d.ts +61 -0
  39. package/dist/types/orchestrator.types.js +7 -0
  40. package/dist/types/predict.types.d.ts +258 -16
  41. package/dist/types/predict.types.js +22 -0
  42. package/dist/types/shared.types.d.ts +156 -3
  43. package/dist/types/shared.types.js +73 -2
  44. package/dist/webhooks.cjs +310 -0
  45. package/dist/webhooks.d.ts +171 -0
  46. package/dist/webhooks.js +310 -0
  47. package/package.json +26 -2
package/README.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # Skytells JavaScript/TypeScript SDK
2
2
 
3
- The official JavaScript/TypeScript SDK for interacting with the [Skytells](https://skytells.ai) API. Edge-compatible with Cloudflare Pages, Vercel Edge Functions, and more.
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
+
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.
11
+
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)
4
13
 
5
14
  ## Installation
6
15
 
@@ -12,192 +21,377 @@ yarn add skytells
12
21
  pnpm add skytells
13
22
  ```
14
23
 
15
- ## Quick Start
24
+ ## Import
16
25
 
26
+ ```ts
27
+ // Recommended: factory (default export)
28
+ import Skytells from 'skytells';
17
29
 
18
- ### Obtaining an API Key
30
+ // Direct class import
31
+ import { SkytellsClient } from 'skytells';
32
+
33
+ // Both in one import
34
+ import Skytells, { SkytellsClient } from 'skytells';
35
+ ```
19
36
 
20
- To obtain an API key, follow these steps:
37
+ Optionally, you may use the named factory:
21
38
 
22
- 1. Log in to your Skytells account at [https://www.skytells.ai/auth/signin](https://www.skytells.ai/auth/signin)
23
- 2. Navigate to your dashboard and go to the API Keys section at [https://www.skytells.ai/dashboard/api-keys](https://www.skytells.ai/dashboard/api-keys)
24
- 3. Click on "Generate New API Key"
25
- 4. Give your API key a descriptive name (e.g., "Production API Key", "Development API Key")
26
- 5. Copy the generated API key immediately - you won't be able to see it again!
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
+ ```
27
45
 
28
- ## Making Predictions
46
+ ## Quick Start
29
47
 
30
48
  ```typescript
31
- import { createClient } from 'skytells';
49
+ import Skytells from 'skytells';
32
50
 
33
- // Initialize the client with your API key
34
- const skytells = createClient('your-api-key-here');
35
-
36
- // Make a prediction
37
- async function makePrediction() {
38
- try {
39
- const prediction = await skytells.predict({
40
- model: 'model-name',
41
- input: {
42
- prompt: 'Your prompt here'
43
- }
44
- });
45
-
46
- console.log('Prediction ID:', prediction.id);
47
- console.log('Status:', prediction.status);
48
- console.log('Output:', prediction.output);
49
- } catch (error) {
50
- console.error('Error making prediction:', error);
51
- }
52
- }
51
+ const skytells = Skytells('your-api-key');
53
52
 
54
- // List available models
55
- async function listModels() {
56
- try {
57
- const models = await skytells.listModels();
58
- console.log('Available models:', models);
59
- } catch (error) {
60
- console.error('Error listing models:', error);
61
- }
62
- }
53
+ // Run a model and get the result
54
+ const prediction = await skytells.run('truefusion', {
55
+ input: { prompt: 'A cat wearing sunglasses' },
56
+ });
63
57
 
64
- // Get a prediction by ID
65
- async function getPrediction(id) {
66
- try {
67
- const prediction = await skytells.getPrediction(id);
68
- console.log('Prediction:', prediction);
69
- } catch (error) {
70
- console.error('Error getting prediction:', error);
71
- }
72
- }
58
+ console.log(prediction.outputs()); // "https://delivery.skytells.cloud/..."
73
59
  ```
74
60
 
75
- ## Edge Compatibility
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)):
76
62
 
77
- This SDK is fully compatible with edge environments including:
63
+ ```typescript
64
+ const client = Skytells('sk-…', { orchestratorApiKey: 'wfb_…' });
65
+ await client.orchestrator.webhooks.execute(workflowId, { /* JSON body */ });
66
+ ```
78
67
 
79
- - Cloudflare Workers and Pages
80
- - Vercel Edge Functions
81
- - Netlify Edge Functions
82
- - Deno Deploy
83
- - Any environment with Fetch API support
68
+ ### Obtaining an API Key
84
69
 
85
- To use a custom API endpoint or proxy:
70
+ 1. Log in at [Skytells Portal](https://www.skytells.ai/auth/signin) or [Create an Account](https://www.skytells.ai/auth/signup)
71
+ 2. Go to [Dashboard → API Keys](https://www.skytells.ai/dashboard/api-keys)
72
+ 3. Click **Generate New API Key** and copy it immediately
73
+
74
+ ## Usage
75
+
76
+ ### Running a Prediction
77
+
78
+ `skytells.run()` sends a prediction, waits for completion, and returns a `Prediction` object:
86
79
 
87
80
  ```typescript
88
- import { createClient } from 'skytells';
81
+ import Skytells from 'skytells';
82
+
83
+ const skytells = Skytells('your-api-key');
89
84
 
90
- // Use a custom API endpoint or proxy
91
- const client = createClient('your-api-key', {
92
- baseUrl: 'https://your-proxy.example.com/v1'
85
+ const prediction = await skytells.run('truefusion', {
86
+ input: { prompt: 'A sunset over mountains' },
93
87
  });
88
+
89
+ // Access output
90
+ console.log(prediction.id); // "pred_abc123"
91
+ console.log(prediction.status); // "succeeded"
92
+ console.log(prediction.output); // Raw: ["https://..."] or "https://..."
93
+ console.log(prediction.outputs()); // Normalized: "https://..." (unwraps single-element arrays)
94
+
95
+ // Full raw response
96
+ const raw = prediction.raw();
97
+ console.log(raw.metrics); // { predict_time: 3.86, total_time: 3.86, ... }
98
+ console.log(raw.metadata); // { billing: { credits_used: 0 }, storage: { ... } }
94
99
  ```
95
100
 
96
- ## API Reference
101
+ ### Progress Tracking
97
102
 
98
- ### Creating a Client
103
+ Pass an `onProgress` callback to track prediction status during polling:
99
104
 
100
105
  ```typescript
101
- import { createClient } from 'skytells';
106
+ const prediction = await skytells.run('beatfusion-2.0', {
107
+ input: { prompt: 'rap, romantic', lyrics: 'Let me introduce the voice you hear, Beatfusion by Skytells making it clear..' },
108
+ }, (p) => {
109
+ console.log(`Status: ${p.status}, Progress: ${p.metrics?.progress ?? 'n/a'}`);
110
+ });
111
+ // [... song url ]
112
+ ```
102
113
 
103
- // With API key (authenticated)
104
- const client = createClient('your-api-key');
114
+ ### Background Predictions
105
115
 
106
- // Without API key (unauthenticated, limited functionality)
107
- const unauthenticatedClient = createClient();
116
+ Create a prediction without waiting for it to finish:
108
117
 
109
- // With options
110
- const clientWithOptions = createClient('your-api-key', {
111
- baseUrl: 'https://api.skytells.ai/v1', // Custom API URL
112
- timeout: 30000 // Custom timeout in ms
118
+ ```typescript
119
+ // Create in background (returns immediately)
120
+ const response = await skytells.predictions.create({
121
+ model: 'truefusion',
122
+ input: { prompt: 'A cat' },
113
123
  });
124
+ console.log(response.id, response.status); // "pred_..." "pending"
125
+
126
+ // Poll until complete
127
+ const result = await skytells.wait(response);
128
+ console.log(result.output);
129
+
130
+ // Or with a timeout and progress (first GET is immediate; then every interval)
131
+ const result = await skytells.wait(response, {
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
135
+ }, (p) => console.log(p.status));
114
136
  ```
115
137
 
116
- ### Predictions
138
+ ### Queue & Dispatch
117
139
 
118
- #### Make a Prediction
140
+ Batch multiple predictions and dispatch them concurrently:
119
141
 
120
142
  ```typescript
121
- const prediction = await client.predict({
122
- model: 'model-name',
123
- input: {
124
- // Model-specific inputs
125
- prompt: 'Your prompt here',
126
- // Other parameters...
127
- }
128
- });
143
+ skytells.queue({ model: 'truefusion-pro', input: { prompt: 'Cat' } });
144
+ skytells.queue({ model: 'truefusion-x', input: { prompt: 'Dog' } });
145
+ skytells.queue({ model: 'FLUX-2.0', input: { prompt: 'Bird' } });
146
+ skytells.queue({ model: 'sora-2', input: { prompt: 'A stunning video....' } });
147
+ skytells.queue({ model: 'beatfusion-2.0', input: { lyrics:' Wherever you are I go In every beat every sound Your love is all around....', prompt: 'Romantic, Love' } });
148
+
149
+
150
+ const results = await skytells.dispatch();
151
+ // results: PredictionResponse[] — one per queued item
152
+
153
+ // Wait for all to complete
154
+ const completed = await Promise.all(results.map(r => skytells.wait(r)));
129
155
  ```
130
156
 
131
- #### Get a Prediction by ID
157
+ ### Prediction Lifecycle
132
158
 
133
159
  ```typescript
134
- const prediction = await client.getPrediction('prediction-id');
160
+ // Cancel a running prediction (works while status is pending/starting/processing)
161
+ await prediction.cancel();
162
+
163
+ // Delete a prediction and all its output assets from storage
164
+ await prediction.delete();
165
+
166
+ // Fetch stream metadata for a prediction
167
+ const stream = await prediction.stream();
168
+ console.log(stream.urls?.stream);
135
169
  ```
136
170
 
137
- #### Stream a Prediction
171
+ ### Models
138
172
 
139
173
  ```typescript
140
- const prediction = await client.streamPrediction('prediction-id');
174
+ // List all models
175
+ const models = await skytells.models.list();
176
+ for (const m of models) {
177
+ console.log(m.name, m.type, m.pricing?.amount);
178
+ }
179
+
180
+ // Get a specific model
181
+ const model = await skytells.models.get('truefusion');
182
+
183
+ // Include schemas
184
+ const detailed = await skytells.models.get('truefusion', {
185
+ fields: ['input_schema', 'output_schema'],
186
+ });
141
187
  ```
142
188
 
143
- #### Cancel a Prediction
189
+ ### Predictions API
144
190
 
145
191
  ```typescript
146
- const prediction = await client.cancelPrediction('prediction-id');
192
+ // List predictions with filters
193
+ const { data, pagination } = await skytells.predictions.list({
194
+ model: 'truefusion',
195
+ since: '2026-01-01',
196
+ until: '2026-03-15',
197
+ page: 2,
198
+ });
199
+
200
+ // Get a prediction by ID
201
+ const prediction = await skytells.predictions.get('pred_abc123');
147
202
  ```
148
203
 
149
- #### Delete a Prediction
204
+ ## Client Options
150
205
 
151
206
  ```typescript
152
- const prediction = await client.deletePrediction('prediction-id');
207
+ import Skytells from 'skytells';
208
+
209
+ const skytells = Skytells('your-api-key', {
210
+ baseUrl: 'https://your-proxy.example.com/v1', // Custom API URL
211
+ timeout: 30000, // Omit for defaults: 60000 normally, 25000 when runtime: 'edge'
212
+ headers: { 'X-Custom-Header': 'value' }, // Extra headers on every request
213
+ retry: {
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],
217
+ },
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
220
+ });
153
221
  ```
154
222
 
155
- ### Models
223
+ Inspect resolved settings: **`skytells.config`** (`requestTimeoutMs`, `prefetchMaxSlugs`, `runtime`) and **`skytells.runtime`**.
156
224
 
157
- #### List All Models
225
+ ## The Prediction Object
158
226
 
159
- ```typescript
160
- const models = await client.listModels();
161
- ```
227
+ When you call `skytells.run()`, you get a `Prediction` object:
228
+
229
+ | Property / Method | Returns | Description |
230
+ |---|---|---|
231
+ | `.id` | `string` | Unique prediction ID |
232
+ | `.status` | `PredictionStatus` | `pending`, `starting`, `started`, `processing`, `succeeded`, `failed`, `cancelled` |
233
+ | `.output` | `string \| string[] \| undefined` | Raw output from the API |
234
+ | `.response` | `PredictionResponse` | Full response object |
235
+ | `.outputs()` | `string \| string[] \| undefined` | Normalized output — unwraps single-element arrays |
236
+ | `.raw()` | `PredictionResponse` | Full raw response |
237
+ | `.cancel()` | `Promise<PredictionResponse>` | Cancel the prediction |
238
+ | `.delete()` | `Promise<PredictionResponse>` | Delete the prediction and its assets |
162
239
 
163
- ## TypeScript Support
240
+ ### `outputs()` Behavior
241
+
242
+ | API returns | `outputs()` returns |
243
+ |---|---|
244
+ | `undefined` | `undefined` |
245
+ | `"https://..."` | `"https://..."` |
246
+ | `["https://..."]` | `"https://..."` (unwrapped) |
247
+ | `["a", "b"]` | `["a", "b"]` (kept as array) |
248
+
249
+ ## Edge Compatibility
164
250
 
165
- This SDK is built with TypeScript and provides full type definitions for all methods and responses.
251
+ This SDK works in any environment with **Fetch** and (for **webhook HMAC verification**) **`crypto.subtle`** (Web Crypto):
252
+
253
+ - **Cloudflare Workers & Pages**
254
+ - **Vercel Edge Functions**
255
+ - **Netlify Edge Functions**
256
+ - **Deno Deploy**
257
+ - **Node.js** — use **19+** for global `crypto.subtle`, or verify webhooks in an environment that provides it
258
+ - **Browsers**
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.
166
261
 
167
262
  ## Error Handling
168
263
 
169
- All API methods return promises that may reject with a `SkytellsError`. The SDK parses API error responses into this structured format:
264
+ All methods throw `SkytellsError` on failure:
170
265
 
171
266
  ```typescript
172
- import { createClient, SkytellsError } from 'skytells';
267
+ import Skytells, { SkytellsError } from 'skytells';
173
268
 
174
269
  try {
175
- const prediction = await client.predict({
176
- model: 'model-name',
177
- input: { prompt: 'Your prompt' }
270
+ const prediction = await skytells.run('truefusion', {
271
+ input: { prompt: 'A cat' },
178
272
  });
179
273
  } catch (error) {
180
274
  if (error instanceof SkytellsError) {
181
- console.error('Error message:', error.message);
182
- console.error('Error ID:', error.errorId); // Example: "VALIDATION_ERROR"
183
- console.error('Error details:', error.details); // Detailed error information
184
- console.error('HTTP status:', error.httpStatus); // HTTP status code (e.g., 422)
185
- } else {
186
- console.error('Unknown error:', error);
275
+ console.error(error.message); // Human-readable message
276
+ console.error(error.errorId); // e.g. "VALIDATION_ERROR"
277
+ console.error(error.details); // Detailed info
278
+ console.error(error.httpStatus); // e.g. 422
187
279
  }
188
280
  }
189
281
  ```
190
282
 
191
- ### Common Error IDs
283
+ ### Error IDs
284
+
285
+ | Error ID | Description |
286
+ |---|---|
287
+ | `UNAUTHORIZED` | Invalid or missing API key |
288
+ | `VALIDATION_ERROR` | Request parameters failed validation |
289
+ | `MODEL_NOT_FOUND` | Model slug not found |
290
+ | `INSUFFICIENT_CREDITS` | Not enough credits |
291
+ | `RATE_LIMIT_EXCEEDED` | Too many requests |
292
+ | `PREDICTION_FAILED` | Prediction completed with failure |
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, …) |
296
+ | `REQUEST_TIMEOUT` | HTTP request timed out |
297
+ | `NETWORK_ERROR` | Connection issue |
298
+ | `SERVER_ERROR` | Non-JSON response from server |
299
+ | `INVALID_JSON` | Declared JSON but body failed `JSON.parse` |
192
300
 
193
- - `VALIDATION_ERROR` - Request parameters failed validation
194
- - `AUTHENTICATION_ERROR` - Invalid or missing API key
195
- - `RATE_LIMIT_EXCEEDED` - Too many requests
196
- - `RESOURCE_NOT_FOUND` - The requested resource doesn't exist
197
- - `NETWORK_ERROR` - Connection issue with the API
198
- - `REQUEST_TIMEOUT` - Request took too long to complete
199
- - `SERVER_ERROR` - The server responded with a non-JSON response (e.g., HTML error page)
200
- - `INVALID_JSON` - The server returned invalid JSON content
301
+ ## TypeScript
302
+
303
+ Full type definitions are included. Key types:
304
+
305
+ ```typescript
306
+ import type {
307
+ PredictionRequest,
308
+ PredictionSdkOptions,
309
+ PredictionResponse,
310
+ PredictionStatus,
311
+ RunOptions,
312
+ WaitOptions,
313
+ Model,
314
+ ClientOptions,
315
+ SkytellsRuntime,
316
+ PaginatedResponse,
317
+ } from 'skytells';
318
+ ```
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
+
357
+ ## Migration from v1.0.2
358
+
359
+ ```diff
360
+ - import { createClient } from 'skytells';
361
+ - const client = createClient('key');
362
+ + import Skytells from 'skytells';
363
+ + const skytells = Skytells('key');
364
+
365
+ - const models = await client.listModels();
366
+ + const models = await skytells.models.list();
367
+
368
+ - const model = await client.getModel('truefusion');
369
+ + const model = await skytells.models.get('truefusion');
370
+
371
+ - const pred = await client.getPrediction(id);
372
+ + const pred = await skytells.predictions.get(id);
373
+ ```
374
+
375
+ `createClient` is still exported for compatibility; the first call logs a console hint to prefer `import Skytells from 'skytells'`.
376
+
377
+ > The old method names still work but log deprecation warnings and will be removed in a future version.
378
+
379
+ ## Documentation
380
+
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)
201
395
 
202
396
  ### Non-JSON Response Handling
203
397
 
@@ -205,7 +399,7 @@ The SDK automatically handles cases when the server doesn't respond with valid J
205
399
 
206
400
  ```typescript
207
401
  try {
208
- const models = await client.listModels();
402
+ const models = await skytells.models.list();
209
403
  } catch (error) {
210
404
  if (error instanceof SkytellsError) {
211
405
  if (error.errorId === 'SERVER_ERROR') {
@@ -241,9 +435,26 @@ npm run lint
241
435
 
242
436
  See [CHANGELOG.md](CHANGELOG.md) for the latest changes.
243
437
 
244
- ## SDK Docs
245
-
246
- 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/).
247
458
 
248
459
  ## License
249
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
+ }