@sogni-ai/sogni-client 5.82.0 → 5.84.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.
Files changed (63) hide show
  1. package/AGENTS.md +9 -2
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +59 -6
  4. package/dist/Changelog/index.d.ts +28 -0
  5. package/dist/Changelog/index.js +81 -0
  6. package/dist/Changelog/index.js.map +1 -0
  7. package/dist/Changelog/types.d.ts +83 -0
  8. package/dist/Changelog/types.js +3 -0
  9. package/dist/Changelog/types.js.map +1 -0
  10. package/dist/Chat/_hostedToolsManifest.generated.js +15 -6
  11. package/dist/Chat/_hostedToolsManifest.generated.js.map +1 -1
  12. package/dist/Chat/hostedToolValidator.js +24 -2
  13. package/dist/Chat/hostedToolValidator.js.map +1 -1
  14. package/dist/Chat/tools.js +1 -1
  15. package/dist/Chat/tools.js.map +1 -1
  16. package/dist/Projects/createJobRequestMessage.js +49 -23
  17. package/dist/Projects/createJobRequestMessage.js.map +1 -1
  18. package/dist/Projects/types/index.d.ts +20 -13
  19. package/dist/Projects/types/index.js.map +1 -1
  20. package/dist/Projects/utils/index.d.ts +24 -6
  21. package/dist/Projects/utils/index.js +34 -9
  22. package/dist/Projects/utils/index.js.map +1 -1
  23. package/dist/index.d.ts +11 -2
  24. package/dist/index.js +16 -11
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/validation.js +1 -0
  27. package/dist/lib/validation.js.map +1 -1
  28. package/dist/version.d.ts +1 -1
  29. package/dist/version.js +1 -1
  30. package/dist-esm/Changelog/index.js +76 -0
  31. package/dist-esm/Changelog/index.js.map +1 -0
  32. package/dist-esm/Changelog/types.js +2 -0
  33. package/dist-esm/Changelog/types.js.map +1 -0
  34. package/dist-esm/Chat/_hostedToolsManifest.generated.js +15 -6
  35. package/dist-esm/Chat/_hostedToolsManifest.generated.js.map +1 -1
  36. package/dist-esm/Chat/hostedToolValidator.js +24 -2
  37. package/dist-esm/Chat/hostedToolValidator.js.map +1 -1
  38. package/dist-esm/Chat/tools.js +1 -1
  39. package/dist-esm/Chat/tools.js.map +1 -1
  40. package/dist-esm/Projects/createJobRequestMessage.js +50 -24
  41. package/dist-esm/Projects/createJobRequestMessage.js.map +1 -1
  42. package/dist-esm/Projects/types/index.js.map +1 -1
  43. package/dist-esm/Projects/utils/index.js +31 -8
  44. package/dist-esm/Projects/utils/index.js.map +1 -1
  45. package/dist-esm/index.js +4 -2
  46. package/dist-esm/index.js.map +1 -1
  47. package/dist-esm/lib/validation.js +1 -0
  48. package/dist-esm/lib/validation.js.map +1 -1
  49. package/dist-esm/version.js +1 -1
  50. package/llms-full.txt +74 -11
  51. package/llms.txt +46 -7
  52. package/package.json +6 -3
  53. package/src/Changelog/index.ts +75 -0
  54. package/src/Changelog/types.ts +96 -0
  55. package/src/Chat/_hostedToolsManifest.generated.ts +15 -6
  56. package/src/Chat/hostedToolValidator.ts +30 -2
  57. package/src/Chat/tools.ts +1 -1
  58. package/src/Projects/createJobRequestMessage.ts +54 -26
  59. package/src/Projects/types/index.ts +20 -13
  60. package/src/Projects/utils/index.ts +36 -8
  61. package/src/index.ts +24 -0
  62. package/src/lib/validation.ts +1 -0
  63. package/src/version.ts +1 -1
package/AGENTS.md CHANGED
@@ -135,6 +135,8 @@ Generated artifacts:
135
135
  - `workflows.{start, list, get, events, streamEvents, resume, reseed, cancel}`
136
136
  - `workflows.templates.{list, get, create, update, delete, fork}`
137
137
  - `replay: ReplayApi` - RunRecord write/list/get via `/v1/replay/records`
138
+ - `changelog: ChangelogApi` - Public platform changelog via `/v1/changelog`, no sign-in needed
139
+ - `changelog.{list, get, products}`
138
140
  - `apiClient: ApiClient` - Internal REST + WebSocket communication
139
141
 
140
142
  ### Core Entity Hierarchy
@@ -244,6 +246,11 @@ The SDK supports two families of video models with **fundamentally different FPS
244
246
  - Minimal call: `referenceVideo` + `upscaleResolution` + `numberOfMedia: 1` + empty prompt. `frames`, `fps`, `width` and `height` are optional; the server probes the upload and adopts the verified source values, and rejects only values a caller sent that conflict with the source. The SDK sets no frame-count or duration limit: the server enforces the maximum clip length and returns a clear error for a source that is too long. Estimates take the output size, the source's `frames`/`fps`, and `sourceWidth`/`sourceHeight`.
245
247
  - `isVideoUpscaleModel()` detects it; `getVideoWorkflowType()` returns `'upscale'`. Hosted chat/workflows expose it as the `upscale_video` tool.
246
248
 
249
+ **RelayVSR** (`RELAYVSR_X2_VIDEO_UPSCALE_MODEL_ID`, `RELAYVSR_X4_VIDEO_UPSCALE_MODEL_ID`) takes the same request and adds `upscaleResolution: 2160`:
250
+ - Opt-in by model id; FlashVSR stays the `upscale_video` default. `model: 'relayvsr'` on the hosted tool selects it.
251
+ - X2 takes sources up to 1080x1920 and delivers at most twice their size; X4 takes sources up to 768x1344 and delivers at most four times. Output long edge at most 3840px. The server checks these against the probed source.
252
+ - The SDK refuses `detailPreference`, `processingSpeed` and `seed`, fixes seed to 0, and sends neither option on the wire. `isRelayVsrModel()` detects both; `isVideoUpscaleModel()` covers them.
253
+
247
254
  ### Key Files
248
255
  - `src/Projects/utils/index.ts` - `isWanModel()`, `isLtx2Model()`, `calculateVideoFrames()`
249
256
  - `src/Projects/createJobRequestMessage.ts` - Uses `calculateVideoFrames()` for duration→frames conversion
@@ -398,7 +405,7 @@ const urls = await project.waitForCompletion();
398
405
  | Text-to-Video | `*_t2v*` | None |
399
406
  | Image-to-Video | `*_i2v*` | `referenceImage` (and/or `referenceImageEnd`) |
400
407
  | First/Last-Frame Video | `*_flf2v*` (MiniMax H3) | `referenceImage` + `referenceImageEnd` |
401
- | MiniMax H3 intermediate keyframes | every H3 id except `*_t2v*`: `*_i2v*`, `*_flf2v*`, `*_ia2v*`, `*_flfa2v*`, `*_a2v*`, `*_r2v*` (`isMinimaxH3KeyframeModel`, 23 ids) | optional `keyframes: [{ image, frameIndex }]`, up to 8, alongside the workflow's own uploads; `frameIndex` is a 0-based 24 fps frame from 1 to `frames - 2` (pass `frames`: `duration` snaps to the 124 + n*17 grid); images upload to `keyframeImage1..N` in order (r2v references keep their `contextImage` slots); the prompt names each keyframe `<Picture N>` after the workflow's own pictures, lists it in the alignment line (r2v: keyframe entry, `keyframe completion` task, retention entry), describes what it shows, and cuts to a new shot where framing or light changes (see `llms.txt`) |
408
+ | MiniMax H3 intermediate keyframes | every H3 id except `*_t2v*`: `*_i2v*`, `*_flf2v*`, `*_ia2v*`, `*_flfa2v*`, `*_a2v*`, `*_r2v*` (`isMinimaxH3KeyframeModel`, 24 ids) | optional `keyframes: [{ image, frameIndex }]`, up to 8, alongside the workflow's own uploads; `frameIndex` is a 0-based 24 fps frame from 1 to `frames - 2` (pass `frames`: `duration` snaps to the 124 + n*17 grid); images upload to `keyframeImage1..N` in order (r2v references keep their `contextImage` slots); the prompt names each keyframe `<Picture N>` after the workflow's own pictures, lists it in the alignment line (r2v: keyframe entry, `keyframe completion` task, retention entry), describes what it shows, and cuts to a new shot where framing or light changes (see `llms.txt`) |
402
409
  | Reference-to-Video | `*_r2v*` (Happy Horse) | 1-9 images via `referenceImage`/`referenceImageUrls` |
403
410
  | Video-to-Video | `*_v2v*` (LTX-2.3) | `referenceVideo` + `controlNet` |
404
411
  | Sound-to-Video | `*_s2v*` (WAN only) | `referenceImage` + `referenceAudio` |
@@ -407,7 +414,7 @@ const urls = await project.waitForCompletion();
407
414
  | Audio-to-Video | `*_a2v*` (LTX-2.3, MiniMax H3 FastH3) | `referenceAudio` |
408
415
  | Animate-Move | `*_animate-move*` | `referenceImage` + `referenceVideo` |
409
416
  | Animate-Replace | `*_animate-replace*` | `referenceImage` + `referenceVideo` |
410
- | Video Upscale | `flashvsr_*` | exactly one `referenceVideo` (promptless) |
417
+ | Video Upscale | `flashvsr_*`, `relayvsr_*` | exactly one `referenceVideo` (promptless) |
411
418
 
412
419
  ## LLM Chat — Thinking Models & Tool Calling
413
420
 
package/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ # [5.84.0](https://github.com/Sogni-AI/sogni-client/compare/v5.83.0...v5.84.0) (2026-11-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **chat:** keep FlashVSR's 2160 refusal in hosted tool validation ([e65764b](https://github.com/Sogni-AI/sogni-client/commit/e65764b71aee32607339b357fe37d509d1db4007))
7
+ * **chat:** validate an unknown upscale_video model as 5.83.0 did ([a00f0e7](https://github.com/Sogni-AI/sogni-client/commit/a00f0e70f3a35989fbdce69d0f2e090cbf46a69c))
8
+
9
+
10
+ ### Features
11
+
12
+ * **minimax-h3:** add the MiniMax H3 Prism reference-to-video model id ([cda5219](https://github.com/Sogni-AI/sogni-client/commit/cda521925bde3eb95a6548b20b03ceea35f1d422))
13
+ * **video:** add RelayVSR video upscaling models ([a613f03](https://github.com/Sogni-AI/sogni-client/commit/a613f03ae0b76198e6e6c4c8fa19f3411f3d0f9a))
14
+ * **video:** refuse a RelayVSR output past 3840 on the long edge ([77261b9](https://github.com/Sogni-AI/sogni-client/commit/77261b9c0e0734ec020c58a6a79a073ebaf3a1d7))
15
+
16
+ # [5.83.0](https://github.com/Sogni-AI/sogni-client/compare/v5.82.0...v5.83.0) (2026-11-14)
17
+
18
+
19
+ ### Features
20
+
21
+ * **changelog:** add sogni.changelog to read the public Sogni changelog ([68a264a](https://github.com/Sogni-AI/sogni-client/commit/68a264a2255e13af7b554b13eddea49b9bb223d3))
22
+
1
23
  # [5.82.0](https://github.com/Sogni-AI/sogni-client/compare/v5.81.0...v5.82.0) (2026-11-13)
2
24
 
3
25
 
package/README.md CHANGED
@@ -228,7 +228,8 @@ const sogni = await SogniClient.createInstance({
228
228
  ```
229
229
 
230
230
  Socket-backed project generation and chat completions are unavailable in REST-only mode. Hosted
231
- chat, durable workflows, replay records, announcements, and account REST APIs remain available.
231
+ chat, durable workflows, replay records, announcements, the platform changelog, and account REST
232
+ APIs remain available.
232
233
 
233
234
  ### Connection metadata and event subscriptions
234
235
 
@@ -1365,11 +1366,15 @@ Example model IDs:
1365
1366
  - `minimax-h3-fastvideo-int8_t2v_turbo_2stage` / `minimax-h3-fastvideo-int8_i2v_turbo_2stage` / `minimax-h3-fastvideo-int8_flf2v_turbo_2stage` / `minimax-h3-fastvideo-int8_ia2v_turbo_2stage` / `minimax-h3-fastvideo-int8_flfa2v_turbo_2stage` / `minimax-h3-fastvideo-int8_a2v_turbo_2stage` (MiniMax H3 FastH3 Two-Stage: the FastH3 Turbo request, delivered at twice the canvas with the same length and audio. 720p: the chosen aspect at a 384 px short edge, 672×384 → 1344×768. 1080p: a 544 px short edge, 960×544 → 1920×1088. 2K: the 768p canvas, 1344×768 → 2688×1536)
1366
1367
  - `minimax-h3-ref2va-fp8_r2v_2stage` / `minimax-h3-ref2va-fp8_r2v_balanced_2stage` (MiniMax H3 Two-Stage Reference-to-Video: the Standard 20-step or Balanced 8-step Ref2VA request, delivered at twice the canvas with the same length, audio and references; the same 384/544/768 px canvas choices as the FastH3 Two-Stage ids)
1367
1368
  - `minimax-h3-fastvideo-omni-int8_r2v_turbo` / `minimax-h3-fastvideo-omni-int8_r2v_turbo_2stage` (MiniMax H3 FastH3 Reference: FastVideo's FastH3 Omni, the FastH3 tier's Reference-to-Video on its own distilled checkpoint, with the same references, catalog LoRAs and Personal LoRAs as the other r2v ids; omit `steps`, since it is not a four-step Turbo id despite the suffix. The `_2stage` id takes the same request and delivers twice the canvas)
1369
+ - `minimax-h3-prism-int8_r2v` (MiniMax H3 Prism: an optional Reference-to-Video model for mature themes with its recipe fixed at 8 Euler steps; the same references, keyframes and catalog LoRAs as the other r2v ids at the 768p class only, with no two-stage id; requires `disableNSFWFilter: true` and is subject to server authorization)
1368
1370
  - `flashvsr_v1.1_tiny_long_bf16` (FlashVSR v1.1 promptless 1080p/1440p video upscaling of one finished video)
1371
+ - `relayvsr_x2_lightx2v_int8_convrot`, `relayvsr_x4_int8_convrot` (RelayVSR 2x and 4x promptless video upscaling up to 2160p of one finished video)
1369
1372
 
1370
1373
  The repository does not bundle sample prompts or input media for the 10Eros model. Creators
1371
1374
  who choose to use it must provide their own prompt and image to
1372
- `examples/workflow_image_to_video.mjs`. Optional test prompts and images are available from the
1375
+ `examples/workflow_image_to_video.mjs`. The same applies to MiniMax H3 Prism in
1376
+ `examples/workflow_minimax_h3_video.mjs` (`--model minimax-h3-r2v-prism`), which also requires
1377
+ `--disable-safe-content-filter`. Optional test prompts and images are available from the
1373
1378
  [model author's sample gallery](https://civitai.red/models/2447875/ltx23-10eros).
1374
1379
 
1375
1380
  ### Video Parameters
@@ -1384,13 +1389,13 @@ When creating video projects, you can specify:
1384
1389
  - `steps` - Increase inference steps to increase quality
1385
1390
  - `seed` - Random seed for reproducibility
1386
1391
  - `referenceImage` - Reference image for workflows that require it (i2v, s2v, animate-move, animate-replace)
1387
- - `referenceVideo` - Reference video for animate and v2v workflows, and the source video for FlashVSR upscaling
1388
- - `upscaleResolution` - FlashVSR only: output short edge, `1080` or `1440`
1392
+ - `referenceVideo` - Reference video for animate and v2v workflows, and the source video for FlashVSR and RelayVSR upscaling
1393
+ - `upscaleResolution` - Video upscaling only: output short edge, `1080` or `1440`, or `2160` on RelayVSR
1389
1394
  - `referenceVideoDurations` - Optional MiniMax H3 r2v duration hints in `[referenceVideo, ...referenceVideos]` order for early client-side validation; Socket probes the uploaded files and uses measured durations for pricing and admission
1390
1395
  - `referenceVideoCompression` - Legacy MiniMax H3 reference-video preference (`'none'` or `'vpack'`), retained for compatibility. Current services select compression automatically; this field no longer selects compression. Leave it unset for new requests.
1391
1396
  - `referenceAudio` - Reference audio for sound-to-video workflows (s2v, ia2v, flfa2v, a2v)
1392
1397
  - `referenceImageEnd` - Last frame for i2v, flf2v and the MiniMax H3 FastH3 flfa2v audio-guide workflow
1393
- - `keyframes` - Every MiniMax H3 workflow except t2v (23 ids, `isMinimaxH3KeyframeModel()`: i2v and flf2v on every tier, Sound to Video ia2v/flfa2v/a2v, and r2v): up to `MINIMAX_H3_MAX_KEYFRAMES` (8) `{ image, frameIndex }` stills pinned between the first and last frame. `frameIndex` is the 0-based frame at 24 fps (`Math.round(seconds * 24)`), an integer from 1 to `frames - 2`, each frame used once. Pass `frames` from the H3 grid (124, 141, 158, … 362) so the count is exact: `duration` snaps to the grid (`duration: 6` renders 141 frames, not 144). Frame 0 and the last frame are never keyframes: i2v, flf2v and flfa2v set them with `referenceImage` / `referenceImageEnd`, ia2v sets frame 0 with `referenceImage`, and a2v and r2v cannot pin them. The prompt names each keyframe `<Picture N>` (MiniMax's keyframe format), numbered in time order after the workflow's own pictures: after the first frame on i2v and ia2v (after the last frame on a last-frame-only i2v job), after the first and last frames on flf2v and flfa2v, from `<Picture 1>` on a2v, and after the reference images on r2v; keyframes still never count as references. i2v, flf2v and Sound to Video prompts open with one alignment line listing every picture at its mark (`How the reference pictures align with the target video — Picture 1 (from Shot 1) aligns with the 0.00-second mark of the target video; Picture 2 (from Shot 2) aligns with the 2.88-second mark of the target video.`), the shot where a keyframe lands says "the shot's keyframe corresponds to `<Picture N>`", and r2v adds a `<Picture N> is the keyframe of [Shot M], showing ...` entry, `keyframe completion` in the summary tasks and a `<Picture N> ([Shot M] keyframe): fully_preserved - ...` retention entry. H3's text encoder never sees the keyframe images, so the prompt must still describe what each keyframe shows at its time. On Sound to Video the audio drives the performance and keyframes pin how it looks at their times. When a keyframe changes the framing, camera angle, location or light, start a new shot (a hard cut) in the prompt at its time: two differently framed or lit stills inside one continuous shot cross-fade, and a shot described differently from its still can flash the still for a single frame. Images upload to their own `keyframeImage1..N` slots in array order, so r2v sends its references (`referenceImage`, `contextImages`) and keyframes together. If no worker serving the model can pin keyframes yet, the job is refused with error code `4100` MiniMax H3 keyframe pricing: the first two keyframes are included; each extra keyframe adds output time at the job's per-second rate, 0.75 s on FastH3 and 0.3 s on every other tier, FastH3 Reference included (an 8 s FastH3 clip with 8 keyframes: 32 + 18 = 50 Spark). Pass `keyframeCount` (or the job's `keyframes`) to `estimateVideoCost` to quote it.
1398
+ - `keyframes` - Every MiniMax H3 workflow except t2v (24 ids, `isMinimaxH3KeyframeModel()`: i2v and flf2v on every tier, Sound to Video ia2v/flfa2v/a2v, and r2v): up to `MINIMAX_H3_MAX_KEYFRAMES` (8) `{ image, frameIndex }` stills pinned between the first and last frame. `frameIndex` is the 0-based frame at 24 fps (`Math.round(seconds * 24)`), an integer from 1 to `frames - 2`, each frame used once. Pass `frames` from the H3 grid (124, 141, 158, … 362) so the count is exact: `duration` snaps to the grid (`duration: 6` renders 141 frames, not 144). Frame 0 and the last frame are never keyframes: i2v, flf2v and flfa2v set them with `referenceImage` / `referenceImageEnd`, ia2v sets frame 0 with `referenceImage`, and a2v and r2v cannot pin them. The prompt names each keyframe `<Picture N>` (MiniMax's keyframe format), numbered in time order after the workflow's own pictures: after the first frame on i2v and ia2v (after the last frame on a last-frame-only i2v job), after the first and last frames on flf2v and flfa2v, from `<Picture 1>` on a2v, and after the reference images on r2v; keyframes still never count as references. i2v, flf2v and Sound to Video prompts open with one alignment line listing every picture at its mark (`How the reference pictures align with the target video — Picture 1 (from Shot 1) aligns with the 0.00-second mark of the target video; Picture 2 (from Shot 2) aligns with the 2.88-second mark of the target video.`), the shot where a keyframe lands says "the shot's keyframe corresponds to `<Picture N>`", and r2v adds a `<Picture N> is the keyframe of [Shot M], showing ...` entry, `keyframe completion` in the summary tasks and a `<Picture N> ([Shot M] keyframe): fully_preserved - ...` retention entry. H3's text encoder never sees the keyframe images, so the prompt must still describe what each keyframe shows at its time. On Sound to Video the audio drives the performance and keyframes pin how it looks at their times. When a keyframe changes the framing, camera angle, location or light, start a new shot (a hard cut) in the prompt at its time: two differently framed or lit stills inside one continuous shot cross-fade, and a shot described differently from its still can flash the still for a single frame. Images upload to their own `keyframeImage1..N` slots in array order, so r2v sends its references (`referenceImage`, `contextImages`) and keyframes together. If no worker serving the model can pin keyframes yet, the job is refused with error code `4100` MiniMax H3 keyframe pricing: the first two keyframes are included; each extra keyframe adds output time at the job's per-second rate, 0.75 s on FastH3 and 0.3 s on every other tier, FastH3 Reference included (an 8 s FastH3 clip with 8 keyframes: 32 + 18 = 50 Spark). Pass `keyframeCount` (or the job's `keyframes`) to `estimateVideoCost` to quote it.
1394
1399
  - `referenceImageUrls` - Loose image context URLs for Seedance, Happy Horse, and Wan 3; Wan 3 accepts up to 10
1395
1400
  - `referenceVideoUrls` - Loose video context URLs for Seedance and Wan 3; Wan 3 accepts up to 5
1396
1401
  - `referenceAudioUrls` - Loose audio context URLs for Seedance and Wan 3; Wan 3 accepts up to 5
@@ -1619,6 +1624,30 @@ const [upscaledUrl] = await project.waitForCompletion(); // MP4 with the origina
1619
1624
 
1620
1625
  To show a price first, call `estimateVideoCost()` with the output `width`/`height` (the source scaled so its short edge equals the target, both edges rounded to even pixels), the source's `frames` and `fps`, `steps: 1`, and `sourceWidth`/`sourceHeight`; the job itself is charged from the verified source. In hosted chat and durable workflows, the same operation is the promptless `upscale_video` tool.
1621
1626
 
1627
+ ### Video Upscale Example (RelayVSR)
1628
+
1629
+ `RELAYVSR_X2_VIDEO_UPSCALE_MODEL_ID` (`relayvsr_x2_lightx2v_int8_convrot`) and `RELAYVSR_X4_VIDEO_UPSCALE_MODEL_ID` (`relayvsr_x4_int8_convrot`) upscale one finished video to 1080p, 1440p, or 2160p on its short edge. The request is the same as FlashVSR's: one `referenceVideo`, `upscaleResolution`, `numberOfMedia: 1`, and an empty prompt. The output keeps every source frame, the exact frame rate, the full aspect ratio, and the original audio.
1630
+
1631
+ X2 takes a source up to 1080x1920 pixels (either orientation) and delivers at most twice its size; X4 takes a source up to 768x1344 and delivers at most four times its size. The target must be larger than the source's short edge, and the output's long edge can be at most 3840px, so 2160p needs a source short edge of exactly 1080px on X2 or 540px to 768px on X4. Sources must be 1-60 fps, SDR, and 100 MB or less, and the server enforces the maximum clip length. Variable-frame-rate, rotated and non-square-pixel clips need no re-export for RelayVSR: the server conforms them, and every limit applies to the clip as it plays.
1632
+
1633
+ ```javascript
1634
+ import fs from 'node:fs';
1635
+ import { RELAYVSR_X2_VIDEO_UPSCALE_MODEL_ID } from '@sogni-ai/sogni-client';
1636
+
1637
+ const project = await sogni.projects.create({
1638
+ type: 'video',
1639
+ network: 'fast',
1640
+ modelId: RELAYVSR_X2_VIDEO_UPSCALE_MODEL_ID,
1641
+ positivePrompt: '',
1642
+ numberOfMedia: 1,
1643
+ referenceVideo: fs.readFileSync('./clip-1080p.mp4'),
1644
+ upscaleResolution: 2160 // 1080 | 1440 | 2160: the output's short edge
1645
+ });
1646
+ const [upscaledUrl] = await project.waitForCompletion(); // MP4 with the original audio
1647
+ ```
1648
+
1649
+ `isRelayVsrModel(modelId)` detects both models, and `isVideoUpscaleModel(modelId)` covers them too. The SDK refuses `detailPreference`, `processingSpeed`, and `seed` for RelayVSR. Quote it the same way as FlashVSR, with the output `width`/`height` and `sourceWidth`/`sourceHeight`; the price follows the source's size and length, not the target. In hosted chat and durable workflows, set `model: 'relayvsr'` on `upscale_video`; the server picks X2 when the target is at most twice the source's short edge and X4 otherwise. FlashVSR stays the tool's default.
1650
+
1622
1651
  ## LLM Text Generation & Tool Calling
1623
1652
 
1624
1653
  The Sogni SDK supports LLM text generation through the Sogni Supernet, providing an OpenAI-compatible chat completions API with streaming, multi-turn conversations, and tool calling (function calling).
@@ -1691,7 +1720,7 @@ Combine LLM intelligence with Sogni's media generation capabilities. The SDK exp
1691
1720
 
1692
1721
  - **Generation** — `generate_image`, `edit_image`, `generate_video`, `sound_to_video`, `video_to_video`, `generate_music`, `generate_speech`
1693
1722
  - **Image adapters** — `restore_photo`, `apply_style`, `refine_result`, `change_angle`, `animate_photo` (image-to-video with multi-source fan-out)
1694
- - **Upscaling** — `upscale_image` (promptless RTX VSR), `upscale_video` (promptless FlashVSR 1080p/1440p video upscale that keeps every frame, the frame rate, and the original audio)
1723
+ - **Upscaling** — `upscale_image` (promptless RTX VSR), `upscale_video` (promptless FlashVSR 1080p/1440p video upscale, or RelayVSR up to 2160p by `model: 'relayvsr'`, that keeps every frame, the frame rate, and the original audio)
1695
1724
  - **Video composition / post-production** — `stitch_video`, `orbit_video`, `dance_montage`, `extend_video`, `replace_video_segment`, `overlay_video`, `add_subtitles`
1696
1725
  - **Synchronous composition and planning** — `enhance_prompt`, `compose_script`, `compose_lyrics`, `compose_instrumental`, `compose_workflow`, `compose_workflow_template`
1697
1726
 
@@ -1911,6 +1940,30 @@ async function startWithRetry(params, attempts = 5) {
1911
1940
 
1912
1941
  See `examples/workflow_creative_agent_workflows.mjs` for start/list/get/events/stream/cancel coverage. The underlying REST endpoints remain documented in the [LLM API durable workflows reference](https://github.com/Sogni-AI/sogni-api/blob/main/docs/llm-api.md#durable-creative-agent-workflows).
1913
1942
 
1943
+ ## Platform changelog
1944
+
1945
+ `sogni.changelog` reads Sogni's public changelog: what changed for artists, developers and worker operators. These reads need no sign-in, so a REST-only client without an API key can make them:
1946
+
1947
+ ```javascript
1948
+ const sogni = await SogniClient.createInstance({ disableSocket: true });
1949
+
1950
+ const filters = { audience: 'developer', since: '2026-11-01' };
1951
+ const { entries, nextCursor } = await sogni.changelog.list(filters);
1952
+ for (const entry of entries) console.log(entry.publishedAt, entry.title, entry.url);
1953
+
1954
+ // The next page takes the same filters plus the cursor; nextCursor is null on the last page.
1955
+ const older = nextCursor ? await sogni.changelog.list({ ...filters, cursor: nextCursor }) : null;
1956
+
1957
+ const entry = await sogni.changelog.get(entries[0].id);
1958
+ const products = await sogni.changelog.products(); // [{ id, label, audiences }]
1959
+ ```
1960
+
1961
+ - `list(options)` returns `{ entries, nextCursor }`, newest first. `audience` (`artist`, `developer`, `worker`), `product` (ids from `products()`) and `type` (`new`, `improved`, `fixed`, `release`, `deprecated`, `removed`, `notice`) take one value or an array. `since` (inclusive) and `until` (exclusive) take an ISO 8601 date or a date-time with a zone. `actionRequired: true` lists only entries you need to act on. `limit` defaults to 50; the API returns at most 100.
1962
+ - `get(id)` returns one entry. An id with no published entry throws `ApiError` with `status` 404 and `payload.errorCode` 204.
1963
+ - For a deprecation or removal, `effectiveAt` is the day the old behavior stops working.
1964
+
1965
+ Responses can be up to five minutes old, so poll no more often than that. The [Changelog API reference](https://docs.sogni.ai/api-reference/changelog/) has the full contract, including the JSON Feed and Atom feeds.
1966
+
1914
1967
  ## Code Examples
1915
1968
 
1916
1969
  ### Hosted World Builds (server-side)
@@ -0,0 +1,28 @@
1
+ import ApiGroup from '../ApiGroup.js';
2
+ import type { ChangelogEntry, ChangelogProduct, ListChangelogOptions, ListChangelogResult } from './types.js';
3
+ /**
4
+ * The public Sogni changelog (`/v1/changelog`): what changed on Sogni for
5
+ * artists, developers and worker operators.
6
+ *
7
+ * These reads need no sign-in, so they work on a client that is not
8
+ * authenticated. Responses may be up to five minutes old; poll no more often
9
+ * than that. A refused request throws `ApiError` with the API's status and
10
+ * message.
11
+ *
12
+ * Full contract: https://docs.sogni.ai/api-reference/changelog/
13
+ */
14
+ declare class ChangelogApi extends ApiGroup {
15
+ /**
16
+ * One page of published entries, newest first. Pass the returned
17
+ * `nextCursor` as `cursor`, with the same filters, for the next page.
18
+ */
19
+ list(options?: ListChangelogOptions): Promise<ListChangelogResult>;
20
+ /**
21
+ * One published entry by its id. An id with no published entry throws
22
+ * `ApiError` with status `404` and `payload.errorCode` `204`.
23
+ */
24
+ get(id: string): Promise<ChangelogEntry>;
25
+ /** The products entries can name, in display order. */
26
+ products(): Promise<ChangelogProduct[]>;
27
+ }
28
+ export default ChangelogApi;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const ApiGroup_js_1 = __importDefault(require("../ApiGroup.js"));
16
+ const index_js_1 = require("../ApiClient/index.js");
17
+ function joined(value) {
18
+ return Array.isArray(value) ? value.join(',') : value;
19
+ }
20
+ /**
21
+ * The public Sogni changelog (`/v1/changelog`): what changed on Sogni for
22
+ * artists, developers and worker operators.
23
+ *
24
+ * These reads need no sign-in, so they work on a client that is not
25
+ * authenticated. Responses may be up to five minutes old; poll no more often
26
+ * than that. A refused request throws `ApiError` with the API's status and
27
+ * message.
28
+ *
29
+ * Full contract: https://docs.sogni.ai/api-reference/changelog/
30
+ */
31
+ class ChangelogApi extends ApiGroup_js_1.default {
32
+ /**
33
+ * One page of published entries, newest first. Pass the returned
34
+ * `nextCursor` as `cursor`, with the same filters, for the next page.
35
+ */
36
+ list() {
37
+ return __awaiter(this, arguments, void 0, function* (options = {}) {
38
+ const res = yield this.client.rest.get('/v1/changelog', {
39
+ audience: joined(options.audience),
40
+ product: joined(options.product),
41
+ type: joined(options.type),
42
+ since: options.since,
43
+ until: options.until,
44
+ actionRequired: options.actionRequired ? 'true' : undefined,
45
+ limit: options.limit,
46
+ cursor: options.cursor
47
+ });
48
+ return res.data;
49
+ });
50
+ }
51
+ /**
52
+ * One published entry by its id. An id with no published entry throws
53
+ * `ApiError` with status `404` and `payload.errorCode` `204`.
54
+ */
55
+ get(id) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ var _a;
58
+ const res = yield this.client.rest.get(`/v1/changelog/${encodeURIComponent(id)}`);
59
+ const entry = (_a = res.data) === null || _a === void 0 ? void 0 : _a.entry;
60
+ if (!entry) {
61
+ // An empty id requests the list itself, and `products` or `feed.json` the
62
+ // product list or the feed; none of them is an entry.
63
+ throw new index_js_1.ApiError(404, {
64
+ status: 'error',
65
+ message: 'Changelog entry not found',
66
+ errorCode: 204
67
+ });
68
+ }
69
+ return entry;
70
+ });
71
+ }
72
+ /** The products entries can name, in display order. */
73
+ products() {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ const res = yield this.client.rest.get('/v1/changelog/products');
76
+ return res.data.products;
77
+ });
78
+ }
79
+ }
80
+ exports.default = ChangelogApi;
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Changelog/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,iEAAsC;AACtC,oDAA8D;AAQ9D,SAAS,MAAM,CAAC,KAAoC;IAClD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACxD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,YAAa,SAAQ,qBAAQ;IACjC;;;OAGG;IACG,IAAI;6DAAC,UAAgC,EAAE;YAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAmC,eAAe,EAAE;gBACxF,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAClC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBAChC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,cAAc,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBAC3D,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,IAAI,CAAC;QAClB,CAAC;KAAA;IAED;;;OAGG;IACG,GAAG,CAAC,EAAU;;;YAClB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CACpC,iBAAiB,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAC1C,CAAC;YACF,MAAM,KAAK,GAAG,MAAA,GAAG,CAAC,IAAI,0CAAE,KAAK,CAAC;YAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,0EAA0E;gBAC1E,sDAAsD;gBACtD,MAAM,IAAI,mBAAQ,CAAC,GAAG,EAAE;oBACtB,MAAM,EAAE,OAAO;oBACf,OAAO,EAAE,2BAA2B;oBACpC,SAAS,EAAE,GAAG;iBACf,CAAC,CAAC;YACL,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KAAA;IAED,uDAAuD;IACjD,QAAQ;;YACZ,MAAM,GAAG,GACP,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CACxB,wBAAwB,CACzB,CAAC;YACJ,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC3B,CAAC;KAAA;CACF;AAED,kBAAe,YAAY,CAAC"}
@@ -0,0 +1,83 @@
1
+ /** Who a changelog entry is for. */
2
+ export type ChangelogAudience = 'artist' | 'developer' | 'worker';
3
+ /**
4
+ * The kind of change. Every entry has exactly one:
5
+ * - `new`: something you could not do before
6
+ * - `improved`: a change to something that already worked
7
+ * - `fixed`: a fix
8
+ * - `release`: a versioned release, such as a worker or SDK version
9
+ * - `deprecated`: still works, until `effectiveAt`
10
+ * - `removed`: no longer available
11
+ * - `notice`: anything else you should know
12
+ */
13
+ export type ChangelogEntryType = 'new' | 'improved' | 'fixed' | 'release' | 'deprecated' | 'removed' | 'notice';
14
+ /** A page related to a changelog entry. */
15
+ export interface ChangelogLink {
16
+ label: string;
17
+ url: string;
18
+ }
19
+ /** One published changelog entry. Times are ISO 8601 UTC strings. */
20
+ export interface ChangelogEntry {
21
+ /** Permanent identifier. It does not change once the entry is published. */
22
+ id: string;
23
+ /** The entry's page on sogni.ai. */
24
+ url: string;
25
+ title: string;
26
+ /** Short summary in plain text. */
27
+ summary: string;
28
+ /** The full text in Markdown. */
29
+ bodyMarkdown: string | null;
30
+ type: ChangelogEntryType;
31
+ audiences: ChangelogAudience[];
32
+ /** Product ids, as listed by `changelog.products()`. */
33
+ products: string[];
34
+ /** The product version the change shipped in. */
35
+ version: string | null;
36
+ links: ChangelogLink[];
37
+ /** `true` when you need to change something, such as for a model retirement. */
38
+ actionRequired: boolean;
39
+ /** When the change takes effect. For a deprecation or removal, the day the old behavior stops working. */
40
+ effectiveAt: string | null;
41
+ /** When the entry was published. Lists sort and filter on it. */
42
+ publishedAt: string;
43
+ /** When any public field of the entry last changed. */
44
+ updatedAt: string;
45
+ }
46
+ /** A product that changelog entries can name. */
47
+ export interface ChangelogProduct {
48
+ /** The id to use with the `product` filter. */
49
+ id: string;
50
+ /** Display name. */
51
+ label: string;
52
+ audiences: ChangelogAudience[];
53
+ }
54
+ /**
55
+ * Filters and paging for `changelog.list()`. Every field is optional. An entry
56
+ * must match every filter given; a filter given several values matches entries
57
+ * that have any of them (at most 20 values per filter).
58
+ */
59
+ export interface ListChangelogOptions {
60
+ audience?: ChangelogAudience | ChangelogAudience[];
61
+ /** Product ids from `changelog.products()`. */
62
+ product?: string | string[];
63
+ type?: ChangelogEntryType | ChangelogEntryType[];
64
+ /**
65
+ * Entries published at or after this time: an ISO 8601 date (`'2026-11-01'`,
66
+ * read as midnight UTC) or a date-time with a zone (`'2026-11-01T17:00:00Z'`).
67
+ */
68
+ since?: string;
69
+ /** Entries published before this time, in the same format as `since`. */
70
+ until?: string;
71
+ /** `true` lists only the entries you need to act on. */
72
+ actionRequired?: boolean;
73
+ /** Entries per page. The API defaults to 50 and returns at most 100. */
74
+ limit?: number;
75
+ /** The previous page's `nextCursor`. Send the same filters with it. */
76
+ cursor?: string;
77
+ }
78
+ /** One page of changelog entries, newest first. */
79
+ export interface ListChangelogResult {
80
+ entries: ChangelogEntry[];
81
+ /** Pass as `cursor` to get the next page. `null` on the last page. */
82
+ nextCursor: string | null;
83
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/Changelog/types.ts"],"names":[],"mappings":""}
@@ -808,7 +808,7 @@ exports.SOGNI_HOSTED_TOOLS_MANIFEST = {
808
808
  "type": "function",
809
809
  "function": {
810
810
  "name": "upscale_video",
811
- "description": "Upscale an existing video to 1080p or 1440p with FlashVSR video super-resolution. This is promptless, deterministic enhancement, not a generative edit: it keeps every source frame, the exact frame rate, the full aspect ratio, and the original audio, and it never changes content, trims, crops, restyles, or interpolates frames. Use it when the user asks to upscale, enlarge, sharpen, or increase the resolution of an uploaded or previously generated video, or wants an HD, 1080p, 1440p, or 2K copy of it. Do not use it to create, restyle, extend, or edit a video; when the user explicitly asks a generative model such as Seedance to re-render the clip, use video_to_video. The output is at most twice the source size, so 1080p needs a source whose short edge is 540-768px and 1440p needs 720-768px, and the source can be at most about 1344x768 pixels (768x1344 in portrait). It must also be 1-60 fps and at most 100 MB. The server sets the maximum clip length and rejects a source that is too long; never quote a length limit yourself, and if the tool reports that rejection, relay that error to the user. It cannot produce 4K or any size above 1440p; when the user asks for one, say so and offer 1440p. Each upscale costs credits based on the source video's size and length. Optional detailPreference (stable or sharper), processingSpeed (stable or faster), and seed tune the result; omit them unless the user asks, and none of them changes the price.",
811
+ "description": "Upscale an existing video to 1080p, 1440p or 2160p (4K) with recommended RelayVSR, or to 1080p or 1440p with FlashVSR. This is promptless, deterministic enhancement, not a generative edit: it keeps every source frame, the exact frame rate, the full aspect ratio, and the original audio, and it never changes content, trims, crops, restyles, or interpolates frames. Use it when the user asks to upscale, enlarge, sharpen, or increase the resolution of an uploaded or previously generated video, or wants an HD, 1080p, 1440p, 2K, or 4K copy of it. Do not use it to create, restyle, extend, or edit a video; when the user explicitly asks a generative model such as Seedance to re-render the clip, use video_to_video. Explicitly set model to relayvsr for new upscales. Use flashvsr when the user requests FlashVSR or specifically wants its detailPreference, processingSpeed or seed controls. Omitted model retains FlashVSR for compatibility. With FlashVSR the output is at most twice the source size, so 1080p needs a source whose short edge is 540-768px and 1440p needs 720-768px, and the source can be at most about 1344x768 pixels (768x1344 in portrait). With RelayVSR the output is at most twice the source size for a source up to 1920x1080 pixels (1080x1920 in portrait), or four times for a source up to 1344x768 (768x1344 in portrait), so 2160p needs a source whose short edge is 540-768px or exactly 1080px, and the output's long edge can be at most 3840px. The source must also be 1-60 fps and at most 100 MB. The server sets the maximum clip length and rejects a source that is too long; never quote a length limit yourself, and if the tool reports that rejection, relay that error to the user. FlashVSR cannot produce 4K or any size above 1440p, so a 4K request always uses relayvsr. Nothing here produces a size above 2160p; when the user asks for one, say so and offer 2160p. Each upscale costs credits based on the source video's size and length. With FlashVSR, optional detailPreference (stable or sharper), processingSpeed (stable or faster), and seed tune the result; omit them unless the user asks, and none of them changes the price. RelayVSR refuses all three.",
812
812
  "parameters": {
813
813
  "type": "object",
814
814
  "properties": {
@@ -816,13 +816,22 @@ exports.SOGNI_HOSTED_TOOLS_MANIFEST = {
816
816
  "type": "number",
817
817
  "description": "Source video to upscale. Non-negative values select a prior generated video result by 0-based index. Negative values select uploaded videos: -1 is the first uploaded video, -2 the second, and so on. If omitted, use the latest generated video, falling back to the most recent uploaded video."
818
818
  },
819
+ "model": {
820
+ "type": "string",
821
+ "enum": [
822
+ "flashvsr",
823
+ "relayvsr"
824
+ ],
825
+ "description": "Upscaler. Explicitly select relayvsr, recommended for new upscales to 1080p, 1440p or 2160p. Use flashvsr when requested or for its detailPreference, processingSpeed or seed controls; it reaches 1080p or 1440p. RelayVSR takes none of those options. Omitted model retains FlashVSR for compatibility."
826
+ },
819
827
  "targetResolution": {
820
828
  "type": "number",
821
829
  "enum": [
822
830
  1080,
823
- 1440
831
+ 1440,
832
+ 2160
824
833
  ],
825
- "description": "Output resolution of the short edge in pixels: 1440 for 1440p/2K or 1080 for 1080p/Full HD. The long edge follows the source aspect ratio, so portrait videos stay portrait. Default: 1440, or 1080 when the source's short edge is below 720px. Set 1080 when the user asks for 1080p or Full HD."
834
+ "description": "Output resolution of the short edge in pixels: 2160 for 2160p/4K (relayvsr only), 1440 for 1440p/2K, or 1080 for 1080p/Full HD. The long edge follows the source aspect ratio, so portrait videos stay portrait. Default: 1440, or 1080 when the source is too small for 1440p. Set 1080 when the user asks for 1080p or Full HD, and 2160 with model relayvsr when the user asks for 4K or 2160p."
826
835
  },
827
836
  "detailPreference": {
828
837
  "type": "string",
@@ -830,7 +839,7 @@ exports.SOGNI_HOSTED_TOOLS_MANIFEST = {
830
839
  "stable",
831
840
  "sharper"
832
841
  ],
833
- "description": "Detail preference. stable, the default, gives the most temporally stable result. sharper renders crisper fine detail with a little more risk of shimmer between frames. Set sharper only when the user asks for a sharper, crisper, or more detailed upscale; otherwise omit it. It does not change the price."
842
+ "description": "FlashVSR only. Detail preference. stable, the default, gives the most temporally stable result. sharper renders crisper fine detail with a little more risk of shimmer between frames. Set sharper only when the user asks for a sharper, crisper, or more detailed upscale; otherwise omit it. It does not change the price."
834
843
  },
835
844
  "processingSpeed": {
836
845
  "type": "string",
@@ -838,13 +847,13 @@ exports.SOGNI_HOSTED_TOOLS_MANIFEST = {
838
847
  "stable",
839
848
  "faster"
840
849
  ],
841
- "description": "Processing speed. stable, the default, gives the most stable result. faster finishes sooner with slightly less stable detail. Set faster only when the user asks for a quicker upscale; otherwise omit it. It does not change the price."
850
+ "description": "FlashVSR only. Processing speed. stable, the default, gives the most stable result. faster finishes sooner with slightly less stable detail. Set faster only when the user asks for a quicker upscale; otherwise omit it. It does not change the price."
842
851
  },
843
852
  "seed": {
844
853
  "type": "integer",
845
854
  "minimum": -1,
846
855
  "maximum": 4294967295,
847
- "description": "Seed for the upscaler's fine texture, 0 through 4294967295; different seeds give slightly different fine detail. Omit it to keep the repeatable default of 0. Use -1 for a random seed. Set it only when the user gives a seed or asks for a different or random variation of an upscale."
856
+ "description": "FlashVSR only. Seed for the upscaler's fine texture, 0 through 4294967295; different seeds give slightly different fine detail. Omit it to keep the repeatable default of 0. Use -1 for a random seed. Set it only when the user gives a seed or asks for a different or random variation of an upscale."
848
857
  }
849
858
  },
850
859
  "required": []