@sogni-ai/sogni-client 4.0.0-alpha.45 → 4.0.0-alpha.47

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 (65) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +32 -27
  3. package/dist/Projects/createJobRequestMessage.d.ts +2 -1
  4. package/dist/Projects/createJobRequestMessage.js +29 -27
  5. package/dist/Projects/createJobRequestMessage.js.map +1 -1
  6. package/dist/Projects/index.d.ts +4 -2
  7. package/dist/Projects/index.js +45 -17
  8. package/dist/Projects/index.js.map +1 -1
  9. package/dist/Projects/types/ComfySamplerParams.d.ts +0 -28
  10. package/dist/Projects/types/ComfySamplerParams.js +0 -34
  11. package/dist/Projects/types/ComfySamplerParams.js.map +1 -1
  12. package/dist/Projects/types/ModelOptions.d.ts +31 -0
  13. package/dist/Projects/types/ModelOptions.js +56 -0
  14. package/dist/Projects/types/ModelOptions.js.map +1 -0
  15. package/dist/Projects/types/ModelTiersRaw.d.ts +67 -0
  16. package/dist/Projects/types/ModelTiersRaw.js +15 -0
  17. package/dist/Projects/types/ModelTiersRaw.js.map +1 -0
  18. package/dist/Projects/types/index.d.ts +16 -24
  19. package/dist/Projects/types/index.js +0 -9
  20. package/dist/Projects/types/index.js.map +1 -1
  21. package/dist/Projects/{utils.d.ts → utils/index.d.ts} +1 -1
  22. package/dist/Projects/{utils.js → utils/index.js} +1 -1
  23. package/dist/Projects/utils/index.js.map +1 -0
  24. package/dist/Projects/utils/samplers.d.ts +6 -0
  25. package/dist/Projects/utils/samplers.js +38 -0
  26. package/dist/Projects/utils/samplers.js.map +1 -0
  27. package/dist/Projects/utils/scheduler.d.ts +6 -0
  28. package/dist/Projects/utils/scheduler.js +30 -0
  29. package/dist/Projects/utils/scheduler.js.map +1 -0
  30. package/dist/index.d.ts +3 -3
  31. package/dist/index.js +1 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/lib/{utils.js → utils/index.js} +1 -1
  34. package/dist/lib/utils/index.js.map +1 -0
  35. package/dist/lib/validation.d.ts +16 -11
  36. package/dist/lib/validation.js +45 -63
  37. package/dist/lib/validation.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/Projects/createJobRequestMessage.ts +43 -33
  40. package/src/Projects/index.ts +54 -28
  41. package/src/Projects/types/ComfySamplerParams.ts +0 -34
  42. package/src/Projects/types/ModelOptions.ts +92 -0
  43. package/src/Projects/types/ModelTiersRaw.ts +86 -0
  44. package/src/Projects/types/index.ts +16 -33
  45. package/src/Projects/{utils.ts → utils/index.ts} +1 -1
  46. package/src/Projects/utils/samplers.ts +35 -0
  47. package/src/Projects/utils/scheduler.ts +27 -0
  48. package/src/index.ts +1 -26
  49. package/src/lib/validation.ts +53 -77
  50. package/dist/Projects/types/ComfySchedulerParams.d.ts +0 -17
  51. package/dist/Projects/types/ComfySchedulerParams.js +0 -23
  52. package/dist/Projects/types/ComfySchedulerParams.js.map +0 -1
  53. package/dist/Projects/types/ForgeSamplerParams.d.ts +0 -27
  54. package/dist/Projects/types/ForgeSamplerParams.js +0 -39
  55. package/dist/Projects/types/ForgeSamplerParams.js.map +0 -1
  56. package/dist/Projects/types/ForgeSchedulerParams.d.ts +0 -17
  57. package/dist/Projects/types/ForgeSchedulerParams.js +0 -28
  58. package/dist/Projects/types/ForgeSchedulerParams.js.map +0 -1
  59. package/dist/Projects/utils.js.map +0 -1
  60. package/dist/lib/utils.js.map +0 -1
  61. package/src/Projects/types/ComfySchedulerParams.ts +0 -21
  62. package/src/Projects/types/ForgeSamplerParams.ts +0 -37
  63. package/src/Projects/types/ForgeSchedulerParams.ts +0 -26
  64. /package/dist/lib/{utils.d.ts → utils/index.d.ts} +0 -0
  65. /package/src/lib/{utils.ts → utils/index.ts} +0 -0
@@ -4,18 +4,12 @@ exports.validateCustomImageSize = validateCustomImageSize;
4
4
  exports.validateVideoSize = validateVideoSize;
5
5
  exports.validateVideoDuration = validateVideoDuration;
6
6
  exports.validateNumber = validateNumber;
7
- exports.validateForgeSampler = validateForgeSampler;
8
- exports.validateForgeScheduler = validateForgeScheduler;
9
7
  exports.validateTeacacheThreshold = validateTeacacheThreshold;
10
- exports.validateComfySampler = validateComfySampler;
11
- exports.validateComfyScheduler = validateComfyScheduler;
12
8
  exports.isComfyModel = isComfyModel;
9
+ exports.getMaxContextImages = getMaxContextImages;
13
10
  exports.validateSampler = validateSampler;
14
11
  exports.validateScheduler = validateScheduler;
15
- const ForgeSamplerParams_1 = require("../Projects/types/ForgeSamplerParams");
16
- const ForgeSchedulerParams_1 = require("../Projects/types/ForgeSchedulerParams");
17
- const ComfySamplerParams_1 = require("../Projects/types/ComfySamplerParams");
18
- const ComfySchedulerParams_1 = require("../Projects/types/ComfySchedulerParams");
12
+ const ApiClient_1 = require("../ApiClient");
19
13
  function validateCustomImageSize(value) {
20
14
  return validateNumber(value, { min: 256, max: 2048, propertyName: 'Width and height' });
21
15
  }
@@ -55,30 +49,6 @@ function validateNumber(value, { min, max, propertyName, defaultValue } = {}) {
55
49
  }
56
50
  return number;
57
51
  }
58
- function validateForgeSampler(value) {
59
- if (!value) {
60
- return null;
61
- }
62
- if ((0, ForgeSamplerParams_1.isRawForgeSampler)(value)) {
63
- return value;
64
- }
65
- if ((0, ForgeSamplerParams_1.isForgeSampler)(value)) {
66
- return ForgeSamplerParams_1.SupportedForgeSamplers[value];
67
- }
68
- throw new Error(`Invalid sampler: ${value}. Supported options: ${Object.keys(ForgeSamplerParams_1.SupportedForgeSamplers).join(', ')}`);
69
- }
70
- function validateForgeScheduler(value) {
71
- if (!value) {
72
- return null;
73
- }
74
- if ((0, ForgeSchedulerParams_1.isRawForgeScheduler)(value)) {
75
- return value;
76
- }
77
- if ((0, ForgeSchedulerParams_1.isForgeScheduler)(value)) {
78
- return ForgeSchedulerParams_1.SupportedForgeSchedulers[value];
79
- }
80
- throw new Error(`Invalid scheduler: ${value}. Supported options: ${Object.keys(ForgeSchedulerParams_1.SupportedForgeSchedulers).join(', ')}`);
81
- }
82
52
  /**
83
53
  * Validate teacacheThreshold for T2V and I2V models.
84
54
  * Range: 0.0-1.0. 0.0 = disabled.
@@ -96,46 +66,58 @@ function validateTeacacheThreshold(value) {
96
66
  }
97
67
  return num;
98
68
  }
99
- /**
100
- * Validate ComfyUI sampler for video models.
101
- * Returns the sampler string directly (no mapping needed).
102
- */
103
- function validateComfySampler(value) {
104
- if (!value) {
105
- return undefined;
106
- }
107
- if ((0, ComfySamplerParams_1.isComfySampler)(value)) {
108
- return ComfySamplerParams_1.SupportedComfySamplers[value];
109
- }
110
- throw new Error(`Invalid comfySampler: ${value}. Supported options: ${Object.keys(ComfySamplerParams_1.SupportedComfySamplers).join(', ')}`);
69
+ function isComfyModel(modelId) {
70
+ const COMFY_PREFIXES = ['z_image_', 'qwen_image_', 'flux2_', 'wan_'];
71
+ return COMFY_PREFIXES.some((prefix) => modelId.startsWith(prefix));
111
72
  }
112
73
  /**
113
- * Validate ComfyUI scheduler for video models.
114
- * Returns the scheduler string directly (no mapping needed).
74
+ * Get the maximum number of context images supported by a model.
75
+ * - Flux.2 Dev: 6 images
76
+ * - Qwen Image Edit: 3 images
77
+ * - Flux Kontext: 2 images
78
+ * - Default: 3 images
115
79
  */
116
- function validateComfyScheduler(value) {
117
- if (!value) {
118
- return undefined;
80
+ function getMaxContextImages(modelId) {
81
+ if (modelId.startsWith('flux2_')) {
82
+ return 6;
119
83
  }
120
- if ((0, ComfySchedulerParams_1.isComfyScheduler)(value)) {
121
- return ComfySchedulerParams_1.SupportedComfySchedulers[value];
84
+ if (modelId.startsWith('qwen_image_')) {
85
+ return 3;
122
86
  }
123
- throw new Error(`Invalid comfyScheduler: ${value}. Supported options: ${Object.keys(ComfySchedulerParams_1.SupportedComfySchedulers).join(', ')}`);
87
+ if (modelId.includes('kontext')) {
88
+ return 2;
89
+ }
90
+ // Default fallback for other models that might support context images
91
+ return 3;
124
92
  }
125
- function isComfyModel(modelId) {
126
- const COMFY_PREFIXES = ['z_image_', 'qwen_image_', 'flux2_', 'wan_'];
127
- return COMFY_PREFIXES.some((prefix) => modelId.startsWith(prefix));
93
+ function validateOption(value, options, errorMessage) {
94
+ if (!options.includes(value)) {
95
+ throw new ApiClient_1.ApiError(400, {
96
+ status: 'error',
97
+ errorCode: 0,
98
+ message: errorMessage
99
+ });
100
+ }
101
+ return value;
128
102
  }
129
- function validateSampler(modelId, sampler) {
130
- if (isComfyModel(modelId)) {
131
- return validateComfySampler(sampler);
103
+ /**
104
+ * Validate sampler value against allowed options.
105
+ * Returns the validated value unchanged - sogni-socket handles normalization.
106
+ */
107
+ function validateSampler(value, options) {
108
+ if (!options.sampler.allowed.length || !value) {
109
+ return null;
132
110
  }
133
- return validateForgeSampler(sampler);
111
+ return validateOption(value, options.sampler.allowed, `Invalid sampler ${value}. Must be one of "${options.sampler.allowed.join('", "')}".`);
134
112
  }
135
- function validateScheduler(modelId, scheduler) {
136
- if (isComfyModel(modelId)) {
137
- return validateComfyScheduler(scheduler);
113
+ /**
114
+ * Validate scheduler value against allowed options.
115
+ * Returns the validated value unchanged - sogni-socket handles normalization.
116
+ */
117
+ function validateScheduler(value, options) {
118
+ if (!options.scheduler.allowed.length || !value) {
119
+ return null;
138
120
  }
139
- return validateForgeScheduler(scheduler);
121
+ return validateOption(value, options.scheduler.allowed, `Invalid scheduler ${value}. Must be one of "${options.scheduler.allowed.join('", "')}".`);
140
122
  }
141
123
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "4.0.0-alpha.45",
6
+ "version": "4.0.0-alpha.47",
7
7
  "description": "Sogni Supernet Client",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -9,17 +9,16 @@ import { ControlNetParams, ControlNetParamsRaw } from './types/ControlNetParams'
9
9
  import {
10
10
  validateNumber,
11
11
  validateCustomImageSize,
12
- validateForgeSampler,
13
- validateForgeScheduler,
14
12
  validateVideoSize,
15
13
  validateTeacacheThreshold,
16
- validateComfySampler,
17
- validateComfyScheduler,
18
14
  isComfyModel,
19
- validateVideoDuration
15
+ validateVideoDuration,
16
+ validateSampler,
17
+ validateScheduler
20
18
  } from '../lib/validation';
21
19
  import { getVideoWorkflowType, isVideoModel, VIDEO_WORKFLOW_ASSETS } from './utils';
22
20
  import { ApiError } from '../ApiClient';
21
+ import { ImageModelOptions, ModelOptions, VideoModelOptions } from './types/ModelOptions';
23
22
 
24
23
  /**
25
24
  * Validate that the provided assets match the workflow requirements.
@@ -178,7 +177,11 @@ function getControlNet(params: ControlNetParams): ControlNetParamsRaw[] {
178
177
  return [cn];
179
178
  }
180
179
 
181
- function applyImageParams(inputKeyframe: Record<string, any>, params: ImageProjectParams) {
180
+ function applyImageParams(
181
+ inputKeyframe: Record<string, any>,
182
+ params: ImageProjectParams,
183
+ options: ImageModelOptions
184
+ ) {
182
185
  const keyFrame: Record<string, any> = {
183
186
  ...inputKeyframe,
184
187
  sizePreset: params.sizePreset,
@@ -189,23 +192,16 @@ function applyImageParams(inputKeyframe: Record<string, any>, params: ImageProje
189
192
  hasContextImage5: !!params.contextImages?.[4],
190
193
  hasContextImage6: !!params.contextImages?.[5]
191
194
  };
192
-
193
- // Handle sampler/scheduler: ComfyUI models use comfySampler/comfyScheduler,
194
- // legacy models use sampler/scheduler (mapped to scheduler/timeStepSpacing)
195
+ // Sampler/scheduler handling: SDK validates and passes through as-is.
196
+ // sogni-socket normalizes values for both ComfyUI and Forge workers.
195
197
  if (isComfyModel(params.modelId)) {
196
- if (params.sampler !== undefined) {
197
- keyFrame.comfySampler = validateComfySampler(params.sampler);
198
- }
199
- if (params.scheduler !== undefined) {
200
- keyFrame.comfyScheduler = validateComfyScheduler(params.scheduler);
201
- }
198
+ // ComfyUI models use comfySampler/comfyScheduler fields
199
+ keyFrame.comfySampler = validateSampler(params.sampler, options);
200
+ keyFrame.comfyScheduler = validateScheduler(params.scheduler, options);
202
201
  } else {
203
- if (params.sampler !== undefined) {
204
- keyFrame.scheduler = validateForgeSampler(params.sampler);
205
- }
206
- if (params.scheduler !== undefined) {
207
- keyFrame.timeStepSpacing = validateForgeScheduler(params.scheduler);
208
- }
202
+ // Legacy Forge models use scheduler/timeStepSpacing fields
203
+ keyFrame.scheduler = validateSampler(params.sampler, options);
204
+ keyFrame.timeStepSpacing = validateScheduler(params.scheduler, options);
209
205
  }
210
206
 
211
207
  if (params.startingImage) {
@@ -232,7 +228,11 @@ function applyImageParams(inputKeyframe: Record<string, any>, params: ImageProje
232
228
  return keyFrame;
233
229
  }
234
230
 
235
- function applyVideoParams(inputKeyframe: Record<string, any>, params: VideoProjectParams) {
231
+ function applyVideoParams(
232
+ inputKeyframe: Record<string, any>,
233
+ params: VideoProjectParams,
234
+ options: VideoModelOptions
235
+ ) {
236
236
  if (!isVideoModel(params.modelId)) {
237
237
  throw new ApiError(400, {
238
238
  status: 'error',
@@ -295,19 +295,13 @@ function applyVideoParams(inputKeyframe: Record<string, any>, params: VideoProje
295
295
  keyFrame.height = validateVideoSize(params.height, 'height');
296
296
  }
297
297
 
298
- // Video models are ComfyUI models - only accept comfySampler/comfyScheduler
299
- // Legacy sampler/scheduler fields are NOT supported for video models
300
- if (params.sampler !== undefined) {
301
- keyFrame.comfySampler = validateComfySampler(params.sampler);
302
- }
303
- if (params.scheduler !== undefined) {
304
- keyFrame.comfyScheduler = validateComfyScheduler(params.scheduler);
305
- }
298
+ keyFrame.comfySampler = validateSampler(params.sampler, options);
299
+ keyFrame.comfyScheduler = validateScheduler(params.scheduler, options);
306
300
 
307
301
  return keyFrame;
308
302
  }
309
303
 
310
- function createJobRequestMessage(id: string, params: ProjectParams) {
304
+ function createJobRequestMessage(id: string, params: ProjectParams, options: ModelOptions) {
311
305
  const template = getTemplate();
312
306
  // Base keyFrame with common params
313
307
  let keyFrame: Record<string, any> = {
@@ -323,10 +317,26 @@ function createJobRequestMessage(id: string, params: ProjectParams) {
323
317
 
324
318
  switch (params.type) {
325
319
  case 'image':
326
- keyFrame = applyImageParams(keyFrame, params);
320
+ if (options.type !== 'image') {
321
+ throw new ApiError(400, {
322
+ status: 'error',
323
+ errorCode: 0,
324
+ message:
325
+ 'Invalid model type. Model does not support image generation. Please use a different model.'
326
+ });
327
+ }
328
+ keyFrame = applyImageParams(keyFrame, params, options);
327
329
  break;
328
330
  case 'video':
329
- keyFrame = applyVideoParams(keyFrame, params);
331
+ if (options.type !== 'video') {
332
+ throw new ApiError(400, {
333
+ status: 'error',
334
+ errorCode: 0,
335
+ message:
336
+ 'Invalid model type. Model does not support video generation. Please use a different model.'
337
+ });
338
+ }
339
+ keyFrame = applyVideoParams(keyFrame, params, options);
330
340
  break;
331
341
  default:
332
342
  throw new ApiError(400, {
@@ -11,15 +11,7 @@ import {
11
11
  SupportedModel,
12
12
  ImageProjectParams,
13
13
  VideoProjectParams,
14
- VideoEstimateRequest,
15
- SupportedComfySamplers,
16
- SupportedForgeSamplers,
17
- SupportedComfySchedulers,
18
- SupportedForgeSchedulers,
19
- ComfyScheduler,
20
- ForgeScheduler,
21
- ComfySampler,
22
- ForgeSampler
14
+ VideoEstimateRequest
23
15
  } from './types';
24
16
  import {
25
17
  JobErrorData,
@@ -47,7 +39,9 @@ import {
47
39
  VIDEO_WORKFLOW_ASSETS
48
40
  } from './utils';
49
41
  import { TokenType } from '../types/token';
50
- import { isComfyModel, validateSampler } from '../lib/validation';
42
+ import { getMaxContextImages, validateSampler } from '../lib/validation';
43
+ import ModelTiersRaw, { isComfyImageTier, isImageTier, isVideoTier } from './types/ModelTiersRaw';
44
+ import { mapComfyImageTier, mapImageTier, mapVideoTier, ModelOptions } from './types/ModelOptions';
51
45
 
52
46
  const sizePresetCache = new Cache<SizePreset[]>(10 * 60 * 1000);
53
47
  const GARBAGE_COLLECT_TIMEOUT = 30000;
@@ -106,6 +100,13 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
106
100
  data: null,
107
101
  updatedAt: new Date(0)
108
102
  };
103
+ private _modelTiers: {
104
+ data: ModelTiersRaw;
105
+ updatedAt: Date;
106
+ } = {
107
+ data: {},
108
+ updatedAt: new Date(0)
109
+ };
109
110
 
110
111
  get availableModels() {
111
112
  return this._availableModels;
@@ -524,7 +525,8 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
524
525
  */
525
526
  async create(data: ProjectParams): Promise<Project> {
526
527
  const project = new Project({ ...data }, { api: this, logger: this.client.logger });
527
- const request = createJobRequestMessage(project.id, data);
528
+ const modelOptions = await this.getModelOptions(data.modelId);
529
+ const request = createJobRequestMessage(project.id, data, modelOptions);
528
530
 
529
531
  switch (data.type) {
530
532
  case 'image':
@@ -550,19 +552,20 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
550
552
  await this.uploadCNImage(project.id, data.controlNet.image);
551
553
  }
552
554
 
553
- // Context images (Flux.2 Dev, Qwen Image Edit Plus support up to 3; Flux Kontext supports up to 2)
555
+ // Context images (Flux.2 Dev supports up to 6; Qwen Image Edit Plus supports up to 3; Flux Kontext supports up to 2)
554
556
  if (data.contextImages?.length) {
555
- if (data.contextImages.length > 3) {
557
+ const maxContextImages = getMaxContextImages(data.modelId);
558
+ if (data.contextImages.length > maxContextImages) {
556
559
  throw new ApiError(500, {
557
560
  status: 'error',
558
561
  errorCode: 0,
559
- message: `Up to 3 context images are supported`
562
+ message: `Up to ${maxContextImages} context images are supported for this model`
560
563
  });
561
564
  }
562
565
  await Promise.all(
563
566
  data.contextImages.map((image, index) => {
564
567
  if (image && image !== true) {
565
- return this.uploadContextImage(project.id, index as 0 | 1 | 2, image);
568
+ return this.uploadContextImage(project.id, index as 0 | 1 | 2 | 3 | 4 | 5, image);
566
569
  }
567
570
  })
568
571
  );
@@ -672,11 +675,11 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
672
675
 
673
676
  private async uploadContextImage(
674
677
  projectId: string,
675
- index: 0 | 1 | 2,
678
+ index: 0 | 1 | 2 | 3 | 4 | 5,
676
679
  file: File | Buffer | Blob
677
680
  ) {
678
681
  const imageId = getUUID();
679
- const imageIndex = (index + 1) as 1 | 2 | 3;
682
+ const imageIndex = (index + 1) as 1 | 2 | 3 | 4 | 5 | 6;
680
683
  const presignedUrl = await this.uploadUrl({
681
684
  imageId,
682
685
  jobId: projectId,
@@ -833,6 +836,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
833
836
  contextImages
834
837
  }: EstimateRequest): Promise<CostEstimation> {
835
838
  let apiVersion = 2;
839
+ const modelOptions = await this.getModelOptions(model);
836
840
  const pathParams = [
837
841
  tokenType || 'spark',
838
842
  network,
@@ -858,7 +862,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
858
862
  if (sampler) {
859
863
  apiVersion = 3;
860
864
  pathParams.push(guidance || 0);
861
- pathParams.push(validateSampler(model, sampler)!);
865
+ pathParams.push(validateSampler(sampler, modelOptions)!);
862
866
  pathParams.push(contextImages || 0);
863
867
  }
864
868
  const r = await this.client.socket.get<EstimationResponse>(
@@ -1005,6 +1009,19 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
1005
1009
  return models;
1006
1010
  }
1007
1011
 
1012
+ private async _getModelTiers(forceRefresh = false) {
1013
+ if (
1014
+ this._modelTiers.data &&
1015
+ !forceRefresh &&
1016
+ Date.now() - this._modelTiers.updatedAt.getTime() < MODELS_REFRESH_INTERVAL
1017
+ ) {
1018
+ return this._modelTiers.data;
1019
+ }
1020
+ const tiers = await this.client.socket.get<ModelTiersRaw>(`/api/v2/models/tiers`);
1021
+ this._modelTiers = { data: tiers, updatedAt: new Date() };
1022
+ return tiers;
1023
+ }
1024
+
1008
1025
  /**
1009
1026
  * Get supported size presets for the model and network. Size presets are cached for 10 minutes.
1010
1027
  *
@@ -1104,18 +1121,27 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
1104
1121
  });
1105
1122
  }
1106
1123
 
1107
- async getSamplers(modelId: string) {
1108
- if (isComfyModel(modelId)) {
1109
- return Object.keys(SupportedComfySamplers) as ComfySampler[];
1124
+ async getModelOptions(modelId: string): Promise<ModelOptions> {
1125
+ const models = await this.getSupportedModels();
1126
+ const tiers = await this._getModelTiers();
1127
+ const model = models.find((m) => m.id === modelId);
1128
+ if (!model) {
1129
+ throw new Error(`Model ${modelId} not supported`);
1110
1130
  }
1111
- return Object.keys(SupportedForgeSamplers) as ForgeSampler[];
1112
- }
1113
-
1114
- async getSchedulers(modelId: string) {
1115
- if (isComfyModel(modelId)) {
1116
- return Object.keys(SupportedComfySchedulers) as ComfyScheduler[];
1131
+ const tier = tiers[model.tier];
1132
+ if (!tier) {
1133
+ throw new Error(`Unable to find model tier "${model.tier}" please contact support`);
1134
+ }
1135
+ if (isImageTier(tier)) {
1136
+ return mapImageTier(tier);
1137
+ }
1138
+ if (isVideoTier(tier)) {
1139
+ return mapVideoTier(tier);
1140
+ }
1141
+ if (isComfyImageTier(tier)) {
1142
+ return mapComfyImageTier(tier);
1117
1143
  }
1118
- return Object.keys(SupportedForgeSchedulers) as ForgeScheduler[];
1144
+ throw new Error(`Unsupported model tier "${model.tier}"`);
1119
1145
  }
1120
1146
  }
1121
1147
 
@@ -1,34 +0,0 @@
1
- /**
2
- * ComfyUI sampler parameters for video models and ComfyUI-based image models.
3
- * These use lowercase underscore format directly matching ComfyUI's internal names.
4
- */
5
- export const SupportedComfySamplers = {
6
- euler: 'euler',
7
- euler_ancestral: 'euler_ancestral',
8
- heun: 'heun',
9
- dpmpp_2m: 'dpmpp_2m',
10
- dpmpp_2m_sde: 'dpmpp_2m_sde',
11
- dpmpp_sde: 'dpmpp_sde',
12
- dpmpp_3m_sde: 'dpmpp_3m_sde',
13
- uni_pc: 'uni_pc',
14
- lcm: 'lcm',
15
- // Additional ComfyUI samplers
16
- lms: 'lms',
17
- dpm_2: 'dpm_2',
18
- dpm_2_ancestral: 'dpm_2_ancestral',
19
- dpm_fast: 'dpm_fast',
20
- dpm_adaptive: 'dpm_adaptive',
21
- dpmpp_2s_ancestral: 'dpmpp_2s_ancestral',
22
- ddpm: 'ddpm',
23
- ddim: 'ddim',
24
- uni_pc_bh2: 'uni_pc_bh2',
25
- // Z-Image specific samplers
26
- res_multistep: 'res_multistep',
27
- res_multistep_cfg_pp: 'res_multistep_cfg_pp'
28
- };
29
-
30
- export function isComfySampler(sampler: string): sampler is ComfySampler {
31
- return sampler in SupportedComfySamplers;
32
- }
33
-
34
- export type ComfySampler = keyof typeof SupportedComfySamplers;
@@ -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
+ }