@adminforth/bulk-ai-flow 1.10.3 → 1.12.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 +72 -29
- 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 +72 -29
- 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 +96 -46
- package/index.ts +94 -48
- package/package.json +1 -1
package/dist/custom/package.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { AdminForthPlugin, Filters } from "adminforth";
|
|
11
|
+
import { suggestIfTypo } from "adminforth";
|
|
11
12
|
import Handlebars from 'handlebars';
|
|
12
13
|
import { RateLimiter } from "adminforth";
|
|
13
14
|
import { randomUUID } from "crypto";
|
|
@@ -59,12 +60,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
59
60
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
60
61
|
const selectedId = recordId;
|
|
61
62
|
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
63
|
// Fetch the record using the provided ID
|
|
69
64
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
70
65
|
const record = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(primaryKeyColumn.name, selectedId)]);
|
|
@@ -72,7 +67,16 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
72
67
|
const attachmentFiles = yield this.options.attachFiles({ record: record });
|
|
73
68
|
if (STUB_MODE) {
|
|
74
69
|
yield new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 8000) + 1000));
|
|
75
|
-
|
|
70
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
71
|
+
if (attachmentFiles.length === 0) {
|
|
72
|
+
jobs.set(jobId, { status: 'failed', error: 'No source images found' });
|
|
73
|
+
}
|
|
74
|
+
else if (!fakeError) {
|
|
75
|
+
jobs.set(jobId, { status: 'completed', result: {} });
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to analyze images' });
|
|
79
|
+
}
|
|
76
80
|
return {};
|
|
77
81
|
}
|
|
78
82
|
else if (attachmentFiles.length !== 0) {
|
|
@@ -110,8 +114,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
else {
|
|
113
|
-
jobs.set(jobId, { status: 'failed', error: "No
|
|
114
|
-
return { ok: false, error: "No
|
|
117
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
118
|
+
return { ok: false, error: "No source images found" };
|
|
115
119
|
}
|
|
116
120
|
});
|
|
117
121
|
}
|
|
@@ -119,12 +123,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
119
123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
124
|
const selectedId = recordId;
|
|
121
125
|
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
126
|
if (STUB_MODE) {
|
|
129
127
|
yield new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
130
128
|
jobs.set(jobId, { status: 'completed', result: {} });
|
|
@@ -168,12 +166,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
168
166
|
var _a, _b;
|
|
169
167
|
const selectedId = recordId;
|
|
170
168
|
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
169
|
const start = +new Date();
|
|
178
170
|
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
171
|
let attachmentFiles;
|
|
@@ -187,13 +179,21 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
187
179
|
const prompt = this.compileGenerationFieldTemplates(record)[key];
|
|
188
180
|
let images;
|
|
189
181
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
190
|
-
|
|
182
|
+
isError = true;
|
|
183
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
191
184
|
return { key, images: [] };
|
|
192
185
|
}
|
|
193
186
|
else {
|
|
194
187
|
if (STUB_MODE) {
|
|
195
188
|
yield new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
196
|
-
|
|
189
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
190
|
+
if (!fakeError) {
|
|
191
|
+
images = `https://pic.re/image`;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
isError = true;
|
|
195
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to generate image' });
|
|
196
|
+
}
|
|
197
197
|
}
|
|
198
198
|
else {
|
|
199
199
|
let generationAdapter;
|
|
@@ -259,7 +259,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
259
259
|
}
|
|
260
260
|
const images = yield Promise.all((new Array(this.options.generateImages[fieldName].countToGenerate)).fill(0).map(() => __awaiter(this, void 0, void 0, function* () {
|
|
261
261
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
262
|
-
|
|
262
|
+
isError = true;
|
|
263
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
263
264
|
return null;
|
|
264
265
|
}
|
|
265
266
|
if (STUB_MODE) {
|
|
@@ -443,6 +444,52 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
443
444
|
`);
|
|
444
445
|
}
|
|
445
446
|
}
|
|
447
|
+
if (this.options.fillFieldsFromImages || this.options.fillPlainFields || this.options.generateImages) {
|
|
448
|
+
let matches = [];
|
|
449
|
+
const regex = /{{(.*?)}}/g;
|
|
450
|
+
if (this.options.fillFieldsFromImages) {
|
|
451
|
+
for (const [key, value] of Object.entries((this.options.fillFieldsFromImages))) {
|
|
452
|
+
const template = value;
|
|
453
|
+
const templateMatches = template.match(regex);
|
|
454
|
+
if (templateMatches) {
|
|
455
|
+
matches.push(...templateMatches);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if (this.options.fillPlainFields) {
|
|
460
|
+
for (const [key, value] of Object.entries((this.options.fillPlainFields))) {
|
|
461
|
+
const template = value;
|
|
462
|
+
const templateMatches = template.match(regex);
|
|
463
|
+
if (templateMatches) {
|
|
464
|
+
matches.push(...templateMatches);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (this.options.generateImages) {
|
|
469
|
+
for (const [key, value] of Object.entries((this.options.generateImages))) {
|
|
470
|
+
const template = value.prompt;
|
|
471
|
+
const templateMatches = template.match(regex);
|
|
472
|
+
if (templateMatches) {
|
|
473
|
+
matches.push(...templateMatches);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
if (matches) {
|
|
478
|
+
matches.forEach((match) => {
|
|
479
|
+
const field = match.replace(/{{|}}/g, '').trim();
|
|
480
|
+
if (!resourceConfig.columns.find((column) => column.name === field)) {
|
|
481
|
+
const similar = suggestIfTypo(resourceConfig.columns.map((column) => column.name), field);
|
|
482
|
+
throw new Error(`Field "${field}" specified in generationPrompt not found in resource "${resourceConfig.label}". ${similar ? `Did you mean "${similar}"?` : ''}`);
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
let column = resourceConfig.columns.find((column) => column.name === field);
|
|
486
|
+
if (column.backendOnly === true) {
|
|
487
|
+
throw new Error(`Field "${field}" specified in generationPrompt is marked as backendOnly in resource "${resourceConfig.label}". Please remove backendOnly or choose another field.`);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
}
|
|
446
493
|
}
|
|
447
494
|
}
|
|
448
495
|
instanceUniqueRepresentation(pluginOptions) {
|
|
@@ -594,33 +641,36 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
594
641
|
jobs.set(jobId, { status: "in_progress" });
|
|
595
642
|
if (!actionType) {
|
|
596
643
|
jobs.set(jobId, { status: "failed", error: "Missing action type" });
|
|
597
|
-
return { error: "Missing action type" };
|
|
644
|
+
//return { error: "Missing action type" };
|
|
598
645
|
}
|
|
599
|
-
if (!recordId) {
|
|
646
|
+
else if (!recordId) {
|
|
600
647
|
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" });
|
|
648
|
+
//return { error: "Missing record id" };
|
|
649
|
+
}
|
|
650
|
+
else {
|
|
651
|
+
switch (actionType) {
|
|
652
|
+
case 'generate_images':
|
|
653
|
+
this.initialImageGenerate(jobId, recordId, adminUser, headers);
|
|
616
654
|
break;
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
655
|
+
case 'analyze_no_images':
|
|
656
|
+
this.analyzeNoImages(jobId, recordId, adminUser, headers);
|
|
657
|
+
break;
|
|
658
|
+
case 'analyze':
|
|
659
|
+
this.analyze_image(jobId, recordId, adminUser, headers);
|
|
660
|
+
break;
|
|
661
|
+
case 'regenerate_images':
|
|
662
|
+
if (!body.prompt || !body.fieldName) {
|
|
663
|
+
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
this.regenerateImage(jobId, recordId, body.fieldName, body.prompt, adminUser, headers);
|
|
667
|
+
break;
|
|
668
|
+
default:
|
|
669
|
+
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
670
|
+
}
|
|
622
671
|
}
|
|
623
672
|
setTimeout(() => jobs.delete(jobId), 1800000);
|
|
673
|
+
setTimeout(() => jobs.set(jobId, { status: "failed", error: "Job timed out" }), 180000);
|
|
624
674
|
return { ok: true, jobId };
|
|
625
675
|
})
|
|
626
676
|
});
|
package/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AdminForthPlugin, Filters } from "adminforth";
|
|
2
2
|
import type { IAdminForth, IHttpServer, AdminForthComponentDeclaration, AdminForthResource } from "adminforth";
|
|
3
|
+
import { suggestIfTypo } from "adminforth";
|
|
3
4
|
import type { PluginOptions } from './types.js';
|
|
4
5
|
import Handlebars from 'handlebars';
|
|
5
6
|
import { RateLimiter } from "adminforth";
|
|
@@ -70,12 +71,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
70
71
|
private async analyze_image(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
71
72
|
const selectedId = recordId;
|
|
72
73
|
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
74
|
// Fetch the record using the provided ID
|
|
80
75
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
81
76
|
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(primaryKeyColumn.name, selectedId)] );
|
|
@@ -84,7 +79,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
84
79
|
const attachmentFiles = await this.options.attachFiles({ record: record });
|
|
85
80
|
if (STUB_MODE) {
|
|
86
81
|
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 8000) + 1000));
|
|
87
|
-
|
|
82
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
83
|
+
if (attachmentFiles.length === 0) {
|
|
84
|
+
jobs.set(jobId, { status: 'failed', error: 'No source images found' });
|
|
85
|
+
} else if (!fakeError) {
|
|
86
|
+
jobs.set(jobId, { status: 'completed', result: {} });
|
|
87
|
+
} else {
|
|
88
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to analyze images' });
|
|
89
|
+
}
|
|
88
90
|
return {};
|
|
89
91
|
} else if (attachmentFiles.length !== 0) {
|
|
90
92
|
//create prompt for OpenAI
|
|
@@ -122,8 +124,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
122
124
|
return { ok: true };
|
|
123
125
|
}
|
|
124
126
|
} else {
|
|
125
|
-
jobs.set(jobId, { status: 'failed', error: "No
|
|
126
|
-
return { ok: false, error: "No
|
|
127
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
128
|
+
return { ok: false, error: "No source images found" };
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
}
|
|
@@ -131,12 +133,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
131
133
|
private async analyzeNoImages(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
132
134
|
const selectedId = recordId;
|
|
133
135
|
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
136
|
if (STUB_MODE) {
|
|
141
137
|
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
142
138
|
jobs.set(jobId, { status: 'completed', result: {} });
|
|
@@ -177,12 +173,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
177
173
|
private async initialImageGenerate(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
178
174
|
const selectedId = recordId;
|
|
179
175
|
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
176
|
const start = +new Date();
|
|
187
177
|
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.resourceConfig.columns.find(c => c.primaryKey)?.name, selectedId)]);
|
|
188
178
|
let attachmentFiles
|
|
@@ -195,12 +185,19 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
195
185
|
const prompt = this.compileGenerationFieldTemplates(record)[key];
|
|
196
186
|
let images;
|
|
197
187
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
198
|
-
|
|
188
|
+
isError = true;
|
|
189
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
199
190
|
return { key, images: [] };
|
|
200
191
|
} else {
|
|
201
192
|
if (STUB_MODE) {
|
|
202
193
|
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 20000) + 1000));
|
|
203
|
-
|
|
194
|
+
const fakeError = Math.random() < 0.5; // 50% chance of error
|
|
195
|
+
if (!fakeError) {
|
|
196
|
+
images = `https://pic.re/image`;
|
|
197
|
+
} else {
|
|
198
|
+
isError = true;
|
|
199
|
+
jobs.set(jobId, { status: 'failed', error: 'AI provider refused to generate image' });
|
|
200
|
+
}
|
|
204
201
|
} else {
|
|
205
202
|
let generationAdapter;
|
|
206
203
|
if (this.options.generateImages[key].adapter) {
|
|
@@ -266,7 +263,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
266
263
|
const images = await Promise.all(
|
|
267
264
|
(new Array(this.options.generateImages[fieldName].countToGenerate)).fill(0).map(async () => {
|
|
268
265
|
if (this.options.attachFiles && attachmentFiles.length === 0) {
|
|
269
|
-
|
|
266
|
+
isError = true;
|
|
267
|
+
jobs.set(jobId, { status: 'failed', error: "No source images found" });
|
|
270
268
|
return null;
|
|
271
269
|
}
|
|
272
270
|
if (STUB_MODE) {
|
|
@@ -464,6 +462,53 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
464
462
|
`);
|
|
465
463
|
}
|
|
466
464
|
}
|
|
465
|
+
if (this.options.fillFieldsFromImages || this.options.fillPlainFields || this.options.generateImages) {
|
|
466
|
+
let matches: string[] = [];
|
|
467
|
+
const regex = /{{(.*?)}}/g;
|
|
468
|
+
|
|
469
|
+
if (this.options.fillFieldsFromImages) {
|
|
470
|
+
for (const [key, value] of Object.entries((this.options.fillFieldsFromImages ))) {
|
|
471
|
+
const template = value;
|
|
472
|
+
const templateMatches = template.match(regex);
|
|
473
|
+
if (templateMatches) {
|
|
474
|
+
matches.push(...templateMatches);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (this.options.fillPlainFields) {
|
|
479
|
+
for (const [key, value] of Object.entries((this.options.fillPlainFields))) {
|
|
480
|
+
const template = value;
|
|
481
|
+
const templateMatches = template.match(regex);
|
|
482
|
+
if (templateMatches) {
|
|
483
|
+
matches.push(...templateMatches);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (this.options.generateImages) {
|
|
488
|
+
for (const [key, value] of Object.entries((this.options.generateImages ))) {
|
|
489
|
+
const template = value.prompt;
|
|
490
|
+
const templateMatches = template.match(regex);
|
|
491
|
+
if (templateMatches) {
|
|
492
|
+
matches.push(...templateMatches);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (matches) {
|
|
498
|
+
matches.forEach((match) => {
|
|
499
|
+
const field = match.replace(/{{|}}/g, '').trim();
|
|
500
|
+
if (!resourceConfig.columns.find((column: any) => column.name === field)) {
|
|
501
|
+
const similar = suggestIfTypo(resourceConfig.columns.map((column: any) => column.name), field);
|
|
502
|
+
throw new Error(`Field "${field}" specified in generationPrompt not found in resource "${resourceConfig.label}". ${similar ? `Did you mean "${similar}"?` : ''}`);
|
|
503
|
+
} else {
|
|
504
|
+
let column = resourceConfig.columns.find((column: any) => column.name === field);
|
|
505
|
+
if (column.backendOnly === true) {
|
|
506
|
+
throw new Error(`Field "${field}" specified in generationPrompt is marked as backendOnly in resource "${resourceConfig.label}". Please remove backendOnly or choose another field.`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
467
512
|
}
|
|
468
513
|
}
|
|
469
514
|
|
|
@@ -633,34 +678,35 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
633
678
|
|
|
634
679
|
if (!actionType) {
|
|
635
680
|
jobs.set(jobId, { status: "failed", error: "Missing action type" });
|
|
636
|
-
return { error: "Missing action type" };
|
|
681
|
+
//return { error: "Missing action type" };
|
|
637
682
|
}
|
|
638
|
-
if (!recordId) {
|
|
683
|
+
else if (!recordId) {
|
|
639
684
|
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
|
-
|
|
685
|
+
//return { error: "Missing record id" };
|
|
686
|
+
} else {
|
|
687
|
+
switch(actionType) {
|
|
688
|
+
case 'generate_images':
|
|
689
|
+
this.initialImageGenerate(jobId, recordId, adminUser, headers);
|
|
690
|
+
break;
|
|
691
|
+
case 'analyze_no_images':
|
|
692
|
+
this.analyzeNoImages(jobId, recordId, adminUser, headers);
|
|
693
|
+
break;
|
|
694
|
+
case 'analyze':
|
|
695
|
+
this.analyze_image(jobId, recordId, adminUser, headers);
|
|
696
|
+
break;
|
|
697
|
+
case 'regenerate_images':
|
|
698
|
+
if (!body.prompt || !body.fieldName) {
|
|
699
|
+
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
700
|
+
break;
|
|
701
|
+
}
|
|
702
|
+
this.regenerateImage(jobId, recordId, body.fieldName, body.prompt, adminUser, headers);
|
|
703
|
+
break;
|
|
704
|
+
default:
|
|
705
|
+
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
706
|
+
}
|
|
662
707
|
}
|
|
663
708
|
setTimeout(() => jobs.delete(jobId), 1_800_000);
|
|
709
|
+
setTimeout(() => jobs.set(jobId, { status: "failed", error: "Job timed out" }), 180_000);
|
|
664
710
|
return { ok: true, jobId };
|
|
665
711
|
}
|
|
666
712
|
});
|