@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.
- package/CHANGELOG.md +357 -0
- package/README.md +295 -58
- package/dist/Account/index.d.ts +18 -16
- package/dist/Account/index.js +42 -21
- package/dist/Account/index.js.map +1 -1
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.d.ts +66 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.js +332 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.js.map +1 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +28 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +203 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -0
- package/dist/ApiClient/WebSocketClient/events.d.ts +12 -0
- package/dist/ApiClient/WebSocketClient/index.d.ts +2 -2
- package/dist/ApiClient/WebSocketClient/index.js +13 -3
- package/dist/ApiClient/WebSocketClient/index.js.map +1 -1
- package/dist/ApiClient/WebSocketClient/types.d.ts +13 -0
- package/dist/ApiClient/index.d.ts +4 -4
- package/dist/ApiClient/index.js +23 -4
- package/dist/ApiClient/index.js.map +1 -1
- package/dist/Projects/Job.d.ts +44 -4
- package/dist/Projects/Job.js +83 -16
- package/dist/Projects/Job.js.map +1 -1
- package/dist/Projects/Project.d.ts +18 -0
- package/dist/Projects/Project.js +38 -10
- package/dist/Projects/Project.js.map +1 -1
- package/dist/Projects/createJobRequestMessage.d.ts +2 -1
- package/dist/Projects/createJobRequestMessage.js +173 -14
- package/dist/Projects/createJobRequestMessage.js.map +1 -1
- package/dist/Projects/index.d.ts +114 -11
- package/dist/Projects/index.js +504 -47
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/types/ComfySamplerParams.d.ts +0 -0
- package/dist/Projects/types/ComfySamplerParams.js +2 -0
- package/dist/Projects/types/ComfySamplerParams.js.map +1 -0
- package/dist/Projects/types/EstimationResponse.d.ts +2 -0
- package/dist/Projects/types/ModelOptions.d.ts +31 -0
- package/dist/Projects/types/ModelOptions.js +56 -0
- package/dist/Projects/types/ModelOptions.js.map +1 -0
- package/dist/Projects/types/ModelTiersRaw.d.ts +67 -0
- package/dist/Projects/types/ModelTiersRaw.js +15 -0
- package/dist/Projects/types/ModelTiersRaw.js.map +1 -0
- package/dist/Projects/types/events.d.ts +5 -1
- package/dist/Projects/types/index.d.ts +219 -42
- package/dist/Projects/types/index.js +8 -0
- package/dist/Projects/types/index.js.map +1 -1
- package/dist/Projects/utils/index.d.ts +20 -0
- package/dist/Projects/utils/index.js +91 -0
- package/dist/Projects/utils/index.js.map +1 -0
- package/dist/Projects/utils/samplers.d.ts +6 -0
- package/dist/Projects/utils/samplers.js +39 -0
- package/dist/Projects/utils/samplers.js.map +1 -0
- package/dist/Projects/utils/scheduler.d.ts +6 -0
- package/dist/Projects/utils/scheduler.js +30 -0
- package/dist/Projects/utils/scheduler.js.map +1 -0
- package/dist/index.d.ts +11 -3
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/AuthManager/TokenAuthManager.js +0 -2
- package/dist/lib/AuthManager/TokenAuthManager.js.map +1 -1
- package/dist/lib/DataEntity.js +4 -2
- package/dist/lib/DataEntity.js.map +1 -1
- package/dist/lib/RestClient.js +15 -2
- package/dist/lib/RestClient.js.map +1 -1
- package/dist/lib/{utils.js → utils/index.js} +1 -1
- package/dist/lib/utils/index.js.map +1 -0
- package/dist/lib/validation.d.ts +31 -2
- package/dist/lib/validation.js +80 -13
- package/dist/lib/validation.js.map +1 -1
- package/package.json +4 -4
- package/src/Account/index.ts +39 -20
- package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.ts +426 -0
- package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +237 -0
- package/src/ApiClient/WebSocketClient/events.ts +14 -0
- package/src/ApiClient/WebSocketClient/index.ts +15 -5
- package/src/ApiClient/WebSocketClient/types.ts +16 -0
- package/src/ApiClient/index.ts +30 -8
- package/src/Projects/Job.ts +97 -16
- package/src/Projects/Project.ts +46 -13
- package/src/Projects/createJobRequestMessage.ts +239 -34
- package/src/Projects/index.ts +533 -51
- package/src/Projects/types/ComfySamplerParams.ts +0 -0
- package/src/Projects/types/EstimationResponse.ts +2 -0
- package/src/Projects/types/ModelOptions.ts +92 -0
- package/src/Projects/types/ModelTiersRaw.ts +86 -0
- package/src/Projects/types/events.ts +6 -0
- package/src/Projects/types/index.ts +253 -45
- package/src/Projects/utils/index.ts +90 -0
- package/src/Projects/utils/samplers.ts +36 -0
- package/src/Projects/utils/scheduler.ts +27 -0
- package/src/index.ts +36 -9
- package/src/lib/AuthManager/TokenAuthManager.ts +0 -2
- package/src/lib/DataEntity.ts +4 -2
- package/src/lib/RestClient.ts +16 -2
- package/src/lib/validation.ts +90 -17
- package/dist/Projects/types/SamplerParams.d.ts +0 -15
- package/dist/Projects/types/SamplerParams.js +0 -21
- package/dist/Projects/types/SamplerParams.js.map +0 -1
- package/dist/Projects/types/SchedulerParams.d.ts +0 -13
- package/dist/Projects/types/SchedulerParams.js +0 -19
- package/dist/Projects/types/SchedulerParams.js.map +0 -1
- package/dist/Projects/utils.d.ts +0 -2
- package/dist/Projects/utils.js +0 -14
- package/dist/Projects/utils.js.map +0 -1
- package/dist/lib/utils.js.map +0 -1
- package/src/Projects/types/SamplerParams.ts +0 -19
- package/src/Projects/types/SchedulerParams.ts +0 -17
- package/src/Projects/utils.ts +0 -12
- /package/dist/lib/{utils.d.ts → utils/index.d.ts} +0 -0
- /package/src/lib/{utils.ts → utils/index.ts} +0 -0
|
@@ -1,11 +1,70 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ImageProjectParams,
|
|
3
|
+
isImageParams,
|
|
4
|
+
isVideoParams,
|
|
5
|
+
ProjectParams,
|
|
6
|
+
VideoProjectParams
|
|
7
|
+
} from './types';
|
|
2
8
|
import { ControlNetParams, ControlNetParamsRaw } from './types/ControlNetParams';
|
|
3
9
|
import {
|
|
4
10
|
validateNumber,
|
|
5
11
|
validateCustomImageSize,
|
|
12
|
+
validateVideoSize,
|
|
13
|
+
validateTeacacheThreshold,
|
|
14
|
+
isComfyModel,
|
|
15
|
+
validateVideoDuration,
|
|
6
16
|
validateSampler,
|
|
7
17
|
validateScheduler
|
|
8
18
|
} from '../lib/validation';
|
|
19
|
+
import { getVideoWorkflowType, isVideoModel, VIDEO_WORKFLOW_ASSETS } from './utils';
|
|
20
|
+
import { ApiError } from '../ApiClient';
|
|
21
|
+
import { ImageModelOptions, ModelOptions, VideoModelOptions } from './types/ModelOptions';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Validate that the provided assets match the workflow requirements.
|
|
25
|
+
* Throws an error if required assets are missing or forbidden assets are provided.
|
|
26
|
+
*/
|
|
27
|
+
function validateVideoWorkflowAssets(params: VideoProjectParams): void {
|
|
28
|
+
const workflowType = getVideoWorkflowType(params.modelId);
|
|
29
|
+
if (!workflowType) return;
|
|
30
|
+
|
|
31
|
+
const requirements = VIDEO_WORKFLOW_ASSETS[workflowType];
|
|
32
|
+
if (!requirements) return;
|
|
33
|
+
|
|
34
|
+
// Special case for i2v: at least ONE of referenceImage or referenceImageEnd required
|
|
35
|
+
if (workflowType === 'i2v') {
|
|
36
|
+
if (!params.referenceImage && !params.referenceImageEnd) {
|
|
37
|
+
throw new ApiError(400, {
|
|
38
|
+
status: 'error',
|
|
39
|
+
errorCode: 0,
|
|
40
|
+
message:
|
|
41
|
+
'i2v workflow requires at least one of referenceImage or referenceImageEnd. Please provide this asset.'
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check for missing required assets and forbidden assets
|
|
47
|
+
for (const [asset, requirement] of Object.entries(requirements)) {
|
|
48
|
+
const assetKey = asset as keyof VideoProjectParams;
|
|
49
|
+
const hasAsset = !!params[assetKey];
|
|
50
|
+
|
|
51
|
+
if (requirement === 'required' && !hasAsset) {
|
|
52
|
+
throw new ApiError(400, {
|
|
53
|
+
status: 'error',
|
|
54
|
+
errorCode: 0,
|
|
55
|
+
message: `${workflowType} workflow requires ${assetKey}. Please provide this asset.`
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (requirement === 'forbidden' && hasAsset) {
|
|
60
|
+
throw new ApiError(400, {
|
|
61
|
+
status: 'error',
|
|
62
|
+
errorCode: 0,
|
|
63
|
+
message: `${workflowType} workflow does not support ${assetKey}. Please remove this asset.`
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
9
68
|
|
|
10
69
|
// Mac worker can't process the data if some of the fields are missing, so we need to provide a default template
|
|
11
70
|
function getTemplate() {
|
|
@@ -118,49 +177,195 @@ function getControlNet(params: ControlNetParams): ControlNetParamsRaw[] {
|
|
|
118
177
|
return [cn];
|
|
119
178
|
}
|
|
120
179
|
|
|
121
|
-
function
|
|
180
|
+
function applyImageParams(
|
|
181
|
+
inputKeyframe: Record<string, any>,
|
|
182
|
+
params: ImageProjectParams,
|
|
183
|
+
options: ImageModelOptions
|
|
184
|
+
) {
|
|
185
|
+
const keyFrame: Record<string, any> = {
|
|
186
|
+
...inputKeyframe,
|
|
187
|
+
sizePreset: params.sizePreset,
|
|
188
|
+
hasContextImage1: !!params.contextImages?.[0],
|
|
189
|
+
hasContextImage2: !!params.contextImages?.[1],
|
|
190
|
+
hasContextImage3: !!params.contextImages?.[2],
|
|
191
|
+
hasContextImage4: !!params.contextImages?.[3],
|
|
192
|
+
hasContextImage5: !!params.contextImages?.[4],
|
|
193
|
+
hasContextImage6: !!params.contextImages?.[5]
|
|
194
|
+
};
|
|
195
|
+
// Sampler/scheduler handling: SDK validates and passes through as-is.
|
|
196
|
+
// sogni-socket normalizes values for both ComfyUI and Forge workers.
|
|
197
|
+
if (isComfyModel(params.modelId)) {
|
|
198
|
+
// ComfyUI models use comfySampler/comfyScheduler fields
|
|
199
|
+
keyFrame.comfySampler = validateSampler(params.sampler, options);
|
|
200
|
+
keyFrame.comfyScheduler = validateScheduler(params.scheduler, options);
|
|
201
|
+
} else {
|
|
202
|
+
// Legacy Forge models use scheduler/timeStepSpacing fields
|
|
203
|
+
keyFrame.scheduler = validateSampler(params.sampler, options);
|
|
204
|
+
keyFrame.timeStepSpacing = validateScheduler(params.scheduler, options);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (params.startingImage) {
|
|
208
|
+
keyFrame.hasStartingImage = true;
|
|
209
|
+
keyFrame.strengthIsEnabled = true;
|
|
210
|
+
keyFrame.strength = 1 - (Number(params.startingImageStrength) || 0.5);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (params.controlNet) {
|
|
214
|
+
keyFrame.currentControlNetsJob = getControlNet(params.controlNet);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Set sizePreset to 'custom' if width/height are provided but sizePreset is not set
|
|
218
|
+
let effectiveSizePreset = params.sizePreset;
|
|
219
|
+
if (params.width && params.height && !params.sizePreset) {
|
|
220
|
+
effectiveSizePreset = 'custom';
|
|
221
|
+
}
|
|
222
|
+
keyFrame.sizePreset = effectiveSizePreset;
|
|
223
|
+
|
|
224
|
+
if (effectiveSizePreset === 'custom' && params.width && params.height) {
|
|
225
|
+
keyFrame.width = validateCustomImageSize(params.width);
|
|
226
|
+
keyFrame.height = validateCustomImageSize(params.height);
|
|
227
|
+
}
|
|
228
|
+
return keyFrame;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function applyVideoParams(
|
|
232
|
+
inputKeyframe: Record<string, any>,
|
|
233
|
+
params: VideoProjectParams,
|
|
234
|
+
options: VideoModelOptions
|
|
235
|
+
) {
|
|
236
|
+
if (!isVideoModel(params.modelId)) {
|
|
237
|
+
throw new ApiError(400, {
|
|
238
|
+
status: 'error',
|
|
239
|
+
errorCode: 0,
|
|
240
|
+
message: 'Video generation is only supported for video models.'
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
validateVideoWorkflowAssets(params);
|
|
244
|
+
const keyFrame: Record<string, any> = { ...inputKeyframe };
|
|
245
|
+
if (params.referenceImage) {
|
|
246
|
+
keyFrame.hasReferenceImage = true;
|
|
247
|
+
}
|
|
248
|
+
if (params.referenceImageEnd) {
|
|
249
|
+
keyFrame.hasReferenceImageEnd = true;
|
|
250
|
+
}
|
|
251
|
+
if (params.referenceAudio) {
|
|
252
|
+
keyFrame.hasReferenceAudio = true;
|
|
253
|
+
}
|
|
254
|
+
if (params.referenceVideo) {
|
|
255
|
+
keyFrame.hasReferenceVideo = true;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Video generation parameters
|
|
259
|
+
if (params.frames !== undefined) {
|
|
260
|
+
keyFrame.frames = params.frames;
|
|
261
|
+
}
|
|
262
|
+
if (params.duration !== undefined) {
|
|
263
|
+
const duration = validateVideoDuration(params.duration);
|
|
264
|
+
keyFrame.frames = duration * 16 + 1;
|
|
265
|
+
}
|
|
266
|
+
if (params.fps !== undefined) {
|
|
267
|
+
keyFrame.fps = params.fps;
|
|
268
|
+
}
|
|
269
|
+
if (params.shift !== undefined) {
|
|
270
|
+
keyFrame.shift = params.shift;
|
|
271
|
+
}
|
|
272
|
+
if (params.teacacheThreshold !== undefined) {
|
|
273
|
+
const validatedThreshold = validateTeacacheThreshold(params.teacacheThreshold);
|
|
274
|
+
if (validatedThreshold !== undefined) {
|
|
275
|
+
keyFrame.teacacheThreshold = validatedThreshold;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// S2V audio parameters
|
|
280
|
+
if (params.audioStart !== undefined) {
|
|
281
|
+
keyFrame.audioStart = params.audioStart;
|
|
282
|
+
}
|
|
283
|
+
if (params.audioDuration !== undefined) {
|
|
284
|
+
keyFrame.audioDuration = params.audioDuration;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Animate video parameters (for animate-move, animate-replace)
|
|
288
|
+
if (params.videoStart !== undefined) {
|
|
289
|
+
keyFrame.videoStart = params.videoStart;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Validate and set video dimensions (minimum 480px for Wan 2.2 models)
|
|
293
|
+
if (params.width && params.height) {
|
|
294
|
+
keyFrame.width = validateVideoSize(params.width, 'width');
|
|
295
|
+
keyFrame.height = validateVideoSize(params.height, 'height');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
keyFrame.comfySampler = validateSampler(params.sampler, options);
|
|
299
|
+
keyFrame.comfyScheduler = validateScheduler(params.scheduler, options);
|
|
300
|
+
|
|
301
|
+
return keyFrame;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function createJobRequestMessage(id: string, params: ProjectParams, options: ModelOptions) {
|
|
122
305
|
const template = getTemplate();
|
|
306
|
+
// Base keyFrame with common params
|
|
307
|
+
let keyFrame: Record<string, any> = {
|
|
308
|
+
...template.keyFrames[0],
|
|
309
|
+
steps: params.steps,
|
|
310
|
+
guidanceScale: params.guidance,
|
|
311
|
+
modelID: params.modelId,
|
|
312
|
+
negativePrompt: params.negativePrompt,
|
|
313
|
+
seed: params.seed,
|
|
314
|
+
positivePrompt: params.positivePrompt,
|
|
315
|
+
stylePrompt: params.stylePrompt,
|
|
316
|
+
// LoRA ID for runtime LoRA loading (optional, model-specific)
|
|
317
|
+
...(params.loraId && { loraId: params.loraId }),
|
|
318
|
+
// LoRA arrays for direct LoRA injection (Qwen Image Edit workflows)
|
|
319
|
+
...(params.loras && params.loras.length > 0 && { loras: params.loras }),
|
|
320
|
+
...(params.loraStrengths && params.loraStrengths.length > 0 && { loraStrengths: params.loraStrengths })
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
switch (params.type) {
|
|
324
|
+
case 'image':
|
|
325
|
+
if (options.type !== 'image') {
|
|
326
|
+
throw new ApiError(400, {
|
|
327
|
+
status: 'error',
|
|
328
|
+
errorCode: 0,
|
|
329
|
+
message:
|
|
330
|
+
'Invalid model type. Model does not support image generation. Please use a different model.'
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
keyFrame = applyImageParams(keyFrame, params, options);
|
|
334
|
+
break;
|
|
335
|
+
case 'video':
|
|
336
|
+
if (options.type !== 'video') {
|
|
337
|
+
throw new ApiError(400, {
|
|
338
|
+
status: 'error',
|
|
339
|
+
errorCode: 0,
|
|
340
|
+
message:
|
|
341
|
+
'Invalid model type. Model does not support video generation. Please use a different model.'
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
keyFrame = applyVideoParams(keyFrame, params, options);
|
|
345
|
+
break;
|
|
346
|
+
default:
|
|
347
|
+
throw new ApiError(400, {
|
|
348
|
+
status: 'error',
|
|
349
|
+
errorCode: 0,
|
|
350
|
+
message: 'Invalid project type. Must be "image" or "video".'
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
123
354
|
const jobRequest: Record<string, any> = {
|
|
124
355
|
...template,
|
|
125
|
-
keyFrames: [
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
scheduler: validateSampler(params.sampler),
|
|
129
|
-
timeStepSpacing: validateScheduler(params.scheduler),
|
|
130
|
-
steps: params.steps,
|
|
131
|
-
guidanceScale: params.guidance,
|
|
132
|
-
modelID: params.modelId,
|
|
133
|
-
negativePrompt: params.negativePrompt,
|
|
134
|
-
seed: params.seed,
|
|
135
|
-
positivePrompt: params.positivePrompt,
|
|
136
|
-
stylePrompt: params.stylePrompt,
|
|
137
|
-
hasStartingImage: !!params.startingImage,
|
|
138
|
-
hasContextImage1: !!params.contextImages?.[0],
|
|
139
|
-
hasContextImage2: !!params.contextImages?.[1],
|
|
140
|
-
strengthIsEnabled: !!params.startingImage,
|
|
141
|
-
strength: !!params.startingImage
|
|
142
|
-
? 1 - (Number(params.startingImageStrength) || 0.5)
|
|
143
|
-
: undefined,
|
|
144
|
-
sizePreset: params.sizePreset
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
previews: params.numberOfPreviews || 0,
|
|
148
|
-
numberOfImages: params.numberOfImages,
|
|
356
|
+
keyFrames: [keyFrame],
|
|
357
|
+
previews: isImageParams(params) ? params.numberOfPreviews || 0 : 0,
|
|
358
|
+
numberOfImages: params.numberOfMedia || 1,
|
|
149
359
|
jobID: id,
|
|
150
360
|
disableSafety: !!params.disableNSFWFilter,
|
|
151
361
|
tokenType: params.tokenType,
|
|
152
|
-
outputFormat: params.outputFormat || 'png'
|
|
362
|
+
outputFormat: params.outputFormat || (isVideoParams(params) ? 'mp4' : 'png')
|
|
153
363
|
};
|
|
364
|
+
|
|
154
365
|
if (params.network) {
|
|
155
366
|
jobRequest.network = params.network;
|
|
156
367
|
}
|
|
157
|
-
|
|
158
|
-
jobRequest.keyFrames[0].currentControlNetsJob = getControlNet(params.controlNet);
|
|
159
|
-
}
|
|
160
|
-
if (params.sizePreset === 'custom') {
|
|
161
|
-
jobRequest.keyFrames[0].width = validateCustomImageSize(params.width);
|
|
162
|
-
jobRequest.keyFrames[0].height = validateCustomImageSize(params.height);
|
|
163
|
-
}
|
|
368
|
+
|
|
164
369
|
return jobRequest;
|
|
165
370
|
}
|
|
166
371
|
|