skytells 1.0.1 → 1.0.3
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 +232 -121
- package/dist/client.cjs +649 -25
- package/dist/client.d.ts +547 -23
- package/dist/client.js +649 -25
- package/dist/endpoints.cjs +2 -0
- package/dist/endpoints.d.ts +2 -0
- package/dist/endpoints.js +2 -0
- package/dist/http.cjs +35 -2
- package/dist/http.d.ts +7 -1
- package/dist/http.js +35 -2
- package/dist/index.cjs +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/dist/types/model.types.d.ts +100 -7
- package/dist/types/model.types.js +30 -0
- package/dist/types/predict.types.d.ts +219 -14
- package/dist/types/predict.types.js +22 -0
- package/dist/types/shared.types.d.ts +40 -0
- package/dist/types/shared.types.js +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
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
|
|
3
|
+
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
|
+
|
|
5
|
+
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
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -14,190 +16,291 @@ pnpm add skytells
|
|
|
14
16
|
|
|
15
17
|
## Quick Start
|
|
16
18
|
|
|
19
|
+
```typescript
|
|
20
|
+
import Skytells from 'skytells';
|
|
21
|
+
|
|
22
|
+
const skytells = Skytells('your-api-key');
|
|
23
|
+
|
|
24
|
+
// Run a model and get the result
|
|
25
|
+
const prediction = await skytells.run('truefusion', {
|
|
26
|
+
input: { prompt: 'A cat wearing sunglasses' },
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
console.log(prediction.outputs()); // "https://delivery.skytells.cloud/..."
|
|
30
|
+
```
|
|
17
31
|
|
|
18
32
|
### Obtaining an API Key
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
1. Log in at [Skytells Portal](https://www.skytells.ai/auth/signin) or [Create an Account](https://www.skytells.ai/auth/signup)
|
|
35
|
+
2. Go to [Dashboard → API Keys](https://www.skytells.ai/dashboard/api-keys)
|
|
36
|
+
3. Click **Generate New API Key** and copy it immediately
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
21
39
|
|
|
22
|
-
|
|
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!
|
|
40
|
+
### Running a Prediction
|
|
27
41
|
|
|
28
|
-
|
|
42
|
+
`skytells.run()` sends a prediction, waits for completion, and returns a `Prediction` object:
|
|
29
43
|
|
|
30
44
|
```typescript
|
|
31
|
-
import
|
|
32
|
-
|
|
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
|
-
}
|
|
45
|
+
import Skytells from 'skytells';
|
|
53
46
|
|
|
54
|
-
|
|
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
|
-
}
|
|
47
|
+
const skytells = Skytells('your-api-key');
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const prediction = await skytells.getPrediction(id);
|
|
68
|
-
console.log('Prediction:', prediction);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error('Error getting prediction:', error);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
```
|
|
49
|
+
const prediction = await skytells.run('truefusion', {
|
|
50
|
+
input: { prompt: 'A sunset over mountains' },
|
|
51
|
+
});
|
|
74
52
|
|
|
75
|
-
|
|
53
|
+
// Access output
|
|
54
|
+
console.log(prediction.id); // "pred_abc123"
|
|
55
|
+
console.log(prediction.status); // "succeeded"
|
|
56
|
+
console.log(prediction.output); // Raw: ["https://..."] or "https://..."
|
|
57
|
+
console.log(prediction.outputs()); // Normalized: "https://..." (unwraps single-element arrays)
|
|
76
58
|
|
|
77
|
-
|
|
59
|
+
// Full raw response
|
|
60
|
+
const raw = prediction.raw();
|
|
61
|
+
console.log(raw.metrics); // { predict_time: 3.86, total_time: 3.86, ... }
|
|
62
|
+
console.log(raw.metadata); // { billing: { credits_used: 0 }, storage: { ... } }
|
|
63
|
+
```
|
|
78
64
|
|
|
79
|
-
|
|
80
|
-
- Vercel Edge Functions
|
|
81
|
-
- Netlify Edge Functions
|
|
82
|
-
- Deno Deploy
|
|
83
|
-
- Any environment with Fetch API support
|
|
65
|
+
### Progress Tracking
|
|
84
66
|
|
|
85
|
-
|
|
67
|
+
Pass an `onProgress` callback to track prediction status during polling:
|
|
86
68
|
|
|
87
69
|
```typescript
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
baseUrl: 'https://your-proxy.example.com/v1'
|
|
70
|
+
const prediction = await skytells.run('beatfusion-2.0', {
|
|
71
|
+
input: { prompt: 'rap, romantic', lyrics: 'Let me introduce the voice you hear, Beatfusion by Skytells making it clear..' },
|
|
72
|
+
}, (p) => {
|
|
73
|
+
console.log(`Status: ${p.status}, Progress: ${p.metrics?.progress ?? 'n/a'}`);
|
|
93
74
|
});
|
|
75
|
+
// [... song url ]
|
|
94
76
|
```
|
|
95
77
|
|
|
96
|
-
|
|
78
|
+
### Background Predictions
|
|
97
79
|
|
|
98
|
-
|
|
80
|
+
Create a prediction without waiting for it to finish:
|
|
99
81
|
|
|
100
82
|
```typescript
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
83
|
+
// Create in background (returns immediately)
|
|
84
|
+
const response = await skytells.predictions.create({
|
|
85
|
+
model: 'truefusion',
|
|
86
|
+
input: { prompt: 'A cat' },
|
|
87
|
+
});
|
|
88
|
+
console.log(response.id, response.status); // "pred_..." "pending"
|
|
105
89
|
|
|
106
|
-
//
|
|
107
|
-
const
|
|
90
|
+
// Poll until complete
|
|
91
|
+
const result = await skytells.wait(response);
|
|
92
|
+
console.log(result.output);
|
|
108
93
|
|
|
109
|
-
//
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
});
|
|
94
|
+
// Or with a timeout and progress
|
|
95
|
+
const result = await skytells.wait(response, {
|
|
96
|
+
interval: 2000, // poll every 2s
|
|
97
|
+
maxWait: 120000, // timeout after 2 min
|
|
98
|
+
}, (p) => console.log(p.status));
|
|
114
99
|
```
|
|
115
100
|
|
|
116
|
-
###
|
|
101
|
+
### Queue & Dispatch
|
|
117
102
|
|
|
118
|
-
|
|
103
|
+
Batch multiple predictions and dispatch them concurrently:
|
|
119
104
|
|
|
120
105
|
```typescript
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
106
|
+
skytells.queue({ model: 'truefusion-pro', input: { prompt: 'Cat' } });
|
|
107
|
+
skytells.queue({ model: 'truefusion-x', input: { prompt: 'Dog' } });
|
|
108
|
+
skytells.queue({ model: 'FLUX-2.0', input: { prompt: 'Bird' } });
|
|
109
|
+
skytells.queue({ model: 'sora-2', input: { prompt: 'A stunning video....' } });
|
|
110
|
+
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' } });
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
const results = await skytells.dispatch();
|
|
114
|
+
// results: PredictionResponse[] — one per queued item
|
|
115
|
+
|
|
116
|
+
// Wait for all to complete
|
|
117
|
+
const completed = await Promise.all(results.map(r => skytells.wait(r)));
|
|
129
118
|
```
|
|
130
119
|
|
|
131
|
-
|
|
120
|
+
### Prediction Lifecycle
|
|
132
121
|
|
|
133
122
|
```typescript
|
|
134
|
-
|
|
123
|
+
// Cancel a running prediction
|
|
124
|
+
await prediction.cancel();
|
|
125
|
+
// or by ID
|
|
126
|
+
await skytells.cancelPrediction('pred_abc123');
|
|
127
|
+
|
|
128
|
+
// Delete a prediction and its assets
|
|
129
|
+
await prediction.delete();
|
|
130
|
+
// or by ID
|
|
131
|
+
await skytells.deletePrediction('pred_abc123');
|
|
132
|
+
|
|
133
|
+
// Stream endpoint
|
|
134
|
+
const stream = await skytells.streamPrediction('pred_abc123');
|
|
135
|
+
console.log(stream.urls?.stream);
|
|
135
136
|
```
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
### Models
|
|
138
139
|
|
|
139
140
|
```typescript
|
|
140
|
-
|
|
141
|
+
// List all models
|
|
142
|
+
const models = await skytells.models.list();
|
|
143
|
+
for (const m of models) {
|
|
144
|
+
console.log(m.name, m.type, m.pricing?.amount);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Get a specific model
|
|
148
|
+
const model = await skytells.models.get('truefusion');
|
|
149
|
+
|
|
150
|
+
// Include schemas
|
|
151
|
+
const detailed = await skytells.models.get('truefusion', {
|
|
152
|
+
fields: ['input_schema', 'output_schema'],
|
|
153
|
+
});
|
|
141
154
|
```
|
|
142
155
|
|
|
143
|
-
|
|
156
|
+
### Predictions API
|
|
144
157
|
|
|
145
158
|
```typescript
|
|
146
|
-
|
|
159
|
+
// List predictions with filters
|
|
160
|
+
const { data, pagination } = await skytells.predictions.list({
|
|
161
|
+
model: 'truefusion',
|
|
162
|
+
since: '2026-01-01',
|
|
163
|
+
until: '2026-03-15',
|
|
164
|
+
page: 2,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Get a prediction by ID
|
|
168
|
+
const prediction = await skytells.predictions.get('pred_abc123');
|
|
147
169
|
```
|
|
148
170
|
|
|
149
|
-
|
|
171
|
+
## Client Options
|
|
150
172
|
|
|
151
173
|
```typescript
|
|
152
|
-
|
|
174
|
+
import Skytells from 'skytells';
|
|
175
|
+
|
|
176
|
+
const skytells = Skytells('your-api-key', {
|
|
177
|
+
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
|
|
180
|
+
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)
|
|
184
|
+
},
|
|
185
|
+
fetch: (url, opts) => // Custom fetch (e.g. Next.js cache workaround)
|
|
186
|
+
fetch(url, { ...opts, cache: 'no-store' }),
|
|
187
|
+
});
|
|
153
188
|
```
|
|
154
189
|
|
|
155
|
-
|
|
190
|
+
## The Prediction Object
|
|
156
191
|
|
|
157
|
-
|
|
192
|
+
When you call `skytells.run()`, you get a `Prediction` object:
|
|
158
193
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
194
|
+
| Property / Method | Returns | Description |
|
|
195
|
+
|---|---|---|
|
|
196
|
+
| `.id` | `string` | Unique prediction ID |
|
|
197
|
+
| `.status` | `PredictionStatus` | `pending`, `starting`, `started`, `processing`, `succeeded`, `failed`, `cancelled` |
|
|
198
|
+
| `.output` | `string \| string[] \| undefined` | Raw output from the API |
|
|
199
|
+
| `.response` | `PredictionResponse` | Full response object |
|
|
200
|
+
| `.outputs()` | `string \| string[] \| undefined` | Normalized output — unwraps single-element arrays |
|
|
201
|
+
| `.raw()` | `PredictionResponse` | Full raw response |
|
|
202
|
+
| `.cancel()` | `Promise<PredictionResponse>` | Cancel the prediction |
|
|
203
|
+
| `.delete()` | `Promise<PredictionResponse>` | Delete the prediction and its assets |
|
|
204
|
+
|
|
205
|
+
### `outputs()` Behavior
|
|
206
|
+
|
|
207
|
+
| API returns | `outputs()` returns |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `undefined` | `undefined` |
|
|
210
|
+
| `"https://..."` | `"https://..."` |
|
|
211
|
+
| `["https://..."]` | `"https://..."` (unwrapped) |
|
|
212
|
+
| `["a", "b"]` | `["a", "b"]` (kept as array) |
|
|
213
|
+
|
|
214
|
+
## Edge Compatibility
|
|
162
215
|
|
|
163
|
-
|
|
216
|
+
This SDK works in any environment with Fetch API support:
|
|
164
217
|
|
|
165
|
-
|
|
218
|
+
- **Cloudflare Workers & Pages**
|
|
219
|
+
- **Vercel Edge Functions**
|
|
220
|
+
- **Netlify Edge Functions**
|
|
221
|
+
- **Deno Deploy**
|
|
222
|
+
- **Node.js 18+**
|
|
223
|
+
- **Browsers**
|
|
166
224
|
|
|
167
225
|
## Error Handling
|
|
168
226
|
|
|
169
|
-
All
|
|
227
|
+
All methods throw `SkytellsError` on failure:
|
|
170
228
|
|
|
171
229
|
```typescript
|
|
172
|
-
import {
|
|
230
|
+
import Skytells, { SkytellsError } from 'skytells';
|
|
173
231
|
|
|
174
232
|
try {
|
|
175
|
-
const prediction = await
|
|
176
|
-
|
|
177
|
-
input: { prompt: 'Your prompt' }
|
|
233
|
+
const prediction = await skytells.run('truefusion', {
|
|
234
|
+
input: { prompt: 'A cat' },
|
|
178
235
|
});
|
|
179
236
|
} catch (error) {
|
|
180
237
|
if (error instanceof SkytellsError) {
|
|
181
|
-
console.error(
|
|
182
|
-
console.error(
|
|
183
|
-
console.error(
|
|
184
|
-
console.error(
|
|
185
|
-
} else {
|
|
186
|
-
console.error('Unknown error:', error);
|
|
238
|
+
console.error(error.message); // Human-readable message
|
|
239
|
+
console.error(error.errorId); // e.g. "VALIDATION_ERROR"
|
|
240
|
+
console.error(error.details); // Detailed info
|
|
241
|
+
console.error(error.httpStatus); // e.g. 422
|
|
187
242
|
}
|
|
188
243
|
}
|
|
189
244
|
```
|
|
190
245
|
|
|
191
|
-
###
|
|
246
|
+
### Error IDs
|
|
247
|
+
|
|
248
|
+
| Error ID | Description |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `UNAUTHORIZED` | Invalid or missing API key |
|
|
251
|
+
| `VALIDATION_ERROR` | Request parameters failed validation |
|
|
252
|
+
| `MODEL_NOT_FOUND` | Model slug not found |
|
|
253
|
+
| `INSUFFICIENT_CREDITS` | Not enough credits |
|
|
254
|
+
| `RATE_LIMIT_EXCEEDED` | Too many requests |
|
|
255
|
+
| `PREDICTION_FAILED` | Prediction completed with failure |
|
|
256
|
+
| `WAIT_TIMEOUT` | Polling exceeded `maxWait` |
|
|
257
|
+
| `REQUEST_TIMEOUT` | HTTP request timed out |
|
|
258
|
+
| `NETWORK_ERROR` | Connection issue |
|
|
259
|
+
| `SERVER_ERROR` | Non-JSON response from server |
|
|
260
|
+
| `INVALID_JSON` | Server returned invalid JSON |
|
|
192
261
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
262
|
+
## TypeScript
|
|
263
|
+
|
|
264
|
+
Full type definitions are included. Key types:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import type {
|
|
268
|
+
PredictionRequest,
|
|
269
|
+
PredictionResponse,
|
|
270
|
+
PredictionStatus,
|
|
271
|
+
RunOptions,
|
|
272
|
+
WaitOptions,
|
|
273
|
+
Model,
|
|
274
|
+
ClientOptions,
|
|
275
|
+
PaginatedResponse,
|
|
276
|
+
} from 'skytells';
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Migration from v1.0.2
|
|
280
|
+
|
|
281
|
+
```diff
|
|
282
|
+
- import { createClient } from 'skytells';
|
|
283
|
+
- const client = createClient('key');
|
|
284
|
+
+ import Skytells from 'skytells';
|
|
285
|
+
+ const skytells = Skytells('key');
|
|
286
|
+
|
|
287
|
+
- const models = await client.listModels();
|
|
288
|
+
+ const models = await skytells.models.list();
|
|
289
|
+
|
|
290
|
+
- const model = await client.getModel('truefusion');
|
|
291
|
+
+ const model = await skytells.models.get('truefusion');
|
|
292
|
+
|
|
293
|
+
- const pred = await client.getPrediction(id);
|
|
294
|
+
+ const pred = await skytells.predictions.get(id);
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
> The old method names still work but log deprecation warnings and will be removed in a future version.
|
|
298
|
+
|
|
299
|
+
## Documentation
|
|
300
|
+
|
|
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
|
|
201
304
|
|
|
202
305
|
### Non-JSON Response Handling
|
|
203
306
|
|
|
@@ -205,7 +308,7 @@ The SDK automatically handles cases when the server doesn't respond with valid J
|
|
|
205
308
|
|
|
206
309
|
```typescript
|
|
207
310
|
try {
|
|
208
|
-
const models = await
|
|
311
|
+
const models = await skytells.listModels();
|
|
209
312
|
} catch (error) {
|
|
210
313
|
if (error instanceof SkytellsError) {
|
|
211
314
|
if (error.errorId === 'SERVER_ERROR') {
|
|
@@ -237,6 +340,14 @@ npm test
|
|
|
237
340
|
npm run lint
|
|
238
341
|
```
|
|
239
342
|
|
|
343
|
+
## Changelog
|
|
344
|
+
|
|
345
|
+
See [CHANGELOG.md](CHANGELOG.md) for the latest changes.
|
|
346
|
+
|
|
347
|
+
## SDK Docs
|
|
348
|
+
|
|
349
|
+
See [SDK Docs](https://docs.skytells.ai/sdks/ts/) for the latest documentation.
|
|
350
|
+
|
|
240
351
|
## License
|
|
241
352
|
|
|
242
353
|
MIT
|