@picsart/ai-sdk 6.54.0 → 6.99.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 +69 -84
- package/_vendor/model-types/index.d.ts +292 -0
- package/index.d.ts +45 -2427
- package/index.js +685 -12734
- 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()
|
|
@@ -194,22 +207,22 @@ names or catalog model IDs from an arbitrary vendor request.
|
|
|
194
207
|
|
|
195
208
|
## Text Generation (LLMs)
|
|
196
209
|
|
|
197
|
-
Claude, GPT, Gemini, Kimi and
|
|
210
|
+
Claude, GPT, Gemini, Kimi, Grok and MiniMax text models are called with `generateText()`. Single-shot:
|
|
198
211
|
pass a prompt and optional image(s)/video, get text back. They surface in the catalog
|
|
199
212
|
as `mode: 'text'`. Each vendor uses its own native workflow, so capabilities aren't lost
|
|
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
|
})
|
|
@@ -227,14 +240,16 @@ await ai.generateText(Models.Gemini3Pro, {
|
|
|
227
240
|
catalog.find({ output: 'text' })
|
|
228
241
|
```
|
|
229
242
|
|
|
230
|
-
> Thinking level maps per vendor: OpenAI, Kimi and
|
|
231
|
-
> `thinkingConfig.thinkingLevel` (LOW/HIGH). Kimi K3
|
|
232
|
-
> they have no `off`.
|
|
243
|
+
> Thinking level maps per vendor: OpenAI, Kimi, Grok and MiniMax M3.1 Flash → `reasoning_effort`, Gemini →
|
|
244
|
+
> `thinkingConfig.thinkingLevel` (LOW/HIGH). Kimi K3, Grok 4.7 and MiniMax M3.1 Flash
|
|
245
|
+
> always reason, so they have no `off`. MiniMax M3 reasons adaptively and has no
|
|
246
|
+
> thinking knob. Claude’s `claude/v1/messages`
|
|
233
247
|
> workflow exposes no thinking knob, so Claude models omit `thinking`.
|
|
234
248
|
|
|
235
|
-
`generateText()`
|
|
236
|
-
|
|
237
|
-
|
|
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.
|
|
238
253
|
|
|
239
254
|
## Generic Execution — ai.run()
|
|
240
255
|
|
|
@@ -249,14 +264,14 @@ task result — and for `mode: 'json'` models, `run()` is the only surface:
|
|
|
249
264
|
structured-output models (judges, evaluators, classifiers) are rejected by
|
|
250
265
|
`generate()`, `generateText()`, and the async lifecycle.
|
|
251
266
|
|
|
252
|
-
The first json model is `typesafe-evaluate`
|
|
253
|
-
|
|
254
|
-
|
|
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()`:
|
|
255
270
|
|
|
256
271
|
```typescript
|
|
257
272
|
interface EvaluateResult { model: string; answers: Record<string, unknown>; usage: unknown }
|
|
258
273
|
|
|
259
|
-
const { result } = await ai.run<EvaluateResult>(
|
|
274
|
+
const { result } = await ai.run<EvaluateResult>('typesafe-evaluate', {
|
|
260
275
|
state: 'The weather is lovely and everyone is having a great time.',
|
|
261
276
|
questions: {
|
|
262
277
|
is_safe: { type: 'noul', instructions: 'Is this content safe for all audiences?' },
|
|
@@ -303,21 +318,21 @@ For progress tracking and job recovery:
|
|
|
303
318
|
|
|
304
319
|
```typescript
|
|
305
320
|
// Submit without waiting — returns the generation id (a string)
|
|
306
|
-
const generationId = await ai.submit(
|
|
321
|
+
const generationId = await ai.submit('kling-v3', { prompt: 'a sunset' })
|
|
307
322
|
|
|
308
323
|
// Subscribe to updates — the terminal generation.completed event carries the
|
|
309
324
|
// parsed result, so no follow-up result() call is needed
|
|
310
|
-
for await (const e of ai.subscribe(
|
|
325
|
+
for await (const e of ai.subscribe('kling-v3', generationId)) {
|
|
311
326
|
if (e.type === 'generation.progress') console.log(e.progress?.percent)
|
|
312
327
|
if (e.type === 'generation.completed') console.log(e.result.url)
|
|
313
328
|
if (e.type === 'generation.failed') console.error(e.error.message)
|
|
314
329
|
}
|
|
315
330
|
|
|
316
331
|
// Or just wait for the parsed result (throws on failure/cancel)
|
|
317
|
-
const result = await ai.result(
|
|
332
|
+
const result = await ai.result('kling-v3', generationId, { intervalMs: 2000 })
|
|
318
333
|
|
|
319
334
|
// One-shot snapshot of a stored id (e.g. after a page reload)
|
|
320
|
-
const { value: snapshot } = await ai.subscribe(
|
|
335
|
+
const { value: snapshot } = await ai.subscribe('kling-v3', generationId).next()
|
|
321
336
|
```
|
|
322
337
|
|
|
323
338
|
Generation ids are plain strings — store them and recover jobs later with
|
|
@@ -330,10 +345,10 @@ is an `ApiError` with the same four fields, so you can branch on the error
|
|
|
330
345
|
instead of pattern-matching its message:
|
|
331
346
|
|
|
332
347
|
```typescript
|
|
333
|
-
import { createClient,
|
|
348
|
+
import { createClient, ApiError } from '@picsart/ai-sdk'
|
|
334
349
|
|
|
335
350
|
try {
|
|
336
|
-
const result = await ai.generate(
|
|
351
|
+
const result = await ai.generate('flux-2-pro', { prompt: 'a cat on mars' })
|
|
337
352
|
} catch (err) {
|
|
338
353
|
if (err instanceof ApiError) {
|
|
339
354
|
err.status // 402 — HTTP status, or its synthesized equivalent
|
|
@@ -386,8 +401,7 @@ Key exports (see `src/index.ts` for the full list):
|
|
|
386
401
|
| Export | Type | Description |
|
|
387
402
|
|--------|------|-------------|
|
|
388
403
|
| `createClient` | function | Create an AI client from an API key (or a custom authenticated fetch) |
|
|
389
|
-
| `
|
|
390
|
-
| `Model`, `catalog` | function / object | Model metadata, params, validation, discovery |
|
|
404
|
+
| `Model`, `catalog` | function / object | Model metadata, params, validation, discovery (after `initModelCatalog()`) |
|
|
391
405
|
| `GenerateResult` | type | `{ url, items: [{ url, metadata? }], generationId, usage?, drive? }` |
|
|
392
406
|
| `GenerationEvent` | type | One `ai.subscribe()` update — `generation.progress` / `.completed` / `.failed` |
|
|
393
407
|
| `GenerationEventType` | const | Named event-type constants (`GenerationEventType.Completed` === `'generation.completed'`) |
|
|
@@ -409,66 +423,37 @@ packages/ai-sdk/
|
|
|
409
423
|
client/
|
|
410
424
|
types.ts # ClientConfig, GenerateResult, DriveConfig
|
|
411
425
|
transport.ts # Default SdkTransport, over @picsart/workflows-client
|
|
412
|
-
prepare.ts #
|
|
426
|
+
prepare.ts # Build the v1/models command + parse its result
|
|
413
427
|
drive.ts # Drive folder management + file saving
|
|
414
|
-
index.ts # createClient() factory
|
|
428
|
+
index.ts # createClient() factory (dynamic-only)
|
|
415
429
|
core/
|
|
416
430
|
types.ts # ModelDefinition, ParamConfig, GenerationContext
|
|
417
431
|
workflow.ts # Task envelope types + the SdkTransport contract
|
|
418
|
-
|
|
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
|
|
419
435
|
schema.ts # ParamConfig → JSON Schema
|
|
420
436
|
response.ts # Vendor-agnostic result extraction
|
|
421
|
-
|
|
422
|
-
model-registry.ts # Model lookup indexes
|
|
437
|
+
model-registry.ts # Model lookup indexes over the active catalog
|
|
423
438
|
providers.ts # Provider colors, labels, names
|
|
424
439
|
voices.ts # Voice catalogs (ElevenLabs, OpenAI, Gemini)
|
|
425
|
-
|
|
426
|
-
generated/
|
|
427
|
-
model-constants.ts # AUTO-GENERATED: Models object + id constants
|
|
428
|
-
model-input-types.ts # AUTO-GENERATED: per-model TypeScript input types
|
|
429
|
-
vendors/
|
|
430
|
-
define.ts # defineModels() framework + params.* helpers
|
|
431
|
-
presets.ts # Reusable paramConfig factories
|
|
432
|
-
catalog/
|
|
433
|
-
index.ts # Aggregation: ALL_MODELS, VENDOR_CATALOGS
|
|
434
|
-
kling.ts # One file per vendor (31 total)
|
|
435
|
-
flux.ts
|
|
436
|
-
...
|
|
440
|
+
descriptors/ # Model()/catalog accessors, param descriptors, pricing
|
|
437
441
|
__tests__/ # SDK tests
|
|
438
442
|
scripts/ # Build scripts
|
|
439
443
|
```
|
|
440
444
|
|
|
441
|
-
##
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
1. Define the model config as above (no `buildPayload`)
|
|
458
|
-
2. Run `npm run build:model-input-types` — generates typed input for your model
|
|
459
|
-
3. Create `src/vendors/catalog/{vendor}.payloads.ts`:
|
|
460
|
-
```ts
|
|
461
|
-
import type { ModelInput } from '../../generated/model-input-types.ts';
|
|
462
|
-
import { registerPayloads } from '../define.ts';
|
|
463
|
-
import { SPECS, MODELS } from './{vendor}.ts';
|
|
464
|
-
|
|
465
|
-
registerPayloads({ SPECS, MODELS }, {
|
|
466
|
-
'model-id': (input: ModelInput<'model-id'>) => ({
|
|
467
|
-
prompt: input.prompt,
|
|
468
|
-
aspect_ratio: input.aspectRatio, // rename for vendor API
|
|
469
|
-
}),
|
|
470
|
-
});
|
|
471
|
-
```
|
|
472
|
-
4. Import the `.payloads.ts` file in `src/vendors/catalog/index.ts` (after the vendor import)
|
|
473
|
-
|
|
474
|
-
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.
|