@sogni-ai/sogni-client 4.0.0-alpha.5 → 4.0.0-alpha.51

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 (109) hide show
  1. package/CHANGELOG.md +357 -0
  2. package/README.md +295 -58
  3. package/dist/Account/index.d.ts +18 -16
  4. package/dist/Account/index.js +42 -21
  5. package/dist/Account/index.js.map +1 -1
  6. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.d.ts +66 -0
  7. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.js +332 -0
  8. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.js.map +1 -0
  9. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +28 -0
  10. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +203 -0
  11. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -0
  12. package/dist/ApiClient/WebSocketClient/events.d.ts +12 -0
  13. package/dist/ApiClient/WebSocketClient/index.d.ts +2 -2
  14. package/dist/ApiClient/WebSocketClient/index.js +13 -3
  15. package/dist/ApiClient/WebSocketClient/index.js.map +1 -1
  16. package/dist/ApiClient/WebSocketClient/types.d.ts +13 -0
  17. package/dist/ApiClient/index.d.ts +4 -4
  18. package/dist/ApiClient/index.js +23 -4
  19. package/dist/ApiClient/index.js.map +1 -1
  20. package/dist/Projects/Job.d.ts +44 -4
  21. package/dist/Projects/Job.js +83 -16
  22. package/dist/Projects/Job.js.map +1 -1
  23. package/dist/Projects/Project.d.ts +18 -0
  24. package/dist/Projects/Project.js +38 -10
  25. package/dist/Projects/Project.js.map +1 -1
  26. package/dist/Projects/createJobRequestMessage.d.ts +2 -1
  27. package/dist/Projects/createJobRequestMessage.js +173 -14
  28. package/dist/Projects/createJobRequestMessage.js.map +1 -1
  29. package/dist/Projects/index.d.ts +114 -11
  30. package/dist/Projects/index.js +504 -47
  31. package/dist/Projects/index.js.map +1 -1
  32. package/dist/Projects/types/ComfySamplerParams.d.ts +0 -0
  33. package/dist/Projects/types/ComfySamplerParams.js +2 -0
  34. package/dist/Projects/types/ComfySamplerParams.js.map +1 -0
  35. package/dist/Projects/types/EstimationResponse.d.ts +2 -0
  36. package/dist/Projects/types/ModelOptions.d.ts +31 -0
  37. package/dist/Projects/types/ModelOptions.js +56 -0
  38. package/dist/Projects/types/ModelOptions.js.map +1 -0
  39. package/dist/Projects/types/ModelTiersRaw.d.ts +67 -0
  40. package/dist/Projects/types/ModelTiersRaw.js +15 -0
  41. package/dist/Projects/types/ModelTiersRaw.js.map +1 -0
  42. package/dist/Projects/types/events.d.ts +5 -1
  43. package/dist/Projects/types/index.d.ts +219 -42
  44. package/dist/Projects/types/index.js +8 -0
  45. package/dist/Projects/types/index.js.map +1 -1
  46. package/dist/Projects/utils/index.d.ts +20 -0
  47. package/dist/Projects/utils/index.js +91 -0
  48. package/dist/Projects/utils/index.js.map +1 -0
  49. package/dist/Projects/utils/samplers.d.ts +6 -0
  50. package/dist/Projects/utils/samplers.js +39 -0
  51. package/dist/Projects/utils/samplers.js.map +1 -0
  52. package/dist/Projects/utils/scheduler.d.ts +6 -0
  53. package/dist/Projects/utils/scheduler.js +30 -0
  54. package/dist/Projects/utils/scheduler.js.map +1 -0
  55. package/dist/index.d.ts +11 -3
  56. package/dist/index.js +8 -3
  57. package/dist/index.js.map +1 -1
  58. package/dist/lib/AuthManager/TokenAuthManager.js +0 -2
  59. package/dist/lib/AuthManager/TokenAuthManager.js.map +1 -1
  60. package/dist/lib/DataEntity.js +4 -2
  61. package/dist/lib/DataEntity.js.map +1 -1
  62. package/dist/lib/RestClient.js +15 -2
  63. package/dist/lib/RestClient.js.map +1 -1
  64. package/dist/lib/{utils.js → utils/index.js} +1 -1
  65. package/dist/lib/utils/index.js.map +1 -0
  66. package/dist/lib/validation.d.ts +31 -2
  67. package/dist/lib/validation.js +80 -13
  68. package/dist/lib/validation.js.map +1 -1
  69. package/package.json +4 -4
  70. package/src/Account/index.ts +39 -20
  71. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.ts +426 -0
  72. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +237 -0
  73. package/src/ApiClient/WebSocketClient/events.ts +14 -0
  74. package/src/ApiClient/WebSocketClient/index.ts +15 -5
  75. package/src/ApiClient/WebSocketClient/types.ts +16 -0
  76. package/src/ApiClient/index.ts +30 -8
  77. package/src/Projects/Job.ts +97 -16
  78. package/src/Projects/Project.ts +46 -13
  79. package/src/Projects/createJobRequestMessage.ts +239 -34
  80. package/src/Projects/index.ts +533 -51
  81. package/src/Projects/types/ComfySamplerParams.ts +0 -0
  82. package/src/Projects/types/EstimationResponse.ts +2 -0
  83. package/src/Projects/types/ModelOptions.ts +92 -0
  84. package/src/Projects/types/ModelTiersRaw.ts +86 -0
  85. package/src/Projects/types/events.ts +6 -0
  86. package/src/Projects/types/index.ts +253 -45
  87. package/src/Projects/utils/index.ts +90 -0
  88. package/src/Projects/utils/samplers.ts +36 -0
  89. package/src/Projects/utils/scheduler.ts +27 -0
  90. package/src/index.ts +36 -9
  91. package/src/lib/AuthManager/TokenAuthManager.ts +0 -2
  92. package/src/lib/DataEntity.ts +4 -2
  93. package/src/lib/RestClient.ts +16 -2
  94. package/src/lib/validation.ts +90 -17
  95. package/dist/Projects/types/SamplerParams.d.ts +0 -15
  96. package/dist/Projects/types/SamplerParams.js +0 -21
  97. package/dist/Projects/types/SamplerParams.js.map +0 -1
  98. package/dist/Projects/types/SchedulerParams.d.ts +0 -13
  99. package/dist/Projects/types/SchedulerParams.js +0 -19
  100. package/dist/Projects/types/SchedulerParams.js.map +0 -1
  101. package/dist/Projects/utils.d.ts +0 -2
  102. package/dist/Projects/utils.js +0 -14
  103. package/dist/Projects/utils.js.map +0 -1
  104. package/dist/lib/utils.js.map +0 -1
  105. package/src/Projects/types/SamplerParams.ts +0 -19
  106. package/src/Projects/types/SchedulerParams.ts +0 -17
  107. package/src/Projects/utils.ts +0 -12
  108. /package/dist/lib/{utils.d.ts → utils/index.d.ts} +0 -0
  109. /package/src/lib/{utils.ts → utils/index.ts} +0 -0
File without changes
@@ -14,6 +14,8 @@ export interface Job {
14
14
  costInRenderSec: string;
15
15
  costInUSD: string;
16
16
  costInToken: string;
17
+ costInSpark: string;
18
+ costInSogni: string;
17
19
  calculatedStepCount?: number;
18
20
  }
19
21
 
@@ -0,0 +1,92 @@
1
+ import { ComfyImageTier, ImageTier, NumericDefaults, VideoTier } from './ModelTiersRaw';
2
+ import { samplerValueToAlias } from '../utils/samplers';
3
+ import { schedulerValueToAlias } from '../utils/scheduler';
4
+
5
+ interface NumRange {
6
+ min: number;
7
+ max: number;
8
+ step: number;
9
+ default: number;
10
+ }
11
+
12
+ interface Options<T> {
13
+ allowed: T[];
14
+ default: T | null;
15
+ }
16
+
17
+ interface NumOptions {
18
+ options: number[];
19
+ default: number;
20
+ }
21
+
22
+ export interface ImageModelOptions {
23
+ type: 'image';
24
+ steps: NumRange;
25
+ guidance: NumRange;
26
+ scheduler: Options<string>;
27
+ sampler: Options<string>;
28
+ }
29
+
30
+ export interface VideoModelOptions {
31
+ type: 'video';
32
+ steps: NumRange;
33
+ guidance: NumRange;
34
+ fps: Options<number>;
35
+ sampler: Options<string>;
36
+ scheduler: Options<string>;
37
+ }
38
+
39
+ export type ModelOptions = ImageModelOptions | VideoModelOptions;
40
+
41
+ function mapRange(data: NumericDefaults): NumRange {
42
+ return {
43
+ min: data.min,
44
+ max: data.max,
45
+ step: data.decimals ? Math.pow(10, 0 - data.decimals) : data.step || 1,
46
+ default: data.default
47
+ };
48
+ }
49
+
50
+ function mapOptions<T>(data: Options<T> | undefined, mapper = (value: T) => value): Options<T> {
51
+ if (!data) {
52
+ return {
53
+ allowed: [],
54
+ default: null
55
+ };
56
+ }
57
+ return {
58
+ allowed: data.allowed.map(mapper),
59
+ default: data.default !== null ? mapper(data.default) : null
60
+ };
61
+ }
62
+
63
+ export function mapImageTier(tier: ImageTier): ImageModelOptions {
64
+ return {
65
+ type: 'image',
66
+ steps: mapRange(tier.steps),
67
+ guidance: mapRange(tier.guidance),
68
+ scheduler: mapOptions(tier.scheduler, schedulerValueToAlias),
69
+ sampler: mapOptions(tier.sampler, samplerValueToAlias)
70
+ };
71
+ }
72
+
73
+ export function mapComfyImageTier(tier: ComfyImageTier): ImageModelOptions {
74
+ return {
75
+ type: 'image',
76
+ steps: mapRange(tier.steps),
77
+ guidance: mapRange(tier.guidance),
78
+ scheduler: mapOptions(tier.comfyScheduler, schedulerValueToAlias),
79
+ sampler: mapOptions(tier.comfySampler, samplerValueToAlias)
80
+ };
81
+ }
82
+
83
+ export function mapVideoTier(tier: VideoTier): VideoModelOptions {
84
+ return {
85
+ type: 'video',
86
+ steps: mapRange(tier.steps),
87
+ guidance: mapRange(tier.guidance),
88
+ scheduler: mapOptions(tier.comfyScheduler, schedulerValueToAlias),
89
+ sampler: mapOptions(tier.comfySampler, samplerValueToAlias),
90
+ fps: tier.fps
91
+ };
92
+ }
@@ -0,0 +1,86 @@
1
+ export type ModelTiersRaw = Record<string, ModelTier>;
2
+
3
+ export type ModelTier = ImageTier | VideoTier | ComfyImageTier;
4
+
5
+ export interface ComfyImageTier {
6
+ benchmark: Benchmark;
7
+ comfySampler: StringDefaults;
8
+ comfyScheduler?: StringDefaults;
9
+ defaultSize: number;
10
+ guidance: NumericDefaults;
11
+ steps: NumericDefaults;
12
+ type: 'image';
13
+ }
14
+
15
+ export function isComfyImageTier(t: ModelTier): t is ComfyImageTier {
16
+ return 'type' in t && t.type === 'image';
17
+ }
18
+
19
+ export interface StringDefaults {
20
+ allowed: string[];
21
+ default: string;
22
+ }
23
+
24
+ export interface NumericDefaults {
25
+ min: number;
26
+ max: number;
27
+ decimals?: number;
28
+ default: number;
29
+ step?: number;
30
+ }
31
+
32
+ export interface ImageTier {
33
+ benchmark: Benchmark;
34
+ guidance: NumericDefaults;
35
+ modelFeeUSD?: number;
36
+ nickname?: string;
37
+ scheduler: StringDefaults;
38
+ steps: NumericDefaults;
39
+ sampler: StringDefaults;
40
+ }
41
+
42
+ export function isImageTier(t: ModelTier): t is ImageTier {
43
+ return !Object.prototype.hasOwnProperty.call(t, 'type');
44
+ }
45
+
46
+ export interface Benchmark {
47
+ sec: number;
48
+ secContext1?: number;
49
+ secContext2?: number;
50
+ secContext3?: number;
51
+ secCN: number;
52
+ secMaxPreviews: number;
53
+ }
54
+
55
+ export interface VideoTier {
56
+ audioDuration?: DurationDefaults;
57
+ audioStart?: DurationDefaults;
58
+ benchmark: Benchmark;
59
+ comfySampler: StringDefaults;
60
+ comfyScheduler: StringDefaults;
61
+ fps: NumericOptions;
62
+ frames: NumericDefaults;
63
+ guidance: NumericDefaults;
64
+ height: NumericDefaults;
65
+ shift: NumericDefaults;
66
+ steps: NumericDefaults;
67
+ type: 'video';
68
+ videoStart?: DurationDefaults;
69
+ width: NumericDefaults;
70
+ }
71
+
72
+ export function isVideoTier(t: ModelTier): t is VideoTier {
73
+ return 'type' in t && t.type === 'video';
74
+ }
75
+
76
+ export interface DurationDefaults {
77
+ min: number;
78
+ default: number;
79
+ }
80
+
81
+ export interface NumericOptions {
82
+ allowed: number[];
83
+ default: number;
84
+ }
85
+
86
+ export default ModelTiersRaw;
@@ -48,6 +48,11 @@ export interface JobProgress extends JobEventBase {
48
48
  stepCount: number;
49
49
  }
50
50
 
51
+ export interface JobETA extends JobEventBase {
52
+ type: 'jobETA';
53
+ etaSeconds: number;
54
+ }
55
+
51
56
  export interface JobPreview extends JobEventBase {
52
57
  type: 'preview';
53
58
  url: string;
@@ -75,6 +80,7 @@ export type JobEvent =
75
80
  | JobInitiating
76
81
  | JobStarted
77
82
  | JobProgress
83
+ | JobETA
78
84
  | JobPreview
79
85
  | JobCompleted
80
86
  | JobError;
@@ -1,19 +1,26 @@
1
1
  import { SupernetType } from '../../ApiClient/WebSocketClient/types';
2
2
  import { ControlNetParams } from './ControlNetParams';
3
3
  import { TokenType } from '../../types/token';
4
- import { Sampler } from './SamplerParams';
5
- import { Scheduler } from './SchedulerParams';
6
4
 
7
5
  export interface SupportedModel {
8
6
  id: string;
9
7
  name: string;
10
8
  SID: number;
9
+ tier: string;
10
+ /**
11
+ * Media type produced by this model: 'image' or 'video'
12
+ */
13
+ media: 'image' | 'video';
11
14
  }
12
15
 
13
16
  export interface AvailableModel {
14
17
  id: string;
15
18
  name: string;
16
19
  workerCount: number;
20
+ /**
21
+ * Media type produced by this model: 'image' or 'video'
22
+ */
23
+ media: 'image' | 'video';
17
24
  }
18
25
 
19
26
  export interface SizePreset {
@@ -25,17 +32,18 @@ export interface SizePreset {
25
32
  aspect: string;
26
33
  }
27
34
 
28
- export type { Sampler, Scheduler };
35
+ export type ImageOutputFormat = 'png' | 'jpg';
36
+ export type VideoOutputFormat = 'mp4';
29
37
 
30
- export type OutputFormat = 'png' | 'jpg';
31
-
32
- export type InputImage = File | Buffer | Blob | boolean;
33
-
34
- export interface ProjectParams {
38
+ export interface BaseProjectParams {
35
39
  /**
36
40
  * ID of the model to use, available models are available in the `availableModels` property of the `ProjectsApi` instance.
37
41
  */
38
42
  modelId: string;
43
+ /**
44
+ * Number of media files to generate. Depending on project type, this can be number of images or number of videos.
45
+ */
46
+ numberOfMedia: number;
39
47
  /**
40
48
  * Prompt for what to be created
41
49
  */
@@ -49,15 +57,17 @@ export interface ProjectParams {
49
57
  */
50
58
  stylePrompt: string;
51
59
  /**
52
- * Number of steps. For most Stable Diffusion models, optimal value is 20
60
+ * Number of steps. For most Stable Diffusion models, optimal value is 20.
53
61
  */
54
- steps: number;
62
+ steps?: number;
55
63
  /**
56
- * Guidance scale. For most Stable Diffusion models, optimal value is 7.5
64
+ * Guidance scale. For most Stable Diffusion models, optimal value is 7.5.
65
+ * For video models: Regular models range 0.7-8.0, LoRA version (lightx2v) range 0.7-1.6, step 0.01.
66
+ * This maps to `guidanceScale` in the keyFrame for both image and video models.
57
67
  */
58
- guidance: number;
68
+ guidance?: number;
59
69
  /**
60
- * Override current network type. Default value can be read from `client.account.currentAccount.network`
70
+ * Override current network type. Default value can be read from `sogni.account.currentAccount.network`
61
71
  */
62
72
  network?: SupernetType;
63
73
  /**
@@ -70,46 +80,164 @@ export interface ProjectParams {
70
80
  */
71
81
  seed?: number;
72
82
  /**
73
- * Number of images to generate
83
+ * Select which tokens to use for the project.
84
+ * If not specified, the Sogni token will be used.
74
85
  */
75
- numberOfImages: number;
86
+ tokenType?: TokenType;
76
87
  /**
77
- * Generate images based on the starting image.
78
- * Supported types:
79
- * `File` - file object from input[type=file]
80
- * `Buffer` - Node.js buffer object with image data
81
- * `Blob` - blob object with image data
82
- * `true` - indicates that the image is already uploaded to the server
88
+ * LoRA ID to use for generation.
89
+ * Available LoRAs are model-specific. The worker will download the LoRA
90
+ * if not already present on the persistent volume.
83
91
  */
84
- startingImage?: InputImage;
92
+ loraId?: string;
85
93
  /**
86
- * How strong effect of starting image should be. From 0 to 1, default 0.5
94
+ * Array of LoRA filenames to apply (for Qwen Image Edit workflows).
95
+ * Filenames should end with .safetensors.
96
+ * Example: ['qwen-image-edit-2511-multiple-angles-lora.safetensors']
87
97
  */
88
- startingImageStrength?: number;
98
+ loras?: string[];
99
+ /**
100
+ * Array of LoRA strengths corresponding to each LoRA in the loras array.
101
+ * Values should be between 0.0 and 2.0. Defaults to 1.0 if not specified.
102
+ * Example: [0.9]
103
+ */
104
+ loraStrengths?: number[];
105
+ }
106
+
107
+ export type InputMedia = File | Buffer | Blob | boolean;
108
+
109
+ /**
110
+ * Video-specific parameters for video workflows (t2v, i2v, s2v, animate).
111
+ * Only applicable when using video models like wan_v2.2-14b-fp8_t2v.
112
+ * Includes frame count, fps, shift, and reference assets (image, audio, video).
113
+ */
114
+ export interface VideoProjectParams extends BaseProjectParams {
115
+ type: 'video';
116
+ /**
117
+ * Number of frames to generate
118
+ * @deprecated Use duration instead
119
+ */
120
+ frames?: number;
121
+ /**
122
+ * Duration of the video in seconds. Supported range 1 to 10
123
+ */
124
+ duration?: number;
125
+ /**
126
+ * Frames per second for output video
127
+ */
128
+ fps?: number;
129
+ /**
130
+ * Shift parameter for video diffusion models.
131
+ * Controls motion intensity. Range: 1.0-8.0, step 0.1.
132
+ * Default: 8.0 for regular models, 5.0 for speed lora (lightx2v) except s2v and animate which use 8.0
133
+ */
134
+ shift?: number;
135
+ /**
136
+ * TeaCache optimization threshold for T2V and I2V models.
137
+ * Range: 0.0-1.0. 0.0 = disabled.
138
+ * Recommended: 0.15 for T2V (~1.5x speedup), 0.2 for I2V (conservative quality-focused)
139
+ */
140
+ teacacheThreshold?: number;
141
+ /**
142
+ * Reference image for WAN video workflows.
143
+ * Maps to: startImage (i2v), characterImage (animate), referenceImage (s2v)
144
+ */
145
+ referenceImage?: InputMedia;
146
+ /**
147
+ * Optional end image for i2v interpolation workflows.
148
+ * When provided with referenceImage, the video will interpolate between the two images.
149
+ */
150
+ referenceImageEnd?: InputMedia;
151
+ /**
152
+ * Reference audio for s2v (sound-to-video) workflows.
153
+ */
154
+ referenceAudio?: InputMedia;
155
+ /**
156
+ * Audio start position in seconds for s2v workflows.
157
+ * Specifies where to begin reading from the audio file.
158
+ * Default: 0
159
+ */
160
+ audioStart?: number;
161
+ /**
162
+ * Audio duration in seconds for s2v workflows.
163
+ * Specifies how many seconds of audio to use.
164
+ * If not provided, defaults to 30 seconds on the server.
165
+ */
166
+ audioDuration?: number;
167
+ /**
168
+ * Reference video for animate workflows.
169
+ * Maps to: drivingVideo (animate-move), sourceVideo (animate-replace)
170
+ */
171
+ referenceVideo?: InputMedia;
172
+ /**
173
+ * Video start position in seconds for animate workflows (animate-move, animate-replace).
174
+ * Specifies where to begin reading from the reference video file.
175
+ * Default: 0
176
+ */
177
+ videoStart?: number;
89
178
  /**
90
- * Context images for Flux Kontext model. Flux Kontext support up to 2 context images.
179
+ * Output video width. Only used if `sizePreset` is "custom"
180
+ */
181
+ width?: number;
182
+ /**
183
+ * Output video height. Only used if `sizePreset` is "custom"
184
+ */
185
+ height?: number;
186
+ /**
187
+ * Sampler, available options depend on the model. Use `sogni.projects.getModelOptions(modelId)`
188
+ * to get the list of available samplers.
189
+ */
190
+ sampler?: string;
191
+ /**
192
+ * Scheduler, available options depend on the model. Use `sogni.projects.getModelOptions(modelId)`
193
+ * to get the list of available schedulers.
194
+ */
195
+ scheduler?: string;
196
+ /**
197
+ * Output video format. For now only 'mp4' is supported, defaults to 'mp4'.
198
+ */
199
+ outputFormat?: VideoOutputFormat;
200
+ }
201
+
202
+ export interface ImageProjectParams extends BaseProjectParams {
203
+ type: 'image';
204
+ /**
205
+ * Number of previews to generate. Note that previews affect project cost
206
+ */
207
+ numberOfPreviews?: number;
208
+ /**
209
+ * Starting image for img2img workflows.
91
210
  * Supported types:
92
211
  * `File` - file object from input[type=file]
93
212
  * `Buffer` - Node.js buffer object with image data
94
213
  * `Blob` - blob object with image data
95
214
  * `true` - indicates that the image is already uploaded to the server
96
215
  */
97
- contextImages?: InputImage[];
216
+ startingImage?: InputMedia;
98
217
  /**
99
- * Number of previews to generate. Note that previews affect project cost\
218
+ * How strong effect of starting image should be. From 0 to 1, default 0.5
100
219
  */
101
- numberOfPreviews?: number;
220
+ startingImageStrength?: number;
221
+ /**
222
+ * Context images for multi-reference image generation.
223
+ * Flux.2 Dev supports up to 6 context images.
224
+ * Qwen Image Edit Plus supports up to 3 context images.
225
+ * Flux Kontext supports up to 2 context images.
226
+ */
227
+ contextImages?: InputMedia[];
102
228
  /**
103
- * Scheduler to use
229
+ * Sampler, available options depend on the model. Use `sogni.projects.getModelOptions(modelId)`
230
+ * to get the list of available samplers.
104
231
  */
105
- sampler?: Sampler;
232
+ sampler?: string;
106
233
  /**
107
- * Time step spacing method
234
+ * Scheduler, available options depend on the model. Use `sogni.projects.getModelOptions(modelId)`
235
+ * to get the list of available schedulers.
108
236
  */
109
- scheduler?: Scheduler;
237
+ scheduler?: string;
110
238
  /**
111
239
  * Size preset ID to use. You can query available size presets
112
- * from `client.projects.sizePresets(network, modelId)`
240
+ * from `sogni.projects.sizePresets(network, modelId)`
113
241
  */
114
242
  sizePreset?: 'custom' | string;
115
243
  /**
@@ -125,25 +253,62 @@ export interface ProjectParams {
125
253
  */
126
254
  controlNet?: ControlNetParams;
127
255
  /**
128
- * Select which tokens to use for the project.
129
- * If not specified, the Sogni token will be used.
130
- */
131
- tokenType?: TokenType;
132
- /**
133
- * Output image format. Can be 'png' or 'jpg'.
134
- * If not specified, 'png' will be used.
256
+ * Output format. Can be 'png' or 'jpg'. Defaults to 'png'.
135
257
  */
136
- outputFormat?: OutputFormat;
258
+ outputFormat?: ImageOutputFormat;
259
+ }
260
+
261
+ export type ProjectParams = ImageProjectParams | VideoProjectParams;
262
+
263
+ export function isVideoParams(params: ProjectParams): params is VideoProjectParams {
264
+ return params.type === 'video';
265
+ }
266
+
267
+ export function isImageParams(params: ProjectParams): params is ImageProjectParams {
268
+ return params.type === 'image';
137
269
  }
138
270
 
271
+ /**
272
+ * Supported audio formats
273
+ */
274
+ export type AudioFormat = 'm4a' | 'mp3' | 'wav';
275
+
276
+ /**
277
+ * Supported video formats
278
+ */
279
+ export type VideoFormat = 'mp4' | 'mov';
280
+
281
+ /**
282
+ * Parameters for image asset URL requests (upload/download)
283
+ */
139
284
  export type ImageUrlParams = {
140
285
  imageId: string;
141
286
  jobId: string;
142
- type: 'preview' | 'complete' | 'startingImage' | 'cnImage' | 'contextImage1' | 'contextImage2';
143
- // This seems to be unused currently
287
+ type:
288
+ | 'preview'
289
+ | 'complete'
290
+ | 'startingImage'
291
+ | 'cnImage'
292
+ | 'contextImage1'
293
+ | 'contextImage2'
294
+ | 'contextImage3'
295
+ | 'contextImage4'
296
+ | 'contextImage5'
297
+ | 'contextImage6'
298
+ | 'referenceImage'
299
+ | 'referenceImageEnd';
144
300
  startContentType?: string;
145
301
  };
146
302
 
303
+ /**
304
+ * Parameters for media asset URL requests (video/audio upload/download)
305
+ */
306
+ export type MediaUrlParams = {
307
+ id?: string;
308
+ jobId: string;
309
+ type: 'complete' | 'preview' | 'referenceAudio' | 'referenceVideo';
310
+ };
311
+
147
312
  export interface EstimateRequest {
148
313
  /**
149
314
  * Network to use. Can be 'fast' or 'relaxed'
@@ -196,9 +361,9 @@ export interface EstimateRequest {
196
361
  */
197
362
  guidance?: number;
198
363
  /**
199
- * Scheduler
364
+ * Sampler
200
365
  */
201
- scheduler?: Sampler;
366
+ sampler?: string;
202
367
  /**
203
368
  * Number of context images to use (for Flux Kontext).
204
369
  * Note that this parameter is ignored if `scheduler` is not provided
@@ -206,4 +371,47 @@ export interface EstimateRequest {
206
371
  contextImages?: number;
207
372
  }
208
373
 
374
+ export interface VideoEstimateRequest {
375
+ tokenType: TokenType;
376
+ model: string;
377
+ width: number;
378
+ height: number;
379
+ duration: number;
380
+ /**
381
+ * Number of frames to generate.
382
+ * @deprecated Use duration instead
383
+ */
384
+ frames?: number;
385
+ fps: number;
386
+ steps: number;
387
+ numberOfMedia: number;
388
+ }
389
+
390
+ /**
391
+ * Represents estimation of project cost in different currency formats
392
+ */
393
+ export interface CostEstimation {
394
+ /** Cost in selected token type */
395
+ token: string;
396
+ /** Cost in USD */
397
+ usd: string;
398
+ /** Cost in Spark Points */
399
+ spark: string;
400
+ /** Cost in Sogni tokens */
401
+ sogni: string;
402
+ }
403
+
209
404
  export type EnhancementStrength = 'light' | 'medium' | 'heavy';
405
+
406
+ /**
407
+ * Video workflow types for WAN models
408
+ */
409
+ export type VideoWorkflowType = 't2v' | 'i2v' | 's2v' | 'animate-move' | 'animate-replace' | null;
410
+
411
+ export type AssetRequirement = 'required' | 'optional' | 'forbidden';
412
+
413
+ export type VideoAssetKey =
414
+ | 'referenceImage'
415
+ | 'referenceImageEnd'
416
+ | 'referenceAudio'
417
+ | 'referenceVideo';
@@ -0,0 +1,90 @@
1
+ import { AssetRequirement, EnhancementStrength, VideoAssetKey, VideoWorkflowType } from '../types';
2
+
3
+ export function getEnhacementStrength(strength: EnhancementStrength): number {
4
+ switch (strength) {
5
+ case 'light':
6
+ return 0.15;
7
+ case 'heavy':
8
+ return 0.49;
9
+ default:
10
+ return 0.35;
11
+ }
12
+ }
13
+
14
+ /**
15
+ * Check if a model ID is for a video workflow.
16
+ * This is consistent with the `media` property returned by the models list API.
17
+ * Video models produce MP4 output; image models produce PNG/JPG output.
18
+ */
19
+ export function isVideoModel(modelId: string): boolean {
20
+ return modelId.startsWith('wan_') || modelId.startsWith('ltx2-');
21
+ }
22
+
23
+ /**
24
+ * Get the video workflow type from a model ID.
25
+ * Returns null for non-video models.
26
+ */
27
+ export function getVideoWorkflowType(modelId: string): VideoWorkflowType {
28
+ if (!modelId) return null;
29
+
30
+ // Check for supported video model prefixes
31
+ const isWan = modelId.startsWith('wan_');
32
+ const isLtx2 = modelId.startsWith('ltx2-');
33
+
34
+ if (!isWan && !isLtx2) return null;
35
+
36
+ // WAN and LTX-2 models share similar workflow type suffixes
37
+ if (modelId.includes('_i2v')) return 'i2v';
38
+ if (modelId.includes('_t2v')) return 't2v';
39
+
40
+ // WAN-specific workflow types
41
+ if (isWan) {
42
+ if (modelId.includes('_s2v')) return 's2v';
43
+ if (modelId.includes('_animate-move')) return 'animate-move';
44
+ if (modelId.includes('_animate-replace')) return 'animate-replace';
45
+ }
46
+
47
+ return null;
48
+ }
49
+
50
+ /**
51
+ * Asset requirements for each video workflow type.
52
+ * - required: Must be provided
53
+ * - optional: Can be provided
54
+ * - forbidden: Must NOT be provided
55
+ */
56
+ export const VIDEO_WORKFLOW_ASSETS: Record<
57
+ NonNullable<VideoWorkflowType>,
58
+ Record<VideoAssetKey, AssetRequirement>
59
+ > = {
60
+ t2v: {
61
+ referenceImage: 'forbidden',
62
+ referenceImageEnd: 'forbidden',
63
+ referenceAudio: 'forbidden',
64
+ referenceVideo: 'forbidden'
65
+ },
66
+ i2v: {
67
+ referenceImage: 'optional',
68
+ referenceImageEnd: 'optional',
69
+ referenceAudio: 'forbidden',
70
+ referenceVideo: 'forbidden'
71
+ },
72
+ s2v: {
73
+ referenceImage: 'required',
74
+ referenceAudio: 'required',
75
+ referenceImageEnd: 'forbidden',
76
+ referenceVideo: 'forbidden'
77
+ },
78
+ 'animate-move': {
79
+ referenceImage: 'required',
80
+ referenceVideo: 'required',
81
+ referenceImageEnd: 'forbidden',
82
+ referenceAudio: 'forbidden'
83
+ },
84
+ 'animate-replace': {
85
+ referenceImage: 'required',
86
+ referenceVideo: 'required',
87
+ referenceImageEnd: 'forbidden',
88
+ referenceAudio: 'forbidden'
89
+ }
90
+ };