@sogni-ai/sogni-client 4.0.0-alpha.3 → 4.0.0-alpha.31

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 (76) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/README.md +279 -28
  3. package/dist/Account/index.d.ts +18 -16
  4. package/dist/Account/index.js +31 -20
  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 +11 -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 +34 -6
  25. package/dist/Projects/Project.js.map +1 -1
  26. package/dist/Projects/createJobRequestMessage.js +109 -15
  27. package/dist/Projects/createJobRequestMessage.js.map +1 -1
  28. package/dist/Projects/index.d.ts +110 -11
  29. package/dist/Projects/index.js +423 -42
  30. package/dist/Projects/index.js.map +1 -1
  31. package/dist/Projects/types/EstimationResponse.d.ts +2 -0
  32. package/dist/Projects/types/SamplerParams.d.ts +13 -0
  33. package/dist/Projects/types/SamplerParams.js +26 -0
  34. package/dist/Projects/types/SamplerParams.js.map +1 -0
  35. package/dist/Projects/types/SchedulerParams.d.ts +14 -0
  36. package/dist/Projects/types/SchedulerParams.js +24 -0
  37. package/dist/Projects/types/SchedulerParams.js.map +1 -0
  38. package/dist/Projects/types/events.d.ts +5 -1
  39. package/dist/Projects/types/index.d.ts +150 -39
  40. package/dist/Projects/types/index.js +13 -0
  41. package/dist/Projects/types/index.js.map +1 -1
  42. package/dist/Projects/utils.d.ts +19 -1
  43. package/dist/Projects/utils.js +68 -0
  44. package/dist/Projects/utils.js.map +1 -1
  45. package/dist/index.d.ts +12 -4
  46. package/dist/index.js +12 -4
  47. package/dist/index.js.map +1 -1
  48. package/dist/lib/AuthManager/TokenAuthManager.js +0 -2
  49. package/dist/lib/AuthManager/TokenAuthManager.js.map +1 -1
  50. package/dist/lib/DataEntity.js +4 -2
  51. package/dist/lib/DataEntity.js.map +1 -1
  52. package/dist/lib/validation.d.ts +7 -0
  53. package/dist/lib/validation.js +36 -0
  54. package/dist/lib/validation.js.map +1 -1
  55. package/package.json +4 -4
  56. package/src/Account/index.ts +30 -19
  57. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.ts +426 -0
  58. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +237 -0
  59. package/src/ApiClient/WebSocketClient/events.ts +13 -0
  60. package/src/ApiClient/WebSocketClient/index.ts +15 -5
  61. package/src/ApiClient/WebSocketClient/types.ts +16 -0
  62. package/src/ApiClient/index.ts +30 -8
  63. package/src/Projects/Job.ts +97 -16
  64. package/src/Projects/Project.ts +42 -9
  65. package/src/Projects/createJobRequestMessage.ts +155 -36
  66. package/src/Projects/index.ts +447 -46
  67. package/src/Projects/types/EstimationResponse.ts +2 -0
  68. package/src/Projects/types/SamplerParams.ts +24 -0
  69. package/src/Projects/types/SchedulerParams.ts +22 -0
  70. package/src/Projects/types/events.ts +6 -0
  71. package/src/Projects/types/index.ts +181 -47
  72. package/src/Projects/utils.ts +66 -1
  73. package/src/index.ts +38 -11
  74. package/src/lib/AuthManager/TokenAuthManager.ts +0 -2
  75. package/src/lib/DataEntity.ts +4 -2
  76. package/src/lib/validation.ts +41 -0
@@ -1,6 +1,54 @@
1
- import { ProjectParams } from './types';
1
+ import {
2
+ ImageProjectParams,
3
+ isImageParams,
4
+ isVideoParams,
5
+ ProjectParams,
6
+ VideoProjectParams
7
+ } from './types';
2
8
  import { ControlNetParams, ControlNetParamsRaw } from './types/ControlNetParams';
3
- import { validateNumber, validateCustomImageSize } from '../lib/validation';
9
+ import {
10
+ validateNumber,
11
+ validateCustomImageSize,
12
+ validateSampler,
13
+ validateScheduler,
14
+ validateVideoSize
15
+ } from '../lib/validation';
16
+ import { getVideoWorkflowType, isVideoModel, VIDEO_WORKFLOW_ASSETS } from './utils';
17
+ import { ApiError } from '../ApiClient';
18
+
19
+ /**
20
+ * Validate that the provided assets match the workflow requirements.
21
+ * Throws an error if required assets are missing or forbidden assets are provided.
22
+ */
23
+ function validateVideoWorkflowAssets(params: VideoProjectParams): void {
24
+ const workflowType = getVideoWorkflowType(params.modelId);
25
+ if (!workflowType) return;
26
+
27
+ const requirements = VIDEO_WORKFLOW_ASSETS[workflowType];
28
+ if (!requirements) return;
29
+ // Check for missing required assets
30
+ for (const [asset, requirement] of Object.entries(requirements)) {
31
+ const assetKey = asset as keyof VideoProjectParams;
32
+ const hasAsset = !!params[assetKey];
33
+
34
+ if (requirement === 'required' && !hasAsset) {
35
+ throw new ApiError(400, {
36
+ status: 'error',
37
+ errorCode: 0,
38
+ message: `${workflowType} workflow requires ${assetKey}. Please provide this asset.`
39
+ });
40
+ }
41
+
42
+ if (requirement === 'forbidden' && hasAsset) {
43
+ throw new ApiError(400, {
44
+ status: 'error',
45
+ errorCode: 0,
46
+ message: `${workflowType} workflow does not support ${assetKey}. Please remove this asset.`
47
+ });
48
+ }
49
+ }
50
+ }
51
+
4
52
  // Mac worker can't process the data if some of the fields are missing, so we need to provide a default template
5
53
  function getTemplate() {
6
54
  return {
@@ -25,8 +73,8 @@ function getTemplate() {
25
73
  guidanceScaleIsEnabled: true,
26
74
  siImageBackgroundColor: 'black',
27
75
  cnDragOffset: [0, 0],
28
- scheduler: 'DPM Solver Multistep (DPM-Solver++)',
29
- timeStepSpacing: 'Linear',
76
+ scheduler: null,
77
+ timeStepSpacing: null,
30
78
  steps: 20,
31
79
  cnRotation: 0,
32
80
  guidanceScale: 7.5,
@@ -112,49 +160,120 @@ function getControlNet(params: ControlNetParams): ControlNetParamsRaw[] {
112
160
  return [cn];
113
161
  }
114
162
 
163
+ function applyImageParams(inputKeyframe: Record<string, any>, params: ImageProjectParams) {
164
+ const keyFrame: Record<string, any> = {
165
+ ...inputKeyframe,
166
+ scheduler: validateSampler(params.sampler),
167
+ timeStepSpacing: validateScheduler(params.scheduler),
168
+ sizePreset: params.sizePreset,
169
+ hasContextImage1: !!params.contextImages?.[0],
170
+ hasContextImage2: !!params.contextImages?.[1],
171
+ hasContextImage3: !!params.contextImages?.[2]
172
+ };
173
+
174
+ if (params.startingImage) {
175
+ keyFrame.hasStartingImage = true;
176
+ keyFrame.strengthIsEnabled = true;
177
+ keyFrame.strength = 1 - (Number(params.startingImageStrength) || 0.5);
178
+ }
179
+
180
+ if (params.controlNet) {
181
+ keyFrame.currentControlNetsJob = getControlNet(params.controlNet);
182
+ }
183
+ if (params.sizePreset === 'custom') {
184
+ keyFrame.width = validateCustomImageSize(params.width);
185
+ keyFrame.height = validateCustomImageSize(params.height);
186
+ }
187
+ return keyFrame;
188
+ }
189
+
190
+ function applyVideoParams(inputKeyframe: Record<string, any>, params: VideoProjectParams) {
191
+ if (!isVideoModel(params.modelId)) {
192
+ throw new ApiError(400, {
193
+ status: 'error',
194
+ errorCode: 0,
195
+ message: 'Video generation is only supported for video models.'
196
+ });
197
+ }
198
+ validateVideoWorkflowAssets(params);
199
+ const keyFrame: Record<string, any> = { ...inputKeyframe };
200
+ if (params.referenceImage) {
201
+ keyFrame.hasReferenceImage = true;
202
+ }
203
+ if (params.referenceImageEnd) {
204
+ keyFrame.hasReferenceImageEnd = true;
205
+ }
206
+ if (params.referenceAudio) {
207
+ keyFrame.hasReferenceAudio = true;
208
+ }
209
+ if (params.referenceVideo) {
210
+ keyFrame.hasReferenceVideo = true;
211
+ }
212
+
213
+ // Video generation parameters
214
+ if (params.frames !== undefined) {
215
+ keyFrame.frames = params.frames;
216
+ }
217
+ if (params.fps !== undefined) {
218
+ keyFrame.fps = params.fps;
219
+ }
220
+ if (params.shift !== undefined) {
221
+ keyFrame.shift = params.shift;
222
+ }
223
+
224
+ // Validate and set video dimensions (minimum 480px for Wan 2.2 models)
225
+ if (params.width && params.height) {
226
+ keyFrame.width = validateVideoSize(params.width, 'width');
227
+ keyFrame.height = validateVideoSize(params.height, 'height');
228
+ }
229
+
230
+ return keyFrame;
231
+ }
232
+
115
233
  function createJobRequestMessage(id: string, params: ProjectParams) {
116
234
  const template = getTemplate();
235
+ // Base keyFrame with common params
236
+ let keyFrame: Record<string, any> = {
237
+ ...template.keyFrames[0],
238
+ steps: params.steps,
239
+ guidanceScale: params.guidance,
240
+ modelID: params.modelId,
241
+ negativePrompt: params.negativePrompt,
242
+ seed: params.seed,
243
+ positivePrompt: params.positivePrompt,
244
+ stylePrompt: params.stylePrompt
245
+ };
246
+
247
+ switch (params.type) {
248
+ case 'image':
249
+ keyFrame = applyImageParams(keyFrame, params);
250
+ break;
251
+ case 'video':
252
+ keyFrame = applyVideoParams(keyFrame, params);
253
+ break;
254
+ default:
255
+ throw new ApiError(400, {
256
+ status: 'error',
257
+ errorCode: 0,
258
+ message: 'Invalid project type. Must be "image" or "video".'
259
+ });
260
+ }
261
+
117
262
  const jobRequest: Record<string, any> = {
118
263
  ...template,
119
- keyFrames: [
120
- {
121
- ...template.keyFrames[0],
122
- scheduler: params.scheduler || null,
123
- timeStepSpacing: params.timeStepSpacing || null,
124
- steps: params.steps,
125
- guidanceScale: params.guidance,
126
- modelID: params.modelId,
127
- negativePrompt: params.negativePrompt,
128
- seed: params.seed,
129
- positivePrompt: params.positivePrompt,
130
- stylePrompt: params.stylePrompt,
131
- hasStartingImage: !!params.startingImage,
132
- hasContextImage1: !!params.contextImages?.[0],
133
- hasContextImage2: !!params.contextImages?.[1],
134
- strengthIsEnabled: !!params.startingImage,
135
- strength: !!params.startingImage
136
- ? 1 - (Number(params.startingImageStrength) || 0.5)
137
- : undefined,
138
- sizePreset: params.sizePreset
139
- }
140
- ],
141
- previews: params.numberOfPreviews || 0,
142
- numberOfImages: params.numberOfImages,
264
+ keyFrames: [keyFrame],
265
+ previews: isImageParams(params) ? params.numberOfPreviews || 0 : 0,
266
+ numberOfImages: params.numberOfMedia || 1,
143
267
  jobID: id,
144
268
  disableSafety: !!params.disableNSFWFilter,
145
269
  tokenType: params.tokenType,
146
- outputFormat: params.outputFormat || 'png'
270
+ outputFormat: params.outputFormat || (isVideoParams(params) ? 'mp4' : 'png')
147
271
  };
272
+
148
273
  if (params.network) {
149
274
  jobRequest.network = params.network;
150
275
  }
151
- if (params.controlNet) {
152
- jobRequest.keyFrames[0].currentControlNetsJob = getControlNet(params.controlNet);
153
- }
154
- if (params.sizePreset === 'custom') {
155
- jobRequest.keyFrames[0].width = validateCustomImageSize(params.width);
156
- jobRequest.keyFrames[0].height = validateCustomImageSize(params.height);
157
- }
276
+
158
277
  return jobRequest;
159
278
  }
160
279