@sogni-ai/sogni-client 3.0.0-alpha.9 → 3.0.1
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 +336 -0
- package/README.md +23 -27
- package/dist/Account/CurrentAccount.d.ts +3 -3
- package/dist/Account/CurrentAccount.js +12 -4
- package/dist/Account/CurrentAccount.js.map +1 -1
- package/dist/Account/index.d.ts +42 -13
- package/dist/Account/index.js +132 -29
- package/dist/Account/index.js.map +1 -1
- package/dist/Account/types.d.ts +21 -0
- package/dist/ApiClient/WebSocketClient/events.d.ts +55 -7
- package/dist/ApiClient/WebSocketClient/index.js +1 -1
- package/dist/ApiClient/index.d.ts +4 -2
- package/dist/ApiClient/index.js +12 -3
- package/dist/ApiClient/index.js.map +1 -1
- package/dist/ApiGroup.d.ts +0 -3
- package/dist/ApiGroup.js +0 -1
- package/dist/ApiGroup.js.map +1 -1
- package/dist/Projects/Job.d.ts +43 -0
- package/dist/Projects/Job.js +76 -0
- package/dist/Projects/Job.js.map +1 -1
- package/dist/Projects/Project.d.ts +1 -1
- package/dist/Projects/Project.js +9 -18
- package/dist/Projects/Project.js.map +1 -1
- package/dist/Projects/createJobRequestMessage.js +1 -1
- package/dist/Projects/createJobRequestMessage.js.map +1 -1
- package/dist/Projects/index.d.ts +7 -2
- package/dist/Projects/index.js +48 -10
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/types/ControlNetParams.d.ts +7 -2
- package/dist/Projects/types/events.d.ts +6 -0
- package/dist/Projects/types/index.d.ts +16 -3
- package/dist/Projects/utils.d.ts +2 -0
- package/dist/Projects/utils.js +14 -0
- package/dist/Projects/utils.js.map +1 -0
- package/dist/index.d.ts +10 -6
- package/dist/index.js +6 -15
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +15 -0
- package/dist/lib/utils.js.map +1 -1
- package/dist/types/token.d.ts +1 -0
- package/dist/types/token.js +3 -0
- package/dist/types/token.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/src/Account/CurrentAccount.ts +14 -6
- package/src/Account/index.ts +163 -59
- package/src/Account/types.ts +26 -0
- package/src/ApiClient/WebSocketClient/events.ts +59 -7
- package/src/ApiClient/WebSocketClient/index.ts +1 -1
- package/src/ApiClient/index.ts +15 -4
- package/src/ApiGroup.ts +0 -4
- package/src/Projects/Job.ts +98 -0
- package/src/Projects/Project.ts +11 -19
- package/src/Projects/createJobRequestMessage.ts +2 -1
- package/src/Projects/index.ts +53 -13
- package/src/Projects/types/ControlNetParams.ts +8 -2
- package/src/Projects/types/events.ts +6 -0
- package/src/Projects/types/index.ts +17 -3
- package/src/Projects/utils.ts +12 -0
- package/src/Stats/index.ts +2 -2
- package/src/index.ts +23 -19
- package/src/lib/utils.ts +4 -0
- package/src/types/token.ts +1 -0
- package/src/version.ts +2 -1
package/src/Projects/Job.ts
CHANGED
|
@@ -4,6 +4,24 @@ import { RawJob, RawProject } from './types/RawProject';
|
|
|
4
4
|
import ProjectsApi from './index';
|
|
5
5
|
import { Logger } from '../lib/DefaultLogger';
|
|
6
6
|
import getUUID from '../lib/getUUID';
|
|
7
|
+
import { EnhancementStrength } from './types';
|
|
8
|
+
import Project from './Project';
|
|
9
|
+
import { SupernetType } from '../ApiClient/WebSocketClient/types';
|
|
10
|
+
import { getEnhacementStrength } from './utils';
|
|
11
|
+
import { TokenType } from '../types/token';
|
|
12
|
+
|
|
13
|
+
export const enhancementDefaults = {
|
|
14
|
+
network: 'fast' as SupernetType,
|
|
15
|
+
modelId: 'flux1-schnell-fp8',
|
|
16
|
+
positivePrompt: '',
|
|
17
|
+
negativePrompt: '',
|
|
18
|
+
stylePrompt: '',
|
|
19
|
+
startingImageStrength: 0.5,
|
|
20
|
+
steps: 5,
|
|
21
|
+
guidance: 1,
|
|
22
|
+
numberOfImages: 1,
|
|
23
|
+
numberOfPreviews: 0
|
|
24
|
+
};
|
|
7
25
|
|
|
8
26
|
export type JobStatus =
|
|
9
27
|
| 'pending'
|
|
@@ -40,6 +58,9 @@ export interface JobData {
|
|
|
40
58
|
previewUrl?: string;
|
|
41
59
|
resultUrl?: string | null;
|
|
42
60
|
error?: ErrorData;
|
|
61
|
+
positivePrompt?: string;
|
|
62
|
+
negativePrompt?: string;
|
|
63
|
+
jobIndex?: number;
|
|
43
64
|
}
|
|
44
65
|
|
|
45
66
|
export interface JobEventMap extends EntityEvents {
|
|
@@ -51,6 +72,7 @@ export interface JobEventMap extends EntityEvents {
|
|
|
51
72
|
export interface JobOptions {
|
|
52
73
|
api: ProjectsApi;
|
|
53
74
|
logger: Logger;
|
|
75
|
+
project: Project;
|
|
54
76
|
}
|
|
55
77
|
|
|
56
78
|
class Job extends DataEntity<JobData, JobEventMap> {
|
|
@@ -72,14 +94,18 @@ class Job extends DataEntity<JobData, JobEventMap> {
|
|
|
72
94
|
|
|
73
95
|
private readonly _api: ProjectsApi;
|
|
74
96
|
private readonly _logger: Logger;
|
|
97
|
+
private readonly _project: Project;
|
|
98
|
+
private _enhancementProject: Project | null = null;
|
|
75
99
|
|
|
76
100
|
constructor(data: JobData, options: JobOptions) {
|
|
77
101
|
super(data);
|
|
78
102
|
|
|
79
103
|
this._api = options.api;
|
|
80
104
|
this._logger = options.logger;
|
|
105
|
+
this._project = options.project;
|
|
81
106
|
|
|
82
107
|
this.on('updated', this.handleUpdated.bind(this));
|
|
108
|
+
this.handleEnhancementUpdate = this.handleEnhancementUpdate.bind(this);
|
|
83
109
|
}
|
|
84
110
|
|
|
85
111
|
get id() {
|
|
@@ -152,6 +178,25 @@ class Job extends DataEntity<JobData, JobEventMap> {
|
|
|
152
178
|
return this.data.error;
|
|
153
179
|
}
|
|
154
180
|
|
|
181
|
+
get hasResultImage() {
|
|
182
|
+
return this.status === 'completed' && !this.isNSFW;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
get enhancedImage() {
|
|
186
|
+
if (!this._enhancementProject) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const project = this._enhancementProject;
|
|
190
|
+
const job = project.jobs[0];
|
|
191
|
+
return {
|
|
192
|
+
status: project.status,
|
|
193
|
+
progress: project.progress,
|
|
194
|
+
result: job?.resultUrl || null,
|
|
195
|
+
error: project.error,
|
|
196
|
+
getResultUrl: () => job?.getResultUrl()
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
155
200
|
/**
|
|
156
201
|
* Get the result URL of the job. This method will make a request to the API to get signed URL.
|
|
157
202
|
* IMPORTANT: URL expires after 30 minutes, so make sure to download the image as soon as possible.
|
|
@@ -225,6 +270,59 @@ class Job extends DataEntity<JobData, JobEventMap> {
|
|
|
225
270
|
this.emit('failed', this.data.error!);
|
|
226
271
|
}
|
|
227
272
|
}
|
|
273
|
+
|
|
274
|
+
private handleEnhancementUpdate() {
|
|
275
|
+
this.emit('updated', ['enhancedImage']);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async getResultData() {
|
|
279
|
+
if (!this.hasResultImage) {
|
|
280
|
+
throw new Error('No result image available');
|
|
281
|
+
}
|
|
282
|
+
const url = await this.getResultUrl();
|
|
283
|
+
const response = await fetch(url);
|
|
284
|
+
if (!response.ok) {
|
|
285
|
+
throw new Error(`Failed to fetch image: ${response.statusText}`);
|
|
286
|
+
}
|
|
287
|
+
return response.blob();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Enhance the image using the Flux model. This method will create a new project with the
|
|
292
|
+
* enhancement parameters and use the result image of the current job as the starting image.
|
|
293
|
+
* @param strength - how much freedom the model has to change the image.
|
|
294
|
+
* @param overrides - optional parameters to override original prompt, style or token type.
|
|
295
|
+
*/
|
|
296
|
+
async enhance(
|
|
297
|
+
strength: EnhancementStrength,
|
|
298
|
+
overrides: { positivePrompt?: string; stylePrompt?: string; tokenType?: TokenType } = {}
|
|
299
|
+
) {
|
|
300
|
+
if (this.status !== 'completed') {
|
|
301
|
+
throw new Error('Job is not completed yet');
|
|
302
|
+
}
|
|
303
|
+
if (this.isNSFW) {
|
|
304
|
+
throw new Error('Job did not pass NSFW filter');
|
|
305
|
+
}
|
|
306
|
+
if (this._enhancementProject) {
|
|
307
|
+
this._enhancementProject.off('updated', this.handleEnhancementUpdate);
|
|
308
|
+
this._enhancementProject = null;
|
|
309
|
+
}
|
|
310
|
+
const imageData = await this.getResultData();
|
|
311
|
+
const project = await this._api.create({
|
|
312
|
+
...enhancementDefaults,
|
|
313
|
+
positivePrompt: overrides.positivePrompt || this._project.params.positivePrompt,
|
|
314
|
+
stylePrompt: overrides.stylePrompt || this._project.params.stylePrompt,
|
|
315
|
+
tokenType: overrides.tokenType || this._project.params.tokenType,
|
|
316
|
+
seed: this.seed || this._project.params.seed,
|
|
317
|
+
startingImage: imageData,
|
|
318
|
+
startingImageStrength: 1 - getEnhacementStrength(strength),
|
|
319
|
+
sizePreset: this._project.params.sizePreset
|
|
320
|
+
});
|
|
321
|
+
this._enhancementProject = project;
|
|
322
|
+
this._enhancementProject.on('updated', this.handleEnhancementUpdate);
|
|
323
|
+
const images = await project.waitForCompletion();
|
|
324
|
+
return images[0];
|
|
325
|
+
}
|
|
228
326
|
}
|
|
229
327
|
|
|
230
328
|
export default Job;
|
package/src/Projects/Project.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Job, { JobData
|
|
1
|
+
import Job, { JobData } from './Job';
|
|
2
2
|
import DataEntity, { EntityEvents } from '../lib/DataEntity';
|
|
3
3
|
import { ProjectParams } from './types';
|
|
4
4
|
import cloneDeep from 'lodash/cloneDeep';
|
|
@@ -50,6 +50,7 @@ export interface ProjectEventMap extends EntityEvents {
|
|
|
50
50
|
progress: number;
|
|
51
51
|
completed: string[];
|
|
52
52
|
failed: ErrorData;
|
|
53
|
+
jobStarted: Job;
|
|
53
54
|
jobCompleted: Job;
|
|
54
55
|
jobFailed: Job;
|
|
55
56
|
}
|
|
@@ -209,37 +210,24 @@ class Project extends DataEntity<ProjectData, ProjectEventMap> {
|
|
|
209
210
|
*/
|
|
210
211
|
_addJob(data: JobData | Job) {
|
|
211
212
|
const job =
|
|
212
|
-
data instanceof Job
|
|
213
|
+
data instanceof Job
|
|
214
|
+
? data
|
|
215
|
+
: new Job(data, { api: this._api, logger: this._logger, project: this });
|
|
213
216
|
this._jobs.push(job);
|
|
214
217
|
job.on('updated', () => {
|
|
215
218
|
this.lastUpdated = new Date();
|
|
216
219
|
this.emit('updated', ['jobs']);
|
|
217
220
|
});
|
|
221
|
+
this.emit('jobStarted', job);
|
|
218
222
|
job.on('completed', () => {
|
|
219
223
|
this.emit('jobCompleted', job);
|
|
220
|
-
this._handleJobFinished(job);
|
|
221
224
|
});
|
|
222
225
|
job.on('failed', () => {
|
|
223
226
|
this.emit('jobFailed', job);
|
|
224
|
-
this._handleJobFinished(job);
|
|
225
227
|
});
|
|
226
228
|
return job;
|
|
227
229
|
}
|
|
228
230
|
|
|
229
|
-
private _handleJobFinished(job: Job) {
|
|
230
|
-
const finalStatus: JobStatus[] = ['completed', 'failed', 'canceled'];
|
|
231
|
-
const allJobsDone = this.jobs.every((job) => finalStatus.includes(job.status));
|
|
232
|
-
// If all jobs are done and project is not already failed or completed, update the project status
|
|
233
|
-
if (allJobsDone && this.status !== 'failed' && this.status !== 'completed') {
|
|
234
|
-
const allJobsFailed = this.jobs.every((job) => job.status === 'failed');
|
|
235
|
-
if (allJobsFailed) {
|
|
236
|
-
this._update({ status: 'failed' });
|
|
237
|
-
} else {
|
|
238
|
-
this._update({ status: 'completed' });
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
231
|
private _checkForTimeout() {
|
|
244
232
|
if (this.lastUpdated.getTime() + PROJECT_TIMEOUT < Date.now()) {
|
|
245
233
|
this._syncToServer().catch((error) => {
|
|
@@ -298,7 +286,11 @@ class Project extends DataEntity<ProjectData, ProjectEventMap> {
|
|
|
298
286
|
// If there are any jobs left in jobData, it means they are new jobs that are not in the project yet
|
|
299
287
|
if (Object.keys(jobData).length) {
|
|
300
288
|
for (const job of Object.values(jobData)) {
|
|
301
|
-
const jobInstance = Job.fromRaw(data, job, {
|
|
289
|
+
const jobInstance = Job.fromRaw(data, job, {
|
|
290
|
+
api: this._api,
|
|
291
|
+
logger: this._logger,
|
|
292
|
+
project: this
|
|
293
|
+
});
|
|
302
294
|
this._addJob(jobInstance);
|
|
303
295
|
}
|
|
304
296
|
}
|
|
@@ -139,7 +139,8 @@ function createJobRequestMessage(id: string, params: ProjectParams) {
|
|
|
139
139
|
previews: params.numberOfPreviews || 0,
|
|
140
140
|
numberOfImages: params.numberOfImages,
|
|
141
141
|
jobID: id,
|
|
142
|
-
disableSafety: !!params.disableNSFWFilter
|
|
142
|
+
disableSafety: !!params.disableNSFWFilter,
|
|
143
|
+
tokenType: params.tokenType
|
|
143
144
|
};
|
|
144
145
|
if (params.network) {
|
|
145
146
|
jobRequest.network = params.network;
|
package/src/Projects/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ApiGroup, { ApiConfig } from '../ApiGroup';
|
|
2
2
|
import {
|
|
3
3
|
AvailableModel,
|
|
4
|
+
EnhancementStrength,
|
|
4
5
|
EstimateRequest,
|
|
5
6
|
ImageUrlParams,
|
|
6
7
|
ProjectParams,
|
|
@@ -16,7 +17,7 @@ import {
|
|
|
16
17
|
} from '../ApiClient/WebSocketClient/events';
|
|
17
18
|
import Project from './Project';
|
|
18
19
|
import createJobRequestMessage from './createJobRequestMessage';
|
|
19
|
-
import { ApiError,
|
|
20
|
+
import { ApiError, ApiResponse } from '../ApiClient';
|
|
20
21
|
import { EstimationResponse } from './types/EstimationResponse';
|
|
21
22
|
import { JobEvent, ProjectApiEvents, ProjectEvent } from './types/events';
|
|
22
23
|
import getUUID from '../lib/getUUID';
|
|
@@ -24,6 +25,9 @@ import { RawProject } from './types/RawProject';
|
|
|
24
25
|
import ErrorData from '../types/ErrorData';
|
|
25
26
|
import { SupernetType } from '../ApiClient/WebSocketClient/types';
|
|
26
27
|
import Cache from '../lib/Cache';
|
|
28
|
+
import { enhancementDefaults } from './Job';
|
|
29
|
+
import { getEnhacementStrength } from './utils';
|
|
30
|
+
import { TokenType } from '../types/token';
|
|
27
31
|
|
|
28
32
|
const sizePresetCache = new Cache<SizePreset[]>(10 * 60 * 1000);
|
|
29
33
|
const GARBAGE_COLLECT_TIMEOUT = 30000;
|
|
@@ -67,7 +71,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
67
71
|
this.client.socket.on('jobProgress', this.handleJobProgress.bind(this));
|
|
68
72
|
this.client.socket.on('jobError', this.handleJobError.bind(this));
|
|
69
73
|
this.client.socket.on('jobResult', this.handleJobResult.bind(this));
|
|
70
|
-
// Listen to server disconnect event
|
|
74
|
+
// Listen to the server disconnect event
|
|
71
75
|
this.client.on('disconnected', this.handleServerDisconnected.bind(this));
|
|
72
76
|
// Listen to project and job events and update project and job instances
|
|
73
77
|
this.on('project', this.handleProjectEvent.bind(this));
|
|
@@ -115,7 +119,10 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
115
119
|
type: 'initiating',
|
|
116
120
|
projectId: data.jobID,
|
|
117
121
|
jobId: data.imgID,
|
|
118
|
-
workerName: data.workerName
|
|
122
|
+
workerName: data.workerName,
|
|
123
|
+
positivePrompt: data.positivePrompt,
|
|
124
|
+
negativePrompt: data.negativePrompt,
|
|
125
|
+
jobIndex: data.jobIndex
|
|
119
126
|
});
|
|
120
127
|
return;
|
|
121
128
|
case 'jobStarted': {
|
|
@@ -123,7 +130,10 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
123
130
|
type: 'started',
|
|
124
131
|
projectId: data.jobID,
|
|
125
132
|
jobId: data.imgID,
|
|
126
|
-
workerName: data.workerName
|
|
133
|
+
workerName: data.workerName,
|
|
134
|
+
positivePrompt: data.positivePrompt,
|
|
135
|
+
negativePrompt: data.negativePrompt,
|
|
136
|
+
jobIndex: data.jobIndex
|
|
127
137
|
});
|
|
128
138
|
return;
|
|
129
139
|
}
|
|
@@ -263,15 +273,30 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
263
273
|
}
|
|
264
274
|
switch (event.type) {
|
|
265
275
|
case 'initiating':
|
|
266
|
-
|
|
276
|
+
// positivePrompt and negativePrompt are only received if a Dynamic Prompt was used for the project creating a different prompt for each job
|
|
277
|
+
job._update({
|
|
278
|
+
status: 'initiating',
|
|
279
|
+
workerName: event.workerName,
|
|
280
|
+
positivePrompt: event.positivePrompt,
|
|
281
|
+
negativePrompt: event.negativePrompt,
|
|
282
|
+
jobIndex: event.jobIndex
|
|
283
|
+
});
|
|
267
284
|
break;
|
|
268
285
|
case 'started':
|
|
269
|
-
|
|
286
|
+
// positivePrompt and negativePrompt are only received if a Dynamic Prompt was used for the project creating a different prompt for each job
|
|
287
|
+
job._update({
|
|
288
|
+
status: 'processing',
|
|
289
|
+
workerName: event.workerName,
|
|
290
|
+
positivePrompt: event.positivePrompt,
|
|
291
|
+
negativePrompt: event.negativePrompt,
|
|
292
|
+
jobIndex: event.jobIndex
|
|
293
|
+
});
|
|
270
294
|
break;
|
|
271
295
|
case 'progress':
|
|
272
296
|
job._update({
|
|
273
297
|
status: 'processing',
|
|
274
|
-
|
|
298
|
+
// Jus in case event comes out of order
|
|
299
|
+
step: Math.max(event.step, job.step),
|
|
275
300
|
stepCount: event.stepCount
|
|
276
301
|
});
|
|
277
302
|
if (project.status !== 'processing') {
|
|
@@ -337,10 +362,10 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
337
362
|
*/
|
|
338
363
|
async create(data: ProjectParams): Promise<Project> {
|
|
339
364
|
const project = new Project({ ...data }, { api: this, logger: this.client.logger });
|
|
340
|
-
if (data.startingImage) {
|
|
365
|
+
if (data.startingImage && data.startingImage !== true) {
|
|
341
366
|
await this.uploadGuideImage(project.id, data.startingImage);
|
|
342
367
|
}
|
|
343
|
-
if (data.controlNet?.image) {
|
|
368
|
+
if (data.controlNet?.image && data.controlNet.image !== true) {
|
|
344
369
|
await this.uploadCNImage(project.id, data.controlNet.image);
|
|
345
370
|
}
|
|
346
371
|
const request = createJobRequestMessage(project.id, data);
|
|
@@ -356,7 +381,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
356
381
|
* @param projectId
|
|
357
382
|
*/
|
|
358
383
|
async get(projectId: string) {
|
|
359
|
-
const { data } = await this.client.rest.get<
|
|
384
|
+
const { data } = await this.client.rest.get<ApiResponse<{ project: RawProject }>>(
|
|
360
385
|
`/v1/projects/${projectId}`
|
|
361
386
|
);
|
|
362
387
|
return data.project;
|
|
@@ -441,6 +466,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
441
466
|
*/
|
|
442
467
|
async estimateCost({
|
|
443
468
|
network,
|
|
469
|
+
tokenType,
|
|
444
470
|
model,
|
|
445
471
|
imageCount,
|
|
446
472
|
stepCount,
|
|
@@ -452,6 +478,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
452
478
|
sizePreset
|
|
453
479
|
}: EstimateRequest) {
|
|
454
480
|
const pathParams = [
|
|
481
|
+
tokenType || 'sogni',
|
|
455
482
|
network,
|
|
456
483
|
model,
|
|
457
484
|
imageCount,
|
|
@@ -471,7 +498,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
471
498
|
pathParams.push(width, height);
|
|
472
499
|
}
|
|
473
500
|
const r = await this.client.socket.get<EstimationResponse>(
|
|
474
|
-
`/api/
|
|
501
|
+
`/api/v2/job/estimate/${pathParams.join('/')}`
|
|
475
502
|
);
|
|
476
503
|
return {
|
|
477
504
|
token: r.quote.project.costInToken,
|
|
@@ -479,13 +506,26 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
479
506
|
};
|
|
480
507
|
}
|
|
481
508
|
|
|
509
|
+
async estimateEnhancementCost(strength: EnhancementStrength, tokenType: TokenType = 'sogni') {
|
|
510
|
+
return this.estimateCost({
|
|
511
|
+
network: enhancementDefaults.network,
|
|
512
|
+
tokenType,
|
|
513
|
+
model: enhancementDefaults.modelId,
|
|
514
|
+
imageCount: 1,
|
|
515
|
+
stepCount: enhancementDefaults.steps,
|
|
516
|
+
previewCount: 0,
|
|
517
|
+
cnEnabled: false,
|
|
518
|
+
startingImageStrength: getEnhacementStrength(strength)
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
482
522
|
/**
|
|
483
523
|
* Get upload URL for image
|
|
484
524
|
* @internal
|
|
485
525
|
* @param params
|
|
486
526
|
*/
|
|
487
527
|
async uploadUrl(params: ImageUrlParams) {
|
|
488
|
-
const r = await this.client.rest.get<
|
|
528
|
+
const r = await this.client.rest.get<ApiResponse<{ uploadUrl: string }>>(
|
|
489
529
|
`/v1/image/uploadUrl`,
|
|
490
530
|
params
|
|
491
531
|
);
|
|
@@ -498,7 +538,7 @@ class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
|
498
538
|
* @param params
|
|
499
539
|
*/
|
|
500
540
|
async downloadUrl(params: ImageUrlParams) {
|
|
501
|
-
const r = await this.client.rest.get<
|
|
541
|
+
const r = await this.client.rest.get<ApiResponse<{ downloadUrl: string }>>(
|
|
502
542
|
`/v1/image/downloadUrl`,
|
|
503
543
|
params
|
|
504
544
|
);
|
|
@@ -16,7 +16,8 @@ export type ControlNetName =
|
|
|
16
16
|
| 'segmentation'
|
|
17
17
|
| 'shuffle'
|
|
18
18
|
| 'softedge'
|
|
19
|
-
| 'tile'
|
|
19
|
+
| 'tile'
|
|
20
|
+
| 'instantid';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Raw ControlNet parameters passed to the API
|
|
@@ -53,8 +54,13 @@ export interface ControlNetParams {
|
|
|
53
54
|
name: ControlNetName;
|
|
54
55
|
/**
|
|
55
56
|
* ControlNet input image
|
|
57
|
+
* Supported types:
|
|
58
|
+
* `File` - file object from input[type=file]
|
|
59
|
+
* `Buffer` - Node.js buffer object with image data
|
|
60
|
+
* `Blob` - blob object with image data
|
|
61
|
+
* `true` - indicates that the image is already uploaded to the server
|
|
56
62
|
*/
|
|
57
|
-
image?: File | Buffer | Blob;
|
|
63
|
+
image?: File | Buffer | Blob | boolean;
|
|
58
64
|
/**
|
|
59
65
|
* ControlNet strength 0 to 1. 0 full control to prompt, 1 full control to ControlNet
|
|
60
66
|
*/
|
|
@@ -29,11 +29,17 @@ export interface JobEventBase {
|
|
|
29
29
|
export interface JobInitiating extends JobEventBase {
|
|
30
30
|
type: 'initiating';
|
|
31
31
|
workerName: string;
|
|
32
|
+
positivePrompt?: string;
|
|
33
|
+
negativePrompt?: string;
|
|
34
|
+
jobIndex?: number;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export interface JobStarted extends JobEventBase {
|
|
35
38
|
type: 'started';
|
|
36
39
|
workerName: string;
|
|
40
|
+
positivePrompt?: string;
|
|
41
|
+
negativePrompt?: string;
|
|
42
|
+
jobIndex?: number;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
export interface JobProgress extends JobEventBase {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SupernetType } from '../../ApiClient/WebSocketClient/types';
|
|
2
2
|
import { ControlNetParams } from './ControlNetParams';
|
|
3
|
+
import { TokenType } from '../../types/token';
|
|
3
4
|
|
|
4
5
|
export interface SupportedModel {
|
|
5
6
|
id: string;
|
|
@@ -102,12 +103,14 @@ export interface ProjectParams {
|
|
|
102
103
|
*/
|
|
103
104
|
numberOfImages: number;
|
|
104
105
|
/**
|
|
105
|
-
* Generate images based on starting image.
|
|
106
|
+
* Generate images based on the starting image.
|
|
107
|
+
* Supported types:
|
|
106
108
|
* `File` - file object from input[type=file]
|
|
107
|
-
* `Buffer` - buffer object with image data
|
|
109
|
+
* `Buffer` - Node.js buffer object with image data
|
|
108
110
|
* `Blob` - blob object with image data
|
|
111
|
+
* `true` - indicates that the image is already uploaded to the server
|
|
109
112
|
*/
|
|
110
|
-
startingImage?: File | Buffer | Blob;
|
|
113
|
+
startingImage?: File | Buffer | Blob | boolean;
|
|
111
114
|
/**
|
|
112
115
|
* How strong effect of starting image should be. From 0 to 1, default 0.5
|
|
113
116
|
*/
|
|
@@ -141,6 +144,11 @@ export interface ProjectParams {
|
|
|
141
144
|
* ControlNet model parameters
|
|
142
145
|
*/
|
|
143
146
|
controlNet?: ControlNetParams;
|
|
147
|
+
/**
|
|
148
|
+
* Select which tokens to use for the project.
|
|
149
|
+
* If not specified, the Sogni token will be used.
|
|
150
|
+
*/
|
|
151
|
+
tokenType?: TokenType;
|
|
144
152
|
}
|
|
145
153
|
|
|
146
154
|
export type ImageUrlParams = {
|
|
@@ -156,6 +164,10 @@ export interface EstimateRequest {
|
|
|
156
164
|
* Network to use. Can be 'fast' or 'relaxed'
|
|
157
165
|
*/
|
|
158
166
|
network: SupernetType;
|
|
167
|
+
/**
|
|
168
|
+
* Token type
|
|
169
|
+
*/
|
|
170
|
+
tokenType?: TokenType;
|
|
159
171
|
/**
|
|
160
172
|
* Model ID
|
|
161
173
|
*/
|
|
@@ -195,3 +207,5 @@ export interface EstimateRequest {
|
|
|
195
207
|
*/
|
|
196
208
|
height?: number;
|
|
197
209
|
}
|
|
210
|
+
|
|
211
|
+
export type EnhancementStrength = 'light' | 'medium' | 'heavy';
|
package/src/Stats/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import ApiGroup from '../ApiGroup';
|
|
2
|
-
import {
|
|
2
|
+
import { ApiResponse } from '../ApiClient';
|
|
3
3
|
import { LeaderboardItem, LeaderboardParams } from './types';
|
|
4
4
|
|
|
5
5
|
class StatsApi extends ApiGroup {
|
|
6
6
|
async leaderboard(params: LeaderboardParams) {
|
|
7
|
-
const res = await this.client.rest.get<
|
|
7
|
+
const res = await this.client.rest.get<ApiResponse<LeaderboardItem[]>>(
|
|
8
8
|
'/v1/leaderboard/',
|
|
9
9
|
params
|
|
10
10
|
);
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AbstractProvider, JsonRpcProvider, getDefaultProvider } from 'ethers';
|
|
2
1
|
// Account API
|
|
3
2
|
import AccountApi from './Account';
|
|
4
3
|
import CurrentAccount from './Account/CurrentAccount';
|
|
@@ -18,6 +17,7 @@ import { AvailableModel, ProjectParams, Scheduler, TimeStepSpacing } from './Pro
|
|
|
18
17
|
import StatsApi from './Stats';
|
|
19
18
|
// Base Types
|
|
20
19
|
import ErrorData from './types/ErrorData';
|
|
20
|
+
import { TokenType } from './types/token';
|
|
21
21
|
|
|
22
22
|
export type {
|
|
23
23
|
AvailableModel,
|
|
@@ -29,7 +29,8 @@ export type {
|
|
|
29
29
|
ProjectStatus,
|
|
30
30
|
Scheduler,
|
|
31
31
|
SupernetType,
|
|
32
|
-
TimeStepSpacing
|
|
32
|
+
TimeStepSpacing,
|
|
33
|
+
TokenType
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
export { ApiError, CurrentAccount, Job, Project };
|
|
@@ -49,6 +50,13 @@ export interface SogniClientConfig {
|
|
|
49
50
|
* @internal
|
|
50
51
|
*/
|
|
51
52
|
socketEndpoint?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Disable WebSocket connection. Useful for testing or when WebSocket is not needed.
|
|
55
|
+
* Note that many may not work without WebSocket connection.
|
|
56
|
+
* @experimental
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
disableSocket?: boolean;
|
|
52
60
|
/**
|
|
53
61
|
* Which network to use after logging in. Can be 'fast' or 'relaxed'
|
|
54
62
|
*/
|
|
@@ -62,10 +70,6 @@ export interface SogniClientConfig {
|
|
|
62
70
|
* @default 'warn'
|
|
63
71
|
**/
|
|
64
72
|
logLevel?: LogLevel;
|
|
65
|
-
/**
|
|
66
|
-
* If provided, the client will connect to this JSON-RPC endpoint to interact with the blockchain
|
|
67
|
-
*/
|
|
68
|
-
jsonRpcUrl?: string;
|
|
69
73
|
/**
|
|
70
74
|
* If true, the client will connect to the testnet. Ignored if jsonRpcUrl is provided
|
|
71
75
|
*/
|
|
@@ -92,7 +96,7 @@ export class SogniClient {
|
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
/**
|
|
95
|
-
*
|
|
99
|
+
* Create client instance, with default configuration
|
|
96
100
|
* @param config
|
|
97
101
|
*/
|
|
98
102
|
static async createInstance(config: SogniClientConfig): Promise<SogniClient> {
|
|
@@ -100,21 +104,21 @@ export class SogniClient {
|
|
|
100
104
|
const socketEndpoint = config.socketEndpoint || 'wss://socket.sogni.ai';
|
|
101
105
|
const network = config.network || 'fast';
|
|
102
106
|
const logger = config.logger || new DefaultLogger(config.logLevel || 'warn');
|
|
103
|
-
const isTestnet = config.testnet !== undefined ? config.testnet :
|
|
107
|
+
const isTestnet = config.testnet !== undefined ? config.testnet : false;
|
|
104
108
|
|
|
105
|
-
const client = new ApiClient(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
const client = new ApiClient(
|
|
110
|
+
restEndpoint,
|
|
111
|
+
socketEndpoint,
|
|
112
|
+
config.appId,
|
|
113
|
+
network,
|
|
114
|
+
logger,
|
|
115
|
+
config.disableSocket
|
|
116
|
+
);
|
|
113
117
|
const eip712 = new EIP712Helper({
|
|
114
|
-
name: 'Sogni-testnet',
|
|
118
|
+
name: isTestnet ? 'Sogni-testnet' : 'Sogni AI',
|
|
115
119
|
version: '1',
|
|
116
|
-
chainId:
|
|
120
|
+
chainId: isTestnet ? '84532' : '8453'
|
|
117
121
|
});
|
|
118
|
-
return new SogniClient({ client,
|
|
122
|
+
return new SogniClient({ client, eip712 });
|
|
119
123
|
}
|
|
120
124
|
}
|
package/src/lib/utils.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TokenType = 'sogni' | 'spark';
|
package/src/version.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { version } from '../package.json';
|
|
2
|
+
export const LIB_VERSION = version;
|