@picsart/ai-sdk 6.55.0 → 7.0.0
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 +64 -80
- package/_vendor/model-types/index.d.ts +292 -0
- package/index.d.ts +45 -2438
- package/index.js +685 -12774
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ npm install @picsart/ai-sdk
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
|
-
import { createClient,
|
|
25
|
+
import { createClient, Model, catalog } from '@picsart/ai-sdk'
|
|
26
26
|
|
|
27
27
|
// Create a client — pass your Picsart API key
|
|
28
28
|
const ai = createClient({
|
|
@@ -30,25 +30,38 @@ const ai = createClient({
|
|
|
30
30
|
apiUrl: 'https://api.picsart.com',
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
-
// Generate
|
|
34
|
-
|
|
33
|
+
// Generate — model ids are plain strings, resolved server-side.
|
|
34
|
+
// Generation works immediately; no catalog load required.
|
|
35
|
+
const result = await ai.generate('flux-2-pro', { prompt: 'a cat on mars' })
|
|
35
36
|
console.log(result.url)
|
|
36
37
|
|
|
38
|
+
// The local catalog accessors (Model / catalog / ai.validate) read a catalog
|
|
39
|
+
// loaded from models-hub. Load it once, then use them:
|
|
40
|
+
await ai.initModelCatalog()
|
|
41
|
+
|
|
37
42
|
// Browse models — the `catalog` accessor
|
|
38
43
|
catalog.all() // every model
|
|
39
44
|
catalog.find({ output: 'video' }) // video models only
|
|
40
45
|
catalog.search('kling') // search by name/id/provider
|
|
41
46
|
|
|
42
47
|
// Model metadata & params — the `Model` accessor
|
|
43
|
-
Model(
|
|
44
|
-
Model(
|
|
45
|
-
Model(
|
|
46
|
-
Model(
|
|
48
|
+
Model('flux-2-pro').name // 'Flux 2 Pro'
|
|
49
|
+
Model('flux-2-pro').meta() // mode, provider, badges, …
|
|
50
|
+
Model('flux-2-pro').params() // accepted parameters
|
|
51
|
+
Model('flux-2-pro').params().toSchema() // param schema
|
|
47
52
|
|
|
48
53
|
// Validate input (never throws) → { valid, errors? }
|
|
49
|
-
Model(
|
|
54
|
+
Model('flux-2-pro').validate({ prompt: 'a cat' })
|
|
50
55
|
```
|
|
51
56
|
|
|
57
|
+
> **Dynamic-only (v7).** The SDK no longer bundles a model catalog or builds
|
|
58
|
+
> vendor payloads locally. Every generation rides the models-hub `v1/models`
|
|
59
|
+
> workflow (the server resolves the model, builds the payload, and normalizes
|
|
60
|
+
> the result). Model ids are plain strings. The catalog accessors
|
|
61
|
+
> (`Model()`, `catalog.*`, `ai.validate()`) require `await ai.initModelCatalog()`
|
|
62
|
+
> first — until then they throw `ApiError` 409 `catalog_not_loaded`.
|
|
63
|
+
> `generate()`/`generateText()`/`run()`/`submit()` never wait on it.
|
|
64
|
+
|
|
52
65
|
## Authentication
|
|
53
66
|
|
|
54
67
|
Pass `apiKey` and the SDK sends `Authorization: Bearer <apiKey>` on every request
|
|
@@ -141,12 +154,12 @@ const ai = createClient({
|
|
|
141
154
|
})
|
|
142
155
|
|
|
143
156
|
// Generates and auto-saves to the root folder
|
|
144
|
-
const result = await ai.generate(
|
|
157
|
+
const result = await ai.generate('flux-2-pro', { prompt: 'a cat' })
|
|
145
158
|
// result.drive = { uid: '...', folder: { name: 'AI Playground', uid: '...' } }
|
|
146
159
|
|
|
147
160
|
// Save to a subfolder
|
|
148
161
|
const board = await ai.drive.ensureFolder('Cats')
|
|
149
|
-
const result = await ai.generate(
|
|
162
|
+
const result = await ai.generate('flux-2-pro', { prompt: 'a cat' }, { folder: board })
|
|
150
163
|
|
|
151
164
|
// Browse Drive
|
|
152
165
|
const folders = await ai.drive.folders()
|
|
@@ -200,16 +213,16 @@ as `mode: 'text'`. Each vendor uses its own native workflow, so capabilities are
|
|
|
200
213
|
— Gemini accepts video input, Claude uses the Anthropic-native messages API.
|
|
201
214
|
|
|
202
215
|
```typescript
|
|
203
|
-
import { createClient
|
|
216
|
+
import { createClient } from '@picsart/ai-sdk'
|
|
204
217
|
|
|
205
218
|
const ai = createClient({ apiKey: process.env.PICSART_API_KEY, apiUrl: 'https://api.picsart.com' })
|
|
206
219
|
|
|
207
220
|
// Text in, text out
|
|
208
|
-
const { text } = await ai.generateText(
|
|
221
|
+
const { text } = await ai.generateText('claude-opus-5', { prompt: 'Explain RAG in one line.' })
|
|
209
222
|
console.log(text)
|
|
210
223
|
|
|
211
224
|
// Optional vision input + reasoning level (OpenAI / Gemini)
|
|
212
|
-
const res = await ai.generateText(
|
|
225
|
+
const res = await ai.generateText('gpt-5-5', {
|
|
213
226
|
prompt: 'What is in this image?',
|
|
214
227
|
imageUrls: ['https://cdn.example.com/photo.jpg'],
|
|
215
228
|
thinking: 'high', // 'off' | 'low' | 'medium' | 'high'
|
|
@@ -218,7 +231,7 @@ console.log(res.text)
|
|
|
218
231
|
console.log(res.raw) // full backend response — usage, finish_reason, etc.
|
|
219
232
|
|
|
220
233
|
// Gemini accepts video input
|
|
221
|
-
await ai.generateText(
|
|
234
|
+
await ai.generateText('gemini-3-pro', {
|
|
222
235
|
prompt: 'Summarize this clip',
|
|
223
236
|
videoUrl: 'https://cdn.example.com/clip.mp4',
|
|
224
237
|
})
|
|
@@ -233,9 +246,10 @@ catalog.find({ output: 'text' })
|
|
|
233
246
|
> thinking knob. Claude’s `claude/v1/messages`
|
|
234
247
|
> workflow exposes no thinking knob, so Claude models omit `thinking`.
|
|
235
248
|
|
|
236
|
-
`generateText()`
|
|
237
|
-
|
|
238
|
-
|
|
249
|
+
Use `generateText()` for text models and `generate()` for media models. In
|
|
250
|
+
dynamic mode ids are plain strings with no compile-time narrowing — the server
|
|
251
|
+
validates the model/mode and answers a 400 `wrong_model_mode` if you call the
|
|
252
|
+
wrong method for a model.
|
|
239
253
|
|
|
240
254
|
## Generic Execution — ai.run()
|
|
241
255
|
|
|
@@ -250,14 +264,14 @@ task result — and for `mode: 'json'` models, `run()` is the only surface:
|
|
|
250
264
|
structured-output models (judges, evaluators, classifiers) are rejected by
|
|
251
265
|
`generate()`, `generateText()`, and the async lifecycle.
|
|
252
266
|
|
|
253
|
-
The first json model is `typesafe-evaluate`
|
|
254
|
-
|
|
255
|
-
|
|
267
|
+
The first json model is `typesafe-evaluate` — LLM-judge evaluation of any
|
|
268
|
+
content against named questions. Type the result via the `R` generic, same as
|
|
269
|
+
`ai.apis.run()`:
|
|
256
270
|
|
|
257
271
|
```typescript
|
|
258
272
|
interface EvaluateResult { model: string; answers: Record<string, unknown>; usage: unknown }
|
|
259
273
|
|
|
260
|
-
const { result } = await ai.run<EvaluateResult>(
|
|
274
|
+
const { result } = await ai.run<EvaluateResult>('typesafe-evaluate', {
|
|
261
275
|
state: 'The weather is lovely and everyone is having a great time.',
|
|
262
276
|
questions: {
|
|
263
277
|
is_safe: { type: 'noul', instructions: 'Is this content safe for all audiences?' },
|
|
@@ -304,21 +318,21 @@ For progress tracking and job recovery:
|
|
|
304
318
|
|
|
305
319
|
```typescript
|
|
306
320
|
// Submit without waiting — returns the generation id (a string)
|
|
307
|
-
const generationId = await ai.submit(
|
|
321
|
+
const generationId = await ai.submit('kling-v3', { prompt: 'a sunset' })
|
|
308
322
|
|
|
309
323
|
// Subscribe to updates — the terminal generation.completed event carries the
|
|
310
324
|
// parsed result, so no follow-up result() call is needed
|
|
311
|
-
for await (const e of ai.subscribe(
|
|
325
|
+
for await (const e of ai.subscribe('kling-v3', generationId)) {
|
|
312
326
|
if (e.type === 'generation.progress') console.log(e.progress?.percent)
|
|
313
327
|
if (e.type === 'generation.completed') console.log(e.result.url)
|
|
314
328
|
if (e.type === 'generation.failed') console.error(e.error.message)
|
|
315
329
|
}
|
|
316
330
|
|
|
317
331
|
// Or just wait for the parsed result (throws on failure/cancel)
|
|
318
|
-
const result = await ai.result(
|
|
332
|
+
const result = await ai.result('kling-v3', generationId, { intervalMs: 2000 })
|
|
319
333
|
|
|
320
334
|
// One-shot snapshot of a stored id (e.g. after a page reload)
|
|
321
|
-
const { value: snapshot } = await ai.subscribe(
|
|
335
|
+
const { value: snapshot } = await ai.subscribe('kling-v3', generationId).next()
|
|
322
336
|
```
|
|
323
337
|
|
|
324
338
|
Generation ids are plain strings — store them and recover jobs later with
|
|
@@ -331,10 +345,10 @@ is an `ApiError` with the same four fields, so you can branch on the error
|
|
|
331
345
|
instead of pattern-matching its message:
|
|
332
346
|
|
|
333
347
|
```typescript
|
|
334
|
-
import { createClient,
|
|
348
|
+
import { createClient, ApiError } from '@picsart/ai-sdk'
|
|
335
349
|
|
|
336
350
|
try {
|
|
337
|
-
const result = await ai.generate(
|
|
351
|
+
const result = await ai.generate('flux-2-pro', { prompt: 'a cat on mars' })
|
|
338
352
|
} catch (err) {
|
|
339
353
|
if (err instanceof ApiError) {
|
|
340
354
|
err.status // 402 — HTTP status, or its synthesized equivalent
|
|
@@ -387,8 +401,7 @@ Key exports (see `src/index.ts` for the full list):
|
|
|
387
401
|
| Export | Type | Description |
|
|
388
402
|
|--------|------|-------------|
|
|
389
403
|
| `createClient` | function | Create an AI client from an API key (or a custom authenticated fetch) |
|
|
390
|
-
| `
|
|
391
|
-
| `Model`, `catalog` | function / object | Model metadata, params, validation, discovery |
|
|
404
|
+
| `Model`, `catalog` | function / object | Model metadata, params, validation, discovery (after `initModelCatalog()`) |
|
|
392
405
|
| `GenerateResult` | type | `{ url, items: [{ url, metadata? }], generationId, usage?, drive? }` |
|
|
393
406
|
| `GenerationEvent` | type | One `ai.subscribe()` update — `generation.progress` / `.completed` / `.failed` |
|
|
394
407
|
| `GenerationEventType` | const | Named event-type constants (`GenerationEventType.Completed` === `'generation.completed'`) |
|
|
@@ -410,66 +423,37 @@ packages/ai-sdk/
|
|
|
410
423
|
client/
|
|
411
424
|
types.ts # ClientConfig, GenerateResult, DriveConfig
|
|
412
425
|
transport.ts # Default SdkTransport, over @picsart/workflows-client
|
|
413
|
-
prepare.ts #
|
|
426
|
+
prepare.ts # Build the v1/models command + parse its result
|
|
414
427
|
drive.ts # Drive folder management + file saving
|
|
415
|
-
index.ts # createClient() factory
|
|
428
|
+
index.ts # createClient() factory (dynamic-only)
|
|
416
429
|
core/
|
|
417
430
|
types.ts # ModelDefinition, ParamConfig, GenerationContext
|
|
418
431
|
workflow.ts # Task envelope types + the SdkTransport contract
|
|
419
|
-
|
|
432
|
+
active-catalog.ts # The process-global catalog installed by initModelCatalog()
|
|
433
|
+
catalog-store.ts # Loads the catalog from models-hub (/v1/models-catalog)
|
|
434
|
+
catalog-wire.ts # Wire ⇄ ModelDefinition (de)serialization
|
|
420
435
|
schema.ts # ParamConfig → JSON Schema
|
|
421
436
|
response.ts # Vendor-agnostic result extraction
|
|
422
|
-
|
|
423
|
-
model-registry.ts # Model lookup indexes
|
|
437
|
+
model-registry.ts # Model lookup indexes over the active catalog
|
|
424
438
|
providers.ts # Provider colors, labels, names
|
|
425
439
|
voices.ts # Voice catalogs (ElevenLabs, OpenAI, Gemini)
|
|
426
|
-
|
|
427
|
-
generated/
|
|
428
|
-
model-constants.ts # AUTO-GENERATED: Models object + id constants
|
|
429
|
-
model-input-types.ts # AUTO-GENERATED: per-model TypeScript input types
|
|
430
|
-
vendors/
|
|
431
|
-
define.ts # defineModels() framework + params.* helpers
|
|
432
|
-
presets.ts # Reusable paramConfig factories
|
|
433
|
-
catalog/
|
|
434
|
-
index.ts # Aggregation: ALL_MODELS, VENDOR_CATALOGS
|
|
435
|
-
kling.ts # One file per vendor (31 total)
|
|
436
|
-
flux.ts
|
|
437
|
-
...
|
|
440
|
+
descriptors/ # Model()/catalog accessors, param descriptors, pricing
|
|
438
441
|
__tests__/ # SDK tests
|
|
439
442
|
scripts/ # Build scripts
|
|
440
443
|
```
|
|
441
444
|
|
|
442
|
-
##
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
1. Define the model config as above (no `buildPayload`)
|
|
459
|
-
2. Run `npm run build:model-input-types` — generates typed input for your model
|
|
460
|
-
3. Create `src/vendors/catalog/{vendor}.payloads.ts`:
|
|
461
|
-
```ts
|
|
462
|
-
import type { ModelInput } from '../../generated/model-input-types.ts';
|
|
463
|
-
import { registerPayloads } from '../define.ts';
|
|
464
|
-
import { SPECS, MODELS } from './{vendor}.ts';
|
|
465
|
-
|
|
466
|
-
registerPayloads({ SPECS, MODELS }, {
|
|
467
|
-
'model-id': (input: ModelInput<'model-id'>) => ({
|
|
468
|
-
prompt: input.prompt,
|
|
469
|
-
aspect_ratio: input.aspectRatio, // rename for vendor API
|
|
470
|
-
}),
|
|
471
|
-
});
|
|
472
|
-
```
|
|
473
|
-
4. Import the `.payloads.ts` file in `src/vendors/catalog/index.ts` (after the vendor import)
|
|
474
|
-
|
|
475
|
-
See `src/vendors/catalog/luma.ts` + `src/vendors/catalog/luma.payloads.ts` for a working example.
|
|
445
|
+
## The Model Catalog
|
|
446
|
+
|
|
447
|
+
The SDK is **dynamic-only**: it ships with no bundled catalog and builds no
|
|
448
|
+
vendor payloads locally. Model definitions (parameter schemas, payload shapes,
|
|
449
|
+
and which workflow serves each model) live in **models-hub**, and every
|
|
450
|
+
generation rides its `v1/models` workflow — the server resolves the model,
|
|
451
|
+
builds the vendor payload, and normalizes the result.
|
|
452
|
+
|
|
453
|
+
- **Add or change a model** in the models-hub service
|
|
454
|
+
([`pa-models-hub-pluggable-worker`](https://gitlab.com/picsart/backend/Editor/external-ai-integrations/pa-models-hub-pluggable-worker));
|
|
455
|
+
it takes effect without an SDK release.
|
|
456
|
+
- **Load the catalog** into the SDK with `await ai.initModelCatalog()` — it
|
|
457
|
+
fetches `/v1/models-catalog` from models-hub and installs it as the active
|
|
458
|
+
catalog, so `Model()`, `catalog.*` and `ai.validate()` serve the loaded data.
|
|
459
|
+
Generation (`generate`/`generateText`/`run`/`submit`) does **not** require it.
|