@adminforth/bulk-ai-flow 1.10.2 → 1.11.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/build.log +3 -2
- package/custom/ImageGenerationCarousel.vue +35 -168
- package/custom/Swiper.vue +76 -0
- package/custom/VisionAction.vue +74 -31
- package/custom/VisionTable.vue +61 -9
- package/custom/package-lock.json +99 -3527
- package/custom/package.json +2 -1
- package/dist/custom/ImageGenerationCarousel.vue +35 -168
- package/dist/custom/Swiper.vue +76 -0
- package/dist/custom/VisionAction.vue +74 -31
- package/dist/custom/VisionTable.vue +61 -9
- package/dist/custom/package-lock.json +99 -3527
- package/dist/custom/package.json +2 -1
- package/dist/index.js +49 -46
- package/index.ts +46 -48
- package/package.json +1 -1
package/dist/custom/package.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -59,12 +59,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
59
59
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
60
60
|
const selectedId = recordId;
|
|
61
61
|
let isError = false;
|
|
62
|
-
// if (typeof(this.options.rateLimits?.fillFieldsFromImages) === 'string'){
|
|
63
|
-
// if (this.checkRateLimit("fillFieldsFromImages" ,this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
64
|
-
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
65
|
-
// return { error: "Rate limit exceeded" };
|
|
66
|
-
// }
|
|
67
|
-
// }
|
|
68
62
|
// Fetch the record using the provided ID
|
|
69
63
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
70
64
|
const record = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(primaryKeyColumn.name, selectedId)]);
|
|
@@ -72,7 +66,16 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
72
66
|
const attachmentFiles = yield this.options.attachFiles({ record: record });
|
|
73
67
|
if (STUB_MODE) {
|
|
74
68
|
yield new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 8000) + 1000));
|
|
75
|
-
|
|
69
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
70
|
+
if (attachmentFiles.length === 0) {
|
|
71
|
+
jobs.set(jobId, { status: 'failed', error: 'No source images found' });
|
|
72
|
+
}
|
|
73
|
+
else if (!fakeError) {
|
|
74
|
+
jobs.set(jobId, { status: 'completed', result: {} });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to analyze images' });
|
|
78
|
+
}
|
|
76
79
|
return {};
|
|
77
80
|
}
|
|
78
81
|
else if (attachmentFiles.length !== 0) {
|
|
@@ -110,8 +113,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
else {
|
|
113
|
-
jobs.set(jobId, { status: 'failed', error: "No
|
|
114
|
-
return { ok: false, error: "No
|
|
116
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
117
|
+
return { ok: false, error: "No source images found" };
|
|
115
118
|
}
|
|
116
119
|
});
|
|
117
120
|
}
|
|
@@ -119,12 +122,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
119
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
123
|
const selectedId = recordId;
|
|
121
124
|
let isError = false;
|
|
122
|
-
// if (typeof(this.options.rateLimits?.fillPlainFields) === 'string'){
|
|
123
|
-
// if (this.checkRateLimit("fillPlainFields", this.options.rateLimits.fillPlainFields, headers)) {
|
|
124
|
-
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
125
|
-
// return { error: "Rate limit exceeded" };
|
|
126
|
-
// }
|
|
127
|
-
// }
|
|
128
125
|
if (STUB_MODE) {
|
|
129
126
|
yield new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
130
127
|
jobs.set(jobId, { status: 'completed', result: {} });
|
|
@@ -168,12 +165,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
168
165
|
var _a, _b;
|
|
169
166
|
const selectedId = recordId;
|
|
170
167
|
let isError = false;
|
|
171
|
-
// if (typeof(this.options.rateLimits?.generateImages) === 'string'){
|
|
172
|
-
// if (this.checkRateLimit("generateImages", this.options.rateLimits.generateImages, headers)) {
|
|
173
|
-
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
174
|
-
// return { error: "Rate limit exceeded" };
|
|
175
|
-
// }
|
|
176
|
-
// }
|
|
177
168
|
const start = +new Date();
|
|
178
169
|
const record = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ((_a = this.resourceConfig.columns.find(c => c.primaryKey)) === null || _a === void 0 ? void 0 : _a.name, selectedId)]);
|
|
179
170
|
let attachmentFiles;
|
|
@@ -187,13 +178,21 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
187
178
|
const prompt = this.compileGenerationFieldTemplates(record)[key];
|
|
188
179
|
let images;
|
|
189
180
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
190
|
-
|
|
181
|
+
isError = true;
|
|
182
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
191
183
|
return { key, images: [] };
|
|
192
184
|
}
|
|
193
185
|
else {
|
|
194
186
|
if (STUB_MODE) {
|
|
195
187
|
yield new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
196
|
-
|
|
188
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
189
|
+
if (!fakeError) {
|
|
190
|
+
images = `https://pic.re/image`;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
isError = true;
|
|
194
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to generate image' });
|
|
195
|
+
}
|
|
197
196
|
}
|
|
198
197
|
else {
|
|
199
198
|
let generationAdapter;
|
|
@@ -259,7 +258,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
259
258
|
}
|
|
260
259
|
const images = yield Promise.all((new Array(this.options.generateImages[fieldName].countToGenerate)).fill(0).map(() => __awaiter(this, void 0, void 0, function* () {
|
|
261
260
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
262
|
-
|
|
261
|
+
isError = true;
|
|
262
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
263
263
|
return null;
|
|
264
264
|
}
|
|
265
265
|
if (STUB_MODE) {
|
|
@@ -594,33 +594,36 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
594
594
|
jobs.set(jobId, { status: "in_progress" });
|
|
595
595
|
if (!actionType) {
|
|
596
596
|
jobs.set(jobId, { status: "failed", error: "Missing action type" });
|
|
597
|
-
return { error: "Missing action type" };
|
|
597
|
+
//return { error: "Missing action type" };
|
|
598
598
|
}
|
|
599
|
-
if (!recordId) {
|
|
599
|
+
else if (!recordId) {
|
|
600
600
|
jobs.set(jobId, { status: "failed", error: "Missing record id" });
|
|
601
|
-
return { error: "Missing record id" };
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
case 'analyze_no_images':
|
|
608
|
-
this.analyzeNoImages(jobId, recordId, adminUser, headers);
|
|
609
|
-
break;
|
|
610
|
-
case 'analyze':
|
|
611
|
-
this.analyze_image(jobId, recordId, adminUser, headers);
|
|
612
|
-
break;
|
|
613
|
-
case 'regenerate_images':
|
|
614
|
-
if (!body.prompt || !body.fieldName) {
|
|
615
|
-
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
601
|
+
//return { error: "Missing record id" };
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
switch (actionType) {
|
|
605
|
+
case 'generate_images':
|
|
606
|
+
this.initialImageGenerate(jobId, recordId, adminUser, headers);
|
|
616
607
|
break;
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
608
|
+
case 'analyze_no_images':
|
|
609
|
+
this.analyzeNoImages(jobId, recordId, adminUser, headers);
|
|
610
|
+
break;
|
|
611
|
+
case 'analyze':
|
|
612
|
+
this.analyze_image(jobId, recordId, adminUser, headers);
|
|
613
|
+
break;
|
|
614
|
+
case 'regenerate_images':
|
|
615
|
+
if (!body.prompt || !body.fieldName) {
|
|
616
|
+
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
617
|
+
break;
|
|
618
|
+
}
|
|
619
|
+
this.regenerateImage(jobId, recordId, body.fieldName, body.prompt, adminUser, headers);
|
|
620
|
+
break;
|
|
621
|
+
default:
|
|
622
|
+
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
623
|
+
}
|
|
622
624
|
}
|
|
623
625
|
setTimeout(() => jobs.delete(jobId), 1800000);
|
|
626
|
+
setTimeout(() => jobs.set(jobId, { status: "failed", error: "Job timed out" }), 180000);
|
|
624
627
|
return { ok: true, jobId };
|
|
625
628
|
})
|
|
626
629
|
});
|
package/index.ts
CHANGED
|
@@ -70,12 +70,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
70
70
|
private async analyze_image(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
71
71
|
const selectedId = recordId;
|
|
72
72
|
let isError = false;
|
|
73
|
-
// if (typeof(this.options.rateLimits?.fillFieldsFromImages) === 'string'){
|
|
74
|
-
// if (this.checkRateLimit("fillFieldsFromImages" ,this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
75
|
-
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
76
|
-
// return { error: "Rate limit exceeded" };
|
|
77
|
-
// }
|
|
78
|
-
// }
|
|
79
73
|
// Fetch the record using the provided ID
|
|
80
74
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
81
75
|
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(primaryKeyColumn.name, selectedId)] );
|
|
@@ -84,7 +78,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
84
78
|
const attachmentFiles = await this.options.attachFiles({ record: record });
|
|
85
79
|
if (STUB_MODE) {
|
|
86
80
|
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 8000) + 1000));
|
|
87
|
-
|
|
81
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
82
|
+
if (attachmentFiles.length === 0) {
|
|
83
|
+
jobs.set(jobId, { status: 'failed', error: 'No source images found' });
|
|
84
|
+
} else if (!fakeError) {
|
|
85
|
+
jobs.set(jobId, { status: 'completed', result: {} });
|
|
86
|
+
} else {
|
|
87
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to analyze images' });
|
|
88
|
+
}
|
|
88
89
|
return {};
|
|
89
90
|
} else if (attachmentFiles.length !== 0) {
|
|
90
91
|
//create prompt for OpenAI
|
|
@@ -122,8 +123,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
122
123
|
return { ok: true };
|
|
123
124
|
}
|
|
124
125
|
} else {
|
|
125
|
-
jobs.set(jobId, { status: 'failed', error: "No
|
|
126
|
-
return { ok: false, error: "No
|
|
126
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
127
|
+
return { ok: false, error: "No source images found" };
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
}
|
|
@@ -131,12 +132,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
131
132
|
private async analyzeNoImages(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
132
133
|
const selectedId = recordId;
|
|
133
134
|
let isError = false;
|
|
134
|
-
// if (typeof(this.options.rateLimits?.fillPlainFields) === 'string'){
|
|
135
|
-
// if (this.checkRateLimit("fillPlainFields", this.options.rateLimits.fillPlainFields, headers)) {
|
|
136
|
-
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
137
|
-
// return { error: "Rate limit exceeded" };
|
|
138
|
-
// }
|
|
139
|
-
// }
|
|
140
135
|
if (STUB_MODE) {
|
|
141
136
|
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
142
137
|
jobs.set(jobId, { status: 'completed', result: {} });
|
|
@@ -177,12 +172,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
177
172
|
private async initialImageGenerate(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
178
173
|
const selectedId = recordId;
|
|
179
174
|
let isError = false;
|
|
180
|
-
// if (typeof(this.options.rateLimits?.generateImages) === 'string'){
|
|
181
|
-
// if (this.checkRateLimit("generateImages", this.options.rateLimits.generateImages, headers)) {
|
|
182
|
-
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
183
|
-
// return { error: "Rate limit exceeded" };
|
|
184
|
-
// }
|
|
185
|
-
// }
|
|
186
175
|
const start = +new Date();
|
|
187
176
|
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.resourceConfig.columns.find(c => c.primaryKey)?.name, selectedId)]);
|
|
188
177
|
let attachmentFiles
|
|
@@ -195,12 +184,19 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
195
184
|
const prompt = this.compileGenerationFieldTemplates(record)[key];
|
|
196
185
|
let images;
|
|
197
186
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
198
|
-
|
|
187
|
+
isError = true;
|
|
188
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
199
189
|
return { key, images: [] };
|
|
200
190
|
} else {
|
|
201
191
|
if (STUB_MODE) {
|
|
202
192
|
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
203
|
-
|
|
193
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
194
|
+
if (!fakeError) {
|
|
195
|
+
images = `https://pic.re/image`;
|
|
196
|
+
} else {
|
|
197
|
+
isError = true;
|
|
198
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to generate image' });
|
|
199
|
+
}
|
|
204
200
|
} else {
|
|
205
201
|
let generationAdapter;
|
|
206
202
|
if (this.options.generateImages[key].adapter) {
|
|
@@ -266,7 +262,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
266
262
|
const images = await Promise.all(
|
|
267
263
|
(new Array(this.options.generateImages[fieldName].countToGenerate)).fill(0).map(async () => {
|
|
268
264
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
269
|
-
|
|
265
|
+
isError = true;
|
|
266
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
270
267
|
return null;
|
|
271
268
|
}
|
|
272
269
|
if (STUB_MODE) {
|
|
@@ -633,34 +630,35 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
633
630
|
|
|
634
631
|
if (!actionType) {
|
|
635
632
|
jobs.set(jobId, { status: "failed", error: "Missing action type" });
|
|
636
|
-
return { error: "Missing action type" };
|
|
633
|
+
//return { error: "Missing action type" };
|
|
637
634
|
}
|
|
638
|
-
if (!recordId) {
|
|
635
|
+
else if (!recordId) {
|
|
639
636
|
jobs.set(jobId, { status: "failed", error: "Missing record id" });
|
|
640
|
-
return { error: "Missing record id" };
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
637
|
+
//return { error: "Missing record id" };
|
|
638
|
+
} else {
|
|
639
|
+
switch(actionType) {
|
|
640
|
+
case 'generate_images':
|
|
641
|
+
this.initialImageGenerate(jobId, recordId, adminUser, headers);
|
|
642
|
+
break;
|
|
643
|
+
case 'analyze_no_images':
|
|
644
|
+
this.analyzeNoImages(jobId, recordId, adminUser, headers);
|
|
645
|
+
break;
|
|
646
|
+
case 'analyze':
|
|
647
|
+
this.analyze_image(jobId, recordId, adminUser, headers);
|
|
648
|
+
break;
|
|
649
|
+
case 'regenerate_images':
|
|
650
|
+
if (!body.prompt || !body.fieldName) {
|
|
651
|
+
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
652
|
+
break;
|
|
653
|
+
}
|
|
654
|
+
this.regenerateImage(jobId, recordId, body.fieldName, body.prompt, adminUser, headers);
|
|
655
|
+
break;
|
|
656
|
+
default:
|
|
657
|
+
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
658
|
+
}
|
|
662
659
|
}
|
|
663
660
|
setTimeout(() => jobs.delete(jobId), 1_800_000);
|
|
661
|
+
setTimeout(() => jobs.set(jobId, { status: "failed", error: "Job timed out" }), 180_000);
|
|
664
662
|
return { ok: true, jobId };
|
|
665
663
|
}
|
|
666
664
|
});
|