@sogni-ai/sogni-client 5.1.0 → 5.2.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.
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +18 -0
- package/README.md +26 -1
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +1 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +12 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
- package/dist/ApiClient/WebSocketClient/events.d.ts +11 -0
- package/dist/Chat/index.d.ts +3 -1
- package/dist/Chat/index.js +17 -4
- package/dist/Chat/index.js.map +1 -1
- package/dist/Chat/modelRouting.d.ts +2 -0
- package/dist/Chat/modelRouting.js +6 -2
- package/dist/Chat/modelRouting.js.map +1 -1
- package/dist/Chat/types.d.ts +40 -0
- package/dist/Projects/createJobRequestMessage.js +1 -0
- package/dist/Projects/createJobRequestMessage.js.map +1 -1
- package/dist/Projects/index.js +3 -2
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/types/ModelOptions.d.ts +1 -0
- package/dist/Projects/types/ModelOptions.js +2 -1
- package/dist/Projects/types/ModelOptions.js.map +1 -1
- package/dist/Projects/types/ModelTiersRaw.d.ts +1 -0
- package/dist/Projects/types/ModelTiersRaw.js.map +1 -1
- package/dist/Projects/types/events.d.ts +3 -0
- package/dist/Projects/types/index.d.ts +29 -9
- package/dist/Projects/types/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/validation.d.ts +6 -0
- package/dist/lib/validation.js +40 -7
- package/dist/lib/validation.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +12 -0
- package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
- package/dist-esm/Chat/index.js +17 -4
- package/dist-esm/Chat/index.js.map +1 -1
- package/dist-esm/Chat/modelRouting.js +6 -2
- package/dist-esm/Chat/modelRouting.js.map +1 -1
- package/dist-esm/Projects/createJobRequestMessage.js +2 -1
- package/dist-esm/Projects/createJobRequestMessage.js.map +1 -1
- package/dist-esm/Projects/index.js +3 -2
- package/dist-esm/Projects/index.js.map +1 -1
- package/dist-esm/Projects/types/ModelOptions.js +2 -1
- package/dist-esm/Projects/types/ModelOptions.js.map +1 -1
- package/dist-esm/Projects/types/ModelTiersRaw.js.map +1 -1
- package/dist-esm/Projects/types/index.js.map +1 -1
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/lib/validation.js +39 -7
- package/dist-esm/lib/validation.js.map +1 -1
- package/dist-esm/version.js +1 -1
- package/llms-full.txt +18 -4
- package/llms.txt +10 -2
- package/package.json +1 -1
- package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +11 -0
- package/src/ApiClient/WebSocketClient/events.ts +12 -0
- package/src/Chat/index.ts +29 -1
- package/src/Chat/modelRouting.ts +15 -2
- package/src/Chat/types.ts +49 -0
- package/src/Projects/createJobRequestMessage.ts +3 -1
- package/src/Projects/index.ts +3 -2
- package/src/Projects/types/ModelOptions.ts +3 -1
- package/src/Projects/types/ModelTiersRaw.ts +1 -0
- package/src/Projects/types/events.ts +4 -0
- package/src/Projects/types/index.ts +29 -9
- package/src/index.ts +8 -1
- package/src/lib/validation.ts +44 -7
- package/src/version.ts +1 -1
package/src/Chat/index.ts
CHANGED
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
HostedChatCompletionParams,
|
|
22
22
|
ConfirmChatRunCostParams,
|
|
23
23
|
HostedChatCompletionResult,
|
|
24
|
+
HostedToolExecutionParams,
|
|
25
|
+
HostedToolExecutionResult,
|
|
24
26
|
LLMCostEstimation,
|
|
25
27
|
LLMEstimateResponse,
|
|
26
28
|
LLMModelInfo,
|
|
@@ -249,6 +251,7 @@ class ChatApi extends ApiGroup<ChatApiEvents> {
|
|
|
249
251
|
*/
|
|
250
252
|
hosted: {
|
|
251
253
|
create: (params: HostedChatCompletionParams) => Promise<HostedChatCompletionResult>;
|
|
254
|
+
executeTool: (params: HostedToolExecutionParams) => Promise<HostedToolExecutionResult>;
|
|
252
255
|
};
|
|
253
256
|
|
|
254
257
|
/**
|
|
@@ -295,7 +298,8 @@ class ChatApi extends ApiGroup<ChatApiEvents> {
|
|
|
295
298
|
create: this.createCompletion.bind(this) as any
|
|
296
299
|
};
|
|
297
300
|
this.hosted = {
|
|
298
|
-
create: this.createHostedCompletion.bind(this)
|
|
301
|
+
create: this.createHostedCompletion.bind(this),
|
|
302
|
+
executeTool: this.executeHostedTool.bind(this)
|
|
299
303
|
};
|
|
300
304
|
this.runs = {
|
|
301
305
|
create: this.createChatRun.bind(this),
|
|
@@ -531,6 +535,9 @@ class ChatApi extends ApiGroup<ChatApiEvents> {
|
|
|
531
535
|
task_profile: params.task_profile ?? params.taskProfile,
|
|
532
536
|
media_references: params.media_references ?? params.mediaReferences,
|
|
533
537
|
api_media_references: params.api_media_references ?? params.apiMediaReferences,
|
|
538
|
+
...(params.safe_content_filter !== undefined || params.safeContentFilter !== undefined
|
|
539
|
+
? { safe_content_filter: params.safe_content_filter ?? params.safeContentFilter }
|
|
540
|
+
: {}),
|
|
534
541
|
...(chatTemplateKwargs && { chat_template_kwargs: chatTemplateKwargs }),
|
|
535
542
|
...(params.response_format && { response_format: params.response_format })
|
|
536
543
|
},
|
|
@@ -559,6 +566,24 @@ class ChatApi extends ApiGroup<ChatApiEvents> {
|
|
|
559
566
|
}
|
|
560
567
|
}
|
|
561
568
|
|
|
569
|
+
private async executeHostedTool(
|
|
570
|
+
params: HostedToolExecutionParams
|
|
571
|
+
): Promise<HostedToolExecutionResult> {
|
|
572
|
+
return this.client.rest.post<HostedToolExecutionResult>(
|
|
573
|
+
'/v1/creative-agent/tools/execute',
|
|
574
|
+
{
|
|
575
|
+
tool: params.tool,
|
|
576
|
+
arguments: params.arguments,
|
|
577
|
+
app_source: params.app_source ?? params.appSource ?? this.client.appSource,
|
|
578
|
+
token_type: params.token_type ?? params.tokenType,
|
|
579
|
+
...(params.safe_content_filter !== undefined || params.safeContentFilter !== undefined
|
|
580
|
+
? { safe_content_filter: params.safe_content_filter ?? params.safeContentFilter }
|
|
581
|
+
: {})
|
|
582
|
+
},
|
|
583
|
+
{ timeoutMs: 300000 }
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
|
|
562
587
|
private async chatRunFetch(path: string, options: RequestInit = {}): Promise<Response> {
|
|
563
588
|
const url = new URL(path, this.client.rest.baseUrl).toString();
|
|
564
589
|
const authenticated = await this.client.auth.authenticateRequest(options);
|
|
@@ -793,6 +818,9 @@ class ChatApi extends ApiGroup<ChatApiEvents> {
|
|
|
793
818
|
presence_penalty: params.presence_penalty,
|
|
794
819
|
stop: params.stop,
|
|
795
820
|
tokenType: params.tokenType,
|
|
821
|
+
...(params.safeContentFilter !== undefined
|
|
822
|
+
? { safeContentFilter: params.safeContentFilter }
|
|
823
|
+
: {}),
|
|
796
824
|
...(params.billingMode && { billingMode: params.billingMode }),
|
|
797
825
|
tools: params.tools,
|
|
798
826
|
tool_choice: params.tool_choice,
|
package/src/Chat/modelRouting.ts
CHANGED
|
@@ -77,7 +77,9 @@ export const PREFERRED_MODEL_IDS = {
|
|
|
77
77
|
flux2: 'flux2_dev_fp8',
|
|
78
78
|
chromaFlash: 'chroma-v.46-flash_fp8',
|
|
79
79
|
zTurbo: 'z_image_turbo_bf16',
|
|
80
|
-
krea2Turbo: 'krea2_turbo_fp8_scaled'
|
|
80
|
+
krea2Turbo: 'krea2_turbo_fp8_scaled',
|
|
81
|
+
krea2IdentityEdit: 'krea2_identity_edit_v1_2',
|
|
82
|
+
darkBeastKrea2IdentityEdit: 'dark_beast_krea2_identity_edit_v1_2'
|
|
81
83
|
},
|
|
82
84
|
video: {
|
|
83
85
|
t2v: 'ltx23-22b-fp8_t2v_distilled',
|
|
@@ -180,7 +182,16 @@ const EDIT_IMAGE_MODEL_SELECTORS: Record<string, string> = {
|
|
|
180
182
|
),
|
|
181
183
|
'qwen-lightning': 'qwen_image_edit_2511_fp8_lightning',
|
|
182
184
|
qwen: 'qwen_image_edit_2511_fp8',
|
|
183
|
-
flux2: PREFERRED_MODEL_IDS.image.flux2
|
|
185
|
+
flux2: PREFERRED_MODEL_IDS.image.flux2,
|
|
186
|
+
'krea-2-identity-edit': PREFERRED_MODEL_IDS.image.krea2IdentityEdit,
|
|
187
|
+
'krea2-identity-edit': PREFERRED_MODEL_IDS.image.krea2IdentityEdit,
|
|
188
|
+
'krea-identity-edit': PREFERRED_MODEL_IDS.image.krea2IdentityEdit,
|
|
189
|
+
'krea-2-identity-edit-lora': PREFERRED_MODEL_IDS.image.krea2IdentityEdit,
|
|
190
|
+
'krea-2-identity-edit-lora-v1-2': PREFERRED_MODEL_IDS.image.krea2IdentityEdit,
|
|
191
|
+
'dark-beast-krea-2-identity-edit': PREFERRED_MODEL_IDS.image.darkBeastKrea2IdentityEdit,
|
|
192
|
+
'dark-beast-krea2-identity-edit': PREFERRED_MODEL_IDS.image.darkBeastKrea2IdentityEdit,
|
|
193
|
+
'dark-beast-krea-2-identity-edit-lora': PREFERRED_MODEL_IDS.image.darkBeastKrea2IdentityEdit,
|
|
194
|
+
'dark-beast-krea-2-identity-edit-lora-v1-2': PREFERRED_MODEL_IDS.image.darkBeastKrea2IdentityEdit
|
|
184
195
|
};
|
|
185
196
|
|
|
186
197
|
const TEXT_VIDEO_MODEL_SELECTORS: Record<string, string> = {
|
|
@@ -383,6 +394,8 @@ export function isEditImageModel(modelId: string): boolean {
|
|
|
383
394
|
return (
|
|
384
395
|
modelId === PREFERRED_MODEL_IDS.image.gptImage2 ||
|
|
385
396
|
modelId.startsWith('qwen_image_edit_') ||
|
|
397
|
+
modelId === PREFERRED_MODEL_IDS.image.krea2IdentityEdit ||
|
|
398
|
+
modelId === PREFERRED_MODEL_IDS.image.darkBeastKrea2IdentityEdit ||
|
|
386
399
|
modelId.startsWith('flux2_') ||
|
|
387
400
|
modelId.includes('kontext')
|
|
388
401
|
);
|
package/src/Chat/types.ts
CHANGED
|
@@ -108,6 +108,12 @@ export interface ChatCompletionParams {
|
|
|
108
108
|
stop?: string | string[];
|
|
109
109
|
/** Token type to use for billing. Defaults to 'sogni'. */
|
|
110
110
|
tokenType?: 'sogni' | 'spark';
|
|
111
|
+
/**
|
|
112
|
+
* Whether the caller wants Sogni's safe-content filter applied for this
|
|
113
|
+
* request context. `false` allows backend routing to adult-capable text LLMs
|
|
114
|
+
* for prompt expansion when the request itself is text-only.
|
|
115
|
+
*/
|
|
116
|
+
safeContentFilter?: boolean;
|
|
111
117
|
/**
|
|
112
118
|
* Billing mode for this request. `'subscription'` bills the job against the
|
|
113
119
|
* active subscription entitlement, `'tokens'` forces token billing, and
|
|
@@ -192,6 +198,8 @@ export interface ChatRequestMessage {
|
|
|
192
198
|
presence_penalty?: number;
|
|
193
199
|
stop?: string | string[];
|
|
194
200
|
tokenType?: 'sogni' | 'spark';
|
|
201
|
+
/** Safe-content filter state forwarded to the socket server. */
|
|
202
|
+
safeContentFilter?: boolean;
|
|
195
203
|
/** Billing mode read by the socket server (`data.billingMode`) — see {@link ChatCompletionParams.billingMode}. */
|
|
196
204
|
billingMode?: BillingMode;
|
|
197
205
|
tools?: ToolDefinition[];
|
|
@@ -270,6 +278,43 @@ export interface HostedChatCompletionResult {
|
|
|
270
278
|
sogni_tool_results?: Record<string, unknown>[];
|
|
271
279
|
}
|
|
272
280
|
|
|
281
|
+
export type HostedSynchronousToolName =
|
|
282
|
+
| 'enhance_prompt'
|
|
283
|
+
| 'compose_script'
|
|
284
|
+
| 'compose_lyrics'
|
|
285
|
+
| 'compose_instrumental'
|
|
286
|
+
| 'compose_workflow'
|
|
287
|
+
| 'compose_workflow_template';
|
|
288
|
+
|
|
289
|
+
export interface HostedToolExecutionParams {
|
|
290
|
+
/** Synchronous hosted composition/planning tool to execute directly. */
|
|
291
|
+
tool: HostedSynchronousToolName | string;
|
|
292
|
+
/** Exact JSON arguments for the selected tool. */
|
|
293
|
+
arguments: Record<string, unknown>;
|
|
294
|
+
/** Optional source label for this hosted REST request. Defaults to the client appSource when configured. */
|
|
295
|
+
app_source?: string;
|
|
296
|
+
/** camelCase alias for {@link HostedToolExecutionParams.app_source}. */
|
|
297
|
+
appSource?: string;
|
|
298
|
+
/** Token type to use for hosted REST billing. */
|
|
299
|
+
token_type?: 'sogni' | 'spark' | 'auto';
|
|
300
|
+
/** camelCase alias for {@link HostedToolExecutionParams.token_type}. */
|
|
301
|
+
tokenType?: 'sogni' | 'spark' | 'auto';
|
|
302
|
+
/** Public snake_case safe-content filter state. */
|
|
303
|
+
safe_content_filter?: boolean;
|
|
304
|
+
/** camelCase alias for {@link HostedToolExecutionParams.safe_content_filter}. */
|
|
305
|
+
safeContentFilter?: boolean;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export interface HostedToolExecutionResult {
|
|
309
|
+
status: 'success';
|
|
310
|
+
data: {
|
|
311
|
+
toolCallId: string;
|
|
312
|
+
tool: string;
|
|
313
|
+
result: Record<string, unknown>;
|
|
314
|
+
message: string | null;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
273
318
|
export type HostedChatCompletionParams = Omit<
|
|
274
319
|
ChatCompletionParams,
|
|
275
320
|
'stream' | 'autoExecuteTools' | 'onToolCall' | 'onToolProgress' | 'maxToolRounds'
|
|
@@ -292,6 +337,10 @@ export type HostedChatCompletionParams = Omit<
|
|
|
292
337
|
mediaReferences?: unknown[];
|
|
293
338
|
api_media_references?: unknown[];
|
|
294
339
|
apiMediaReferences?: unknown[];
|
|
340
|
+
/** Public snake_case safe-content filter state. */
|
|
341
|
+
safe_content_filter?: boolean;
|
|
342
|
+
/** camelCase alias for {@link HostedChatCompletionParams.safe_content_filter}. */
|
|
343
|
+
safeContentFilter?: boolean;
|
|
295
344
|
};
|
|
296
345
|
|
|
297
346
|
/**
|
|
@@ -21,7 +21,8 @@ import {
|
|
|
21
21
|
isComfyModel,
|
|
22
22
|
validateVideoDuration,
|
|
23
23
|
validateSampler,
|
|
24
|
-
validateScheduler
|
|
24
|
+
validateScheduler,
|
|
25
|
+
validateVae
|
|
25
26
|
} from '../lib/validation.js';
|
|
26
27
|
import {
|
|
27
28
|
getVideoWorkflowType,
|
|
@@ -420,6 +421,7 @@ function applyImageParams(
|
|
|
420
421
|
// ComfyUI models use comfySampler/comfyScheduler fields
|
|
421
422
|
keyFrame.comfySampler = validateSampler(params.sampler, options);
|
|
422
423
|
keyFrame.comfyScheduler = validateScheduler(params.scheduler, options);
|
|
424
|
+
keyFrame.vae = validateVae(params.vae, options);
|
|
423
425
|
} else {
|
|
424
426
|
// Legacy Forge models use scheduler/timeStepSpacing fields
|
|
425
427
|
keyFrame.scheduler = validateSampler(params.sampler, options);
|
package/src/Projects/index.ts
CHANGED
|
@@ -287,7 +287,8 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
287
287
|
workerName: data.workerName,
|
|
288
288
|
positivePrompt: data.positivePrompt,
|
|
289
289
|
negativePrompt: data.negativePrompt,
|
|
290
|
-
jobIndex: data.jobIndex
|
|
290
|
+
jobIndex: data.jobIndex,
|
|
291
|
+
preparation: data.preparation
|
|
291
292
|
});
|
|
292
293
|
return;
|
|
293
294
|
case 'jobStarted': {
|
|
@@ -698,7 +699,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
698
699
|
await this.uploadCNImage(project.id, data.controlNet.image);
|
|
699
700
|
}
|
|
700
701
|
|
|
701
|
-
// Context images (GPT Image 2 supports up to 16; Flux.2 Dev supports up to 6; Qwen Image Edit
|
|
702
|
+
// Context images (GPT Image 2 supports up to 16; Flux.2 Dev supports up to 6; Qwen Image Edit supports up to 3; Krea 2 Identity Edit and Flux Kontext support up to 2)
|
|
702
703
|
if (data.contextImages?.length) {
|
|
703
704
|
const maxContextImages = getMaxContextImages(data.modelId);
|
|
704
705
|
if (data.contextImages.length > maxContextImages) {
|
|
@@ -31,6 +31,7 @@ export interface ImageModelOptions {
|
|
|
31
31
|
guidance: NumRange;
|
|
32
32
|
scheduler: Options<string>;
|
|
33
33
|
sampler: Options<string>;
|
|
34
|
+
vae?: Options<string>;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export interface VideoModelOptions {
|
|
@@ -99,7 +100,8 @@ export function mapComfyImageTier(tier: ComfyImageTier): ImageModelOptions {
|
|
|
99
100
|
steps: mapRange(tier.steps),
|
|
100
101
|
guidance: mapRange(tier.guidance),
|
|
101
102
|
scheduler: mapOptions(tier.comfyScheduler, schedulerValueToAlias),
|
|
102
|
-
sampler: mapOptions(tier.comfySampler, samplerValueToAlias)
|
|
103
|
+
sampler: mapOptions(tier.comfySampler, samplerValueToAlias),
|
|
104
|
+
vae: tier.vae ? mapOptions(tier.vae) : undefined
|
|
103
105
|
};
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { AvailableModel } from './index.js';
|
|
2
2
|
import ErrorData from '../../types/ErrorData.js';
|
|
3
|
+
import type { JobPreparation } from '../../ApiClient/WebSocketClient/events.js';
|
|
4
|
+
|
|
5
|
+
export type { JobPreparation } from '../../ApiClient/WebSocketClient/events.js';
|
|
3
6
|
|
|
4
7
|
export interface ProjectEventBase {
|
|
5
8
|
projectId: string;
|
|
@@ -32,6 +35,7 @@ export interface JobInitiating extends JobEventBase {
|
|
|
32
35
|
positivePrompt?: string;
|
|
33
36
|
negativePrompt?: string;
|
|
34
37
|
jobIndex?: number;
|
|
38
|
+
preparation?: JobPreparation;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
export interface JobStarted extends JobEventBase {
|
|
@@ -100,17 +100,31 @@ export interface BaseProjectParams {
|
|
|
100
100
|
*/
|
|
101
101
|
appSource?: string;
|
|
102
102
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
103
|
+
* LoRA IDs to apply, in the order they should be chained.
|
|
104
|
+
*
|
|
105
|
+
* Which LoRAs are available depends on the model; the Krea 2 family carries
|
|
106
|
+
* the largest set. Workers download a LoRA on first use, so the first render
|
|
107
|
+
* with an uncached one takes longer to start.
|
|
108
|
+
*
|
|
109
|
+
* Order is significant. The LoRAs are applied in sequence and the same set in
|
|
110
|
+
* a different order produces a measurably different image, because these
|
|
111
|
+
* models run fp8-quantized and the patches do not commute.
|
|
112
|
+
*
|
|
113
|
+
* Up to 8 per render. IDs are resolved to filenames by the worker.
|
|
114
|
+
* Example: ['krea2-detail-enhancer', 'krea2-amateur']
|
|
108
115
|
*/
|
|
109
116
|
loras?: string[];
|
|
110
117
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
118
|
+
* Strength for each entry in `loras`, positionally matched. Defaults to 1.0.
|
|
119
|
+
*
|
|
120
|
+
* Not restricted to positive values. Most Krea 2 LoRAs are bipolar sliders
|
|
121
|
+
* where a negative strength applies the inverse effect and 0 does nothing -
|
|
122
|
+
* Warm Light warms at 2 and cools at -2. Each LoRA has its own valid range
|
|
123
|
+
* and its author's recommended band; values outside the valid range are
|
|
124
|
+
* clamped server-side, and pushing past the recommended band usually costs
|
|
125
|
+
* detail rather than adding effect.
|
|
126
|
+
*
|
|
127
|
+
* Example: [3, -2]
|
|
114
128
|
*/
|
|
115
129
|
loraStrengths?: number[];
|
|
116
130
|
}
|
|
@@ -378,7 +392,8 @@ export interface ImageProjectParams extends BaseProjectParams {
|
|
|
378
392
|
* Context images for multi-reference image generation.
|
|
379
393
|
* GPT Image 2 supports up to 16 context images.
|
|
380
394
|
* Flux.2 Dev supports up to 6 context images.
|
|
381
|
-
* Qwen Image Edit
|
|
395
|
+
* Qwen Image Edit supports up to 3 context images.
|
|
396
|
+
* Krea 2 Identity Edit supports up to 2 context images.
|
|
382
397
|
* Flux Kontext supports up to 2 context images.
|
|
383
398
|
*/
|
|
384
399
|
contextImages?: InputMedia[];
|
|
@@ -392,6 +407,11 @@ export interface ImageProjectParams extends BaseProjectParams {
|
|
|
392
407
|
* to get the list of available schedulers.
|
|
393
408
|
*/
|
|
394
409
|
scheduler?: string;
|
|
410
|
+
/**
|
|
411
|
+
* VAE filename, available options depend on the model. Use `sogni.projects.getModelOptions(modelId)`
|
|
412
|
+
* to get the list of available VAEs.
|
|
413
|
+
*/
|
|
414
|
+
vae?: string;
|
|
395
415
|
/**
|
|
396
416
|
* Size preset ID to use. You can query available size presets
|
|
397
417
|
* from `sogni.projects.sizePresets(network, modelId)`
|
package/src/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
CostEstimation,
|
|
43
43
|
InputMedia
|
|
44
44
|
} from './Projects/types/index.js';
|
|
45
|
-
import type { ProjectEvent, JobEvent } from './Projects/types/events.js';
|
|
45
|
+
import type { ProjectEvent, JobEvent, JobPreparation } from './Projects/types/events.js';
|
|
46
46
|
import type { RawProject } from './Projects/types/RawProject.js';
|
|
47
47
|
import type { Balances, Reward, TxHistoryEntry } from './Account/types.js';
|
|
48
48
|
import type {
|
|
@@ -92,6 +92,9 @@ import {
|
|
|
92
92
|
HostedChatCompletionChoice,
|
|
93
93
|
HostedChatCompletionMessage,
|
|
94
94
|
HostedCreativeWorkflowReference,
|
|
95
|
+
HostedSynchronousToolName,
|
|
96
|
+
HostedToolExecutionParams,
|
|
97
|
+
HostedToolExecutionResult,
|
|
95
98
|
TextContentPart,
|
|
96
99
|
ImageUrlContentPart,
|
|
97
100
|
TokenUsage as ChatTokenUsage,
|
|
@@ -199,6 +202,9 @@ export type {
|
|
|
199
202
|
HostedChatCompletionParams,
|
|
200
203
|
HostedChatCompletionResult,
|
|
201
204
|
HostedCreativeWorkflowReference,
|
|
205
|
+
HostedSynchronousToolName,
|
|
206
|
+
HostedToolExecutionParams,
|
|
207
|
+
HostedToolExecutionResult,
|
|
202
208
|
CreativeWorkflowArtifact,
|
|
203
209
|
CreativeWorkflowEvent,
|
|
204
210
|
CreativeWorkflowRecord,
|
|
@@ -303,6 +309,7 @@ export type {
|
|
|
303
309
|
CostEstimation,
|
|
304
310
|
ProjectEvent,
|
|
305
311
|
JobEvent,
|
|
312
|
+
JobPreparation,
|
|
306
313
|
RawProject,
|
|
307
314
|
ToastMessage,
|
|
308
315
|
DataEntity,
|
package/src/lib/validation.ts
CHANGED
|
@@ -12,28 +12,37 @@ const EXTENDED_IMAGE_SIZE_MODEL_IDS = new Set([
|
|
|
12
12
|
'flux2_dev_fp8'
|
|
13
13
|
]);
|
|
14
14
|
|
|
15
|
+
const KREA_IDENTITY_EDIT_MODEL_IDS = new Set([
|
|
16
|
+
'krea2_identity_edit_v1_2',
|
|
17
|
+
'dark_beast_krea2_identity_edit_v1_2'
|
|
18
|
+
]);
|
|
19
|
+
|
|
15
20
|
interface ImageSizeValidationOptions {
|
|
16
21
|
modelId?: string;
|
|
17
22
|
propertyName?: string;
|
|
18
23
|
}
|
|
19
24
|
|
|
20
|
-
function
|
|
25
|
+
function getCustomImageSizeBounds(modelId?: string): { min: number; max: number } {
|
|
26
|
+
if (modelId && KREA_IDENTITY_EDIT_MODEL_IDS.has(modelId)) {
|
|
27
|
+
return { min: 512, max: 2048 };
|
|
28
|
+
}
|
|
21
29
|
if (modelId === 'gpt-image-2') {
|
|
22
|
-
return 3840;
|
|
30
|
+
return { min: 256, max: 3840 };
|
|
23
31
|
}
|
|
24
32
|
if (modelId && EXTENDED_IMAGE_SIZE_MODEL_IDS.has(modelId)) {
|
|
25
|
-
return 2560;
|
|
33
|
+
return { min: 256, max: 2560 };
|
|
26
34
|
}
|
|
27
|
-
return 2048;
|
|
35
|
+
return { min: 256, max: 2048 };
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
export function validateCustomImageSize(
|
|
31
39
|
value: any,
|
|
32
40
|
{ modelId, propertyName = 'Width and height' }: ImageSizeValidationOptions = {}
|
|
33
41
|
): number {
|
|
42
|
+
const bounds = getCustomImageSizeBounds(modelId);
|
|
34
43
|
return validateNumber(value, {
|
|
35
|
-
min:
|
|
36
|
-
max:
|
|
44
|
+
min: bounds.min,
|
|
45
|
+
max: bounds.max,
|
|
37
46
|
propertyName
|
|
38
47
|
});
|
|
39
48
|
}
|
|
@@ -106,7 +115,16 @@ export function validateTeacacheThreshold(value?: number): number | undefined {
|
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
export function isComfyModel(modelId: string): boolean {
|
|
109
|
-
const COMFY_PREFIXES = [
|
|
118
|
+
const COMFY_PREFIXES = [
|
|
119
|
+
'z_image_',
|
|
120
|
+
'dark_beast_z_image_',
|
|
121
|
+
'krea2_',
|
|
122
|
+
'dark_beast_krea2_',
|
|
123
|
+
'qwen_image_',
|
|
124
|
+
'flux2_',
|
|
125
|
+
'wan_',
|
|
126
|
+
'ace_step'
|
|
127
|
+
];
|
|
110
128
|
return COMFY_PREFIXES.some((prefix) => modelId.startsWith(prefix));
|
|
111
129
|
}
|
|
112
130
|
|
|
@@ -115,6 +133,7 @@ export function isComfyModel(modelId: string): boolean {
|
|
|
115
133
|
* - GPT Image 2: 16 images
|
|
116
134
|
* - Flux.2 Dev: 6 images
|
|
117
135
|
* - Qwen Image Edit: 3 images
|
|
136
|
+
* - Krea 2 Identity Edit: 2 images
|
|
118
137
|
* - Flux Kontext: 2 images
|
|
119
138
|
* - Default: 3 images
|
|
120
139
|
*/
|
|
@@ -128,6 +147,9 @@ export function getMaxContextImages(modelId: string): number {
|
|
|
128
147
|
if (modelId.startsWith('qwen_image_')) {
|
|
129
148
|
return 3;
|
|
130
149
|
}
|
|
150
|
+
if (KREA_IDENTITY_EDIT_MODEL_IDS.has(modelId)) {
|
|
151
|
+
return 2;
|
|
152
|
+
}
|
|
131
153
|
if (modelId.includes('kontext')) {
|
|
132
154
|
return 2;
|
|
133
155
|
}
|
|
@@ -175,3 +197,18 @@ export function validateScheduler(value: string | undefined, options: ModelOptio
|
|
|
175
197
|
`Invalid scheduler ${value}. Must be one of "${options.scheduler.allowed.join('", "')}".`
|
|
176
198
|
);
|
|
177
199
|
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Validate a model-specific VAE value against allowed options.
|
|
203
|
+
* Returns the validated value unchanged; sogni-socket passes the filename to ComfyUI.
|
|
204
|
+
*/
|
|
205
|
+
export function validateVae(value: string | undefined, options: ModelOptions) {
|
|
206
|
+
if (!('vae' in options) || !options.vae?.allowed.length || !value) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return validateOption(
|
|
210
|
+
value,
|
|
211
|
+
options.vae.allowed,
|
|
212
|
+
`Invalid VAE ${value}. Must be one of "${options.vae.allowed.join('", "')}".`
|
|
213
|
+
);
|
|
214
|
+
}
|
package/src/version.ts
CHANGED