@sogni-ai/sogni-client 5.63.2 → 5.63.4
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 +14 -0
- package/README.md +5 -2
- package/dist/Projects/index.d.ts +2 -0
- package/dist/Projects/index.js +26 -60
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/utils/fileContentType.d.ts +18 -0
- package/dist/Projects/utils/fileContentType.js +63 -0
- package/dist/Projects/utils/fileContentType.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-esm/Projects/index.js +16 -50
- package/dist-esm/Projects/index.js.map +1 -1
- package/dist-esm/Projects/utils/fileContentType.js +60 -0
- package/dist-esm/Projects/utils/fileContentType.js.map +1 -0
- package/dist-esm/version.js +1 -1
- package/package.json +2 -1
- package/src/Projects/index.ts +18 -44
- package/src/Projects/utils/fileContentType.ts +55 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [5.63.4](https://github.com/Sogni-AI/sogni-client/compare/v5.63.3...v5.63.4) (2026-10-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **projects:** start admission grace after request preparation ([2d9d99a](https://github.com/Sogni-AI/sogni-client/commit/2d9d99accdce4c897331b6a5ceefe05e3ec46c52))
|
|
7
|
+
|
|
8
|
+
## [5.63.3](https://github.com/Sogni-AI/sogni-client/compare/v5.63.2...v5.63.3) (2026-10-14)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **projects:** declare FLAC, Ogg and WebM reference files by their bytes ([4b03ac8](https://github.com/Sogni-AI/sogni-client/commit/4b03ac80ca792746fdfc69a60833cff9cf054702))
|
|
14
|
+
|
|
1
15
|
## [5.63.2](https://github.com/Sogni-AI/sogni-client/compare/v5.63.1...v5.63.2) (2026-10-12)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -1524,8 +1524,11 @@ const workflow = await sogni.workflows.start({
|
|
|
1524
1524
|
}
|
|
1525
1525
|
},
|
|
1526
1526
|
{
|
|
1527
|
+
// animate_photo starts the clip from the keyframe. generate_video's
|
|
1528
|
+
// referenceImageIndices are loose references, which only Seedance,
|
|
1529
|
+
// HappyHorse, Wan 3 and MiniMax H3 reference-to-video accept.
|
|
1527
1530
|
id: 'clip',
|
|
1528
|
-
toolName: '
|
|
1531
|
+
toolName: 'animate_photo',
|
|
1529
1532
|
arguments: {
|
|
1530
1533
|
prompt: 'slow dolly-in, warm stage lights, subtle hand motion',
|
|
1531
1534
|
videoModel: 'ltx23',
|
|
@@ -1535,7 +1538,7 @@ const workflow = await sogni.workflows.start({
|
|
|
1535
1538
|
{
|
|
1536
1539
|
sourceStepId: 'keyframe',
|
|
1537
1540
|
sourceArtifactIndex: 0,
|
|
1538
|
-
targetArgument: '
|
|
1541
|
+
targetArgument: 'sourceImageIndex',
|
|
1539
1542
|
mediaType: 'image',
|
|
1540
1543
|
transform: 'image_index',
|
|
1541
1544
|
required: true
|
package/dist/Projects/index.d.ts
CHANGED
|
@@ -170,6 +170,8 @@ declare class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
170
170
|
/** Projects waiting for a reconnect to be resubmitted on. */
|
|
171
171
|
private _awaitingResubmit;
|
|
172
172
|
private _resubmitWaiters;
|
|
173
|
+
/** Initial sends finish after model lookups and uploads, independently of creation time. */
|
|
174
|
+
private _submittedAt;
|
|
173
175
|
/** When each resubmitted project was last sent, for the recently-created grace. */
|
|
174
176
|
private _resubmittedAt;
|
|
175
177
|
/** Bumped on every transport loss; tells a frame sent before a drop from one sent after. */
|
package/dist/Projects/index.js
CHANGED
|
@@ -58,6 +58,7 @@ const getUUID_js_1 = __importDefault(require("../lib/getUUID.js"));
|
|
|
58
58
|
const Cache_js_1 = __importDefault(require("../lib/Cache.js"));
|
|
59
59
|
const Job_js_1 = require("./Job.js");
|
|
60
60
|
const index_js_2 = require("./utils/index.js");
|
|
61
|
+
const fileContentType_js_1 = require("./utils/fileContentType.js");
|
|
61
62
|
const validation_js_1 = require("../lib/validation.js");
|
|
62
63
|
const ModelTiersRaw_js_1 = require("./types/ModelTiersRaw.js");
|
|
63
64
|
const ModelOptions_js_1 = require("./types/ModelOptions.js");
|
|
@@ -186,46 +187,6 @@ function deriveLoraCapableModelIds(loras) {
|
|
|
186
187
|
}
|
|
187
188
|
return Array.from(modelIds).sort();
|
|
188
189
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Detect content type from a file object.
|
|
191
|
-
* For File objects in browser, uses the type property.
|
|
192
|
-
* Returns undefined if content type cannot be detected.
|
|
193
|
-
*/
|
|
194
|
-
function getFileContentType(file) {
|
|
195
|
-
if (file instanceof Blob && 'type' in file && file.type) {
|
|
196
|
-
return file.type;
|
|
197
|
-
}
|
|
198
|
-
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(file)) {
|
|
199
|
-
if (file.length >= 12) {
|
|
200
|
-
if (file[0] === 0xff && file[1] === 0xd8 && file[2] === 0xff)
|
|
201
|
-
return 'image/jpeg';
|
|
202
|
-
if (file[0] === 0x89 && file[1] === 0x50 && file[2] === 0x4e && file[3] === 0x47) {
|
|
203
|
-
return 'image/png';
|
|
204
|
-
}
|
|
205
|
-
if (file.toString('ascii', 0, 4) === 'RIFF' && file.toString('ascii', 8, 12) === 'WEBP') {
|
|
206
|
-
return 'image/webp';
|
|
207
|
-
}
|
|
208
|
-
if (file.toString('ascii', 0, 3) === 'GIF')
|
|
209
|
-
return 'image/gif';
|
|
210
|
-
if (file.toString('ascii', 4, 8) === 'ftyp') {
|
|
211
|
-
const brand = file.toString('ascii', 8, 12).toLowerCase();
|
|
212
|
-
if (brand.includes('m4a') || brand.includes('m4b'))
|
|
213
|
-
return 'audio/mp4';
|
|
214
|
-
if (brand.includes('qt'))
|
|
215
|
-
return 'video/quicktime';
|
|
216
|
-
return 'video/mp4';
|
|
217
|
-
}
|
|
218
|
-
if (file.toString('ascii', 0, 4) === 'RIFF' && file.toString('ascii', 8, 12) === 'WAVE') {
|
|
219
|
-
return 'audio/wav';
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (file.length >= 3 && file.toString('ascii', 0, 3) === 'ID3')
|
|
223
|
-
return 'audio/mpeg';
|
|
224
|
-
if (file.length >= 2 && file[0] === 0xff && (file[1] & 0xe0) === 0xe0)
|
|
225
|
-
return 'audio/mpeg';
|
|
226
|
-
}
|
|
227
|
-
return undefined;
|
|
228
|
-
}
|
|
229
190
|
/**
|
|
230
191
|
* Convert file to a format compatible with fetch body.
|
|
231
192
|
* Converts Node.js Buffer to Blob for cross-platform compatibility.
|
|
@@ -483,6 +444,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
483
444
|
/** Projects waiting for a reconnect to be resubmitted on. */
|
|
484
445
|
this._awaitingResubmit = new Set();
|
|
485
446
|
this._resubmitWaiters = new Set();
|
|
447
|
+
/** Initial sends finish after model lookups and uploads, independently of creation time. */
|
|
448
|
+
this._submittedAt = new Map();
|
|
486
449
|
/** When each resubmitted project was last sent, for the recently-created grace. */
|
|
487
450
|
this._resubmittedAt = new Map();
|
|
488
451
|
/** Bumped on every transport loss; tells a frame sent before a drop from one sent after. */
|
|
@@ -565,6 +528,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
565
528
|
for (const stopWaiting of this._resubmitWaiters)
|
|
566
529
|
stopWaiting();
|
|
567
530
|
this._awaitingResubmit.clear();
|
|
531
|
+
this._submittedAt.clear();
|
|
568
532
|
this._resubmittedAt.clear();
|
|
569
533
|
this._sentOnGeneration.clear();
|
|
570
534
|
this._recoveredCompletedIds.clear();
|
|
@@ -999,6 +963,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
999
963
|
}
|
|
1000
964
|
if (project.finished) {
|
|
1001
965
|
this._unadmittedRequests.delete(project.id);
|
|
966
|
+
this._submittedAt.delete(project.id);
|
|
1002
967
|
this._resubmittedAt.delete(project.id);
|
|
1003
968
|
this._sentOnGeneration.delete(project.id);
|
|
1004
969
|
// Sync project data with the server and remove it from the list after some time
|
|
@@ -1286,8 +1251,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1286
1251
|
}, Math.max(0, delayMs) + 250);
|
|
1287
1252
|
}
|
|
1288
1253
|
_lastSubmittedAt(project) {
|
|
1289
|
-
var _a;
|
|
1290
|
-
return Math.max(project.startedAt.getTime(), (
|
|
1254
|
+
var _a, _b;
|
|
1255
|
+
return Math.max((_a = this._submittedAt.get(project.id)) !== null && _a !== void 0 ? _a : project.startedAt.getTime(), (_b = this._resubmittedAt.get(project.id)) !== null && _b !== void 0 ? _b : 0);
|
|
1291
1256
|
}
|
|
1292
1257
|
handleServerConnected() {
|
|
1293
1258
|
this.transportDisconnected = false;
|
|
@@ -2007,6 +1972,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2007
1972
|
_trackSubmitted(project) {
|
|
2008
1973
|
const tracked = this.projects.find((candidate) => candidate.id === project.id);
|
|
2009
1974
|
if (!tracked) {
|
|
1975
|
+
this._submittedAt.set(project.id, Date.now());
|
|
2010
1976
|
this.projects.push(project);
|
|
2011
1977
|
return project;
|
|
2012
1978
|
}
|
|
@@ -2066,7 +2032,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2066
2032
|
if (!keyFrame)
|
|
2067
2033
|
return;
|
|
2068
2034
|
if (data.referenceAudio && data.referenceAudio !== true) {
|
|
2069
|
-
keyFrame.referenceAudioContentType = getFileContentType(data.referenceAudio);
|
|
2035
|
+
keyFrame.referenceAudioContentType = (0, fileContentType_js_1.getFileContentType)(data.referenceAudio, 'audio');
|
|
2070
2036
|
}
|
|
2071
2037
|
}
|
|
2072
2038
|
_processVideoAssets(project, data) {
|
|
@@ -2123,37 +2089,37 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2123
2089
|
if (!keyFrame)
|
|
2124
2090
|
return;
|
|
2125
2091
|
if (data.referenceImage && data.referenceImage !== true) {
|
|
2126
|
-
keyFrame.referenceImageContentType = getFileContentType(data.referenceImage);
|
|
2092
|
+
keyFrame.referenceImageContentType = (0, fileContentType_js_1.getFileContentType)(data.referenceImage);
|
|
2127
2093
|
}
|
|
2128
2094
|
if (data.referenceImageEnd && data.referenceImageEnd !== true) {
|
|
2129
|
-
keyFrame.referenceImageEndContentType = getFileContentType(data.referenceImageEnd);
|
|
2095
|
+
keyFrame.referenceImageEndContentType = (0, fileContentType_js_1.getFileContentType)(data.referenceImageEnd);
|
|
2130
2096
|
}
|
|
2131
2097
|
const isMinimaxH3R2v = (0, index_js_2.isMinimaxH3ReferenceModel)(data.modelId);
|
|
2132
2098
|
if (!isMinimaxH3R2v && data.referenceAudio && data.referenceAudio !== true) {
|
|
2133
|
-
keyFrame.referenceAudioContentType = getFileContentType(data.referenceAudio);
|
|
2099
|
+
keyFrame.referenceAudioContentType = (0, fileContentType_js_1.getFileContentType)(data.referenceAudio, 'audio');
|
|
2134
2100
|
}
|
|
2135
2101
|
if (data.referenceAudioIdentity && data.referenceAudioIdentity !== true) {
|
|
2136
|
-
const contentType = getFileContentType(data.referenceAudioIdentity);
|
|
2102
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(data.referenceAudioIdentity, 'audio');
|
|
2137
2103
|
keyFrame.referenceAudioIdentityContentType = contentType;
|
|
2138
2104
|
(_b = keyFrame.referenceAudioContentType) !== null && _b !== void 0 ? _b : (keyFrame.referenceAudioContentType = contentType);
|
|
2139
2105
|
}
|
|
2140
2106
|
if (!isMinimaxH3R2v && data.referenceVideo && data.referenceVideo !== true) {
|
|
2141
|
-
keyFrame.referenceVideoContentType = getFileContentType(data.referenceVideo);
|
|
2107
|
+
keyFrame.referenceVideoContentType = (0, fileContentType_js_1.getFileContentType)(data.referenceVideo, 'video');
|
|
2142
2108
|
}
|
|
2143
2109
|
if (isMinimaxH3R2v) {
|
|
2144
2110
|
for (const { slot, media } of (0, index_js_2.getMinimaxH3ReferenceAudioSlots)(data)) {
|
|
2145
2111
|
if (typeof media !== 'boolean') {
|
|
2146
|
-
keyFrame[`referenceAudio${slot}ContentType`] = getFileContentType(media);
|
|
2112
|
+
keyFrame[`referenceAudio${slot}ContentType`] = (0, fileContentType_js_1.getFileContentType)(media, 'audio');
|
|
2147
2113
|
}
|
|
2148
2114
|
}
|
|
2149
2115
|
for (const { slot, media } of (0, index_js_2.getMinimaxH3ReferenceVideoSlots)(data)) {
|
|
2150
2116
|
if (typeof media !== 'boolean') {
|
|
2151
|
-
keyFrame[`referenceVideo${slot}ContentType`] = getFileContentType(media);
|
|
2117
|
+
keyFrame[`referenceVideo${slot}ContentType`] = (0, fileContentType_js_1.getFileContentType)(media, 'video');
|
|
2152
2118
|
}
|
|
2153
2119
|
}
|
|
2154
2120
|
}
|
|
2155
2121
|
if (data.referenceMask && data.referenceMask !== true && (0, index_js_2.usesReferenceMask)(data)) {
|
|
2156
|
-
keyFrame.referenceMaskContentType = getFileContentType(data.referenceMask);
|
|
2122
|
+
keyFrame.referenceMaskContentType = (0, fileContentType_js_1.getFileContentType)(data.referenceMask);
|
|
2157
2123
|
}
|
|
2158
2124
|
}
|
|
2159
2125
|
/**
|
|
@@ -2491,7 +2457,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2491
2457
|
const imageId = (0, getUUID_js_1.default)();
|
|
2492
2458
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2493
2459
|
assertSession();
|
|
2494
|
-
const contentType = getFileContentType(file);
|
|
2460
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2495
2461
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'startingImage' }))
|
|
2496
2462
|
return imageId;
|
|
2497
2463
|
assertSession();
|
|
@@ -2527,7 +2493,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2527
2493
|
const imageId = (0, getUUID_js_1.default)();
|
|
2528
2494
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2529
2495
|
assertSession();
|
|
2530
|
-
const contentType = getFileContentType(file);
|
|
2496
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2531
2497
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'cnImage' }))
|
|
2532
2498
|
return imageId;
|
|
2533
2499
|
assertSession();
|
|
@@ -2564,7 +2530,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2564
2530
|
const imageIndex = (index + 1);
|
|
2565
2531
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2566
2532
|
assertSession();
|
|
2567
|
-
const contentType = getFileContentType(file);
|
|
2533
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2568
2534
|
if (yield this.assets.tryBindFile(file, contentType, {
|
|
2569
2535
|
projectId,
|
|
2570
2536
|
type: `contextImage${imageIndex}`
|
|
@@ -2610,7 +2576,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2610
2576
|
const type = `keyframeImage${slot}`;
|
|
2611
2577
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2612
2578
|
assertSession();
|
|
2613
|
-
const contentType = getFileContentType(file);
|
|
2579
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2614
2580
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type }))
|
|
2615
2581
|
return imageId;
|
|
2616
2582
|
assertSession();
|
|
@@ -2648,7 +2614,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2648
2614
|
const imageId = (0, getUUID_js_1.default)();
|
|
2649
2615
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2650
2616
|
assertSession();
|
|
2651
|
-
const contentType = getFileContentType(file);
|
|
2617
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2652
2618
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceImage' }))
|
|
2653
2619
|
return imageId;
|
|
2654
2620
|
assertSession();
|
|
@@ -2688,7 +2654,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2688
2654
|
const imageId = (0, getUUID_js_1.default)();
|
|
2689
2655
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2690
2656
|
assertSession();
|
|
2691
|
-
const contentType = getFileContentType(file);
|
|
2657
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2692
2658
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceMask' }))
|
|
2693
2659
|
return imageId;
|
|
2694
2660
|
assertSession();
|
|
@@ -2728,7 +2694,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2728
2694
|
const imageId = (0, getUUID_js_1.default)();
|
|
2729
2695
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2730
2696
|
assertSession();
|
|
2731
|
-
const contentType = getFileContentType(file);
|
|
2697
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file);
|
|
2732
2698
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceImageEnd' }))
|
|
2733
2699
|
return imageId;
|
|
2734
2700
|
assertSession();
|
|
@@ -2769,7 +2735,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2769
2735
|
var _a;
|
|
2770
2736
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2771
2737
|
assertSession();
|
|
2772
|
-
const contentType = getFileContentType(file);
|
|
2738
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file, 'audio');
|
|
2773
2739
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceAudio', id }))
|
|
2774
2740
|
return;
|
|
2775
2741
|
assertSession();
|
|
@@ -2809,7 +2775,7 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
2809
2775
|
var _a;
|
|
2810
2776
|
const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : (0, requestSession_js_1.captureRequestSession)(this.client.auth);
|
|
2811
2777
|
assertSession();
|
|
2812
|
-
const contentType = getFileContentType(file);
|
|
2778
|
+
const contentType = (0, fileContentType_js_1.getFileContentType)(file, 'video');
|
|
2813
2779
|
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceVideo', id }))
|
|
2814
2780
|
return;
|
|
2815
2781
|
assertSession();
|