@adminforth/bulk-ai-flow 1.26.10 → 1.27.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/dist/index.js +91 -30
- package/index.ts +105 -33
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -12,6 +12,49 @@ import { suggestIfTypo, filtersTools } from "adminforth";
|
|
|
12
12
|
import Handlebars from 'handlebars';
|
|
13
13
|
import { RateLimiter } from "adminforth";
|
|
14
14
|
import { randomUUID } from "crypto";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
const getRecordsBodySchema = z.object({
|
|
17
|
+
record: z.array(z.any()).nullish(),
|
|
18
|
+
}).strict();
|
|
19
|
+
const getImagesBodySchema = z.object({
|
|
20
|
+
record: z.array(z.any()).nullish(),
|
|
21
|
+
}).strict();
|
|
22
|
+
const getOldDataBodySchema = z.object({
|
|
23
|
+
recordId: z.union([z.string(), z.number()]).nullish(),
|
|
24
|
+
}).strict();
|
|
25
|
+
const updateFieldsBodySchema = z.object({
|
|
26
|
+
selectedIds: z.array(z.any()).nullish(),
|
|
27
|
+
fields: z.any(),
|
|
28
|
+
saveImages: z.boolean().nullish(),
|
|
29
|
+
}).strict();
|
|
30
|
+
const getImageGenerationPromptsBodySchema = z.object({
|
|
31
|
+
recordId: z.union([z.string(), z.number()]).nullish(),
|
|
32
|
+
customPrompt: z.string().nullish(),
|
|
33
|
+
}).strict();
|
|
34
|
+
const createJobBodySchema = z.object({
|
|
35
|
+
actionType: z.string().nullish(),
|
|
36
|
+
recordId: z.union([z.string(), z.number()]).nullish(),
|
|
37
|
+
customPrompt: z.string().nullish(),
|
|
38
|
+
filterFilledFields: z.boolean().nullish(),
|
|
39
|
+
sessionIds: z.array(z.string()).nullish(),
|
|
40
|
+
prompt: z.string().nullish(),
|
|
41
|
+
fieldName: z.string().nullish(),
|
|
42
|
+
fieldToRegenerate: z.string().nullish(),
|
|
43
|
+
action: z.string().nullish(),
|
|
44
|
+
}).strict();
|
|
45
|
+
const jobStatusBodySchema = z.object({
|
|
46
|
+
jobId: z.string(),
|
|
47
|
+
}).strict();
|
|
48
|
+
const updateRateLimitsBodySchema = z.object({
|
|
49
|
+
actionType: z.string().nullish(),
|
|
50
|
+
}).strict();
|
|
51
|
+
const compileOldImageLinkBodySchema = z.object({
|
|
52
|
+
image: z.string().nullish(),
|
|
53
|
+
columnName: z.string().nullish(),
|
|
54
|
+
}).strict();
|
|
55
|
+
const getFilteredIdsBodySchema = z.object({
|
|
56
|
+
filters: z.any(),
|
|
57
|
+
}).passthrough();
|
|
15
58
|
const STUB_MODE = false;
|
|
16
59
|
const jobs = new Map();
|
|
17
60
|
export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
@@ -771,18 +814,19 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
771
814
|
server.endpoint({
|
|
772
815
|
method: 'POST',
|
|
773
816
|
path: `/plugin/${this.pluginInstanceId}/get_records`,
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
817
|
+
request_schema: getRecordsBodySchema,
|
|
818
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response }) {
|
|
819
|
+
const data = body;
|
|
820
|
+
if (!Array.isArray(data.record)) {
|
|
777
821
|
return { records: [] };
|
|
778
822
|
}
|
|
779
823
|
let records = [];
|
|
780
824
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
781
|
-
records = yield this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name,
|
|
825
|
+
records = yield this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name, data.record)]);
|
|
782
826
|
for (const [index, record] of records.entries()) {
|
|
783
827
|
records[index]._label = this.resourceConfig.recordLabel(records[index]);
|
|
784
828
|
}
|
|
785
|
-
const order = Object.fromEntries(
|
|
829
|
+
const order = Object.fromEntries(data.record.map((id, i) => [id, i]));
|
|
786
830
|
const sortedRecords = records.sort((a, b) => order[a.id] - order[b.id]);
|
|
787
831
|
return {
|
|
788
832
|
records: sortedRecords,
|
|
@@ -792,8 +836,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
792
836
|
server.endpoint({
|
|
793
837
|
method: 'POST',
|
|
794
838
|
path: `/plugin/${this.pluginInstanceId}/get_old_data`,
|
|
795
|
-
|
|
796
|
-
|
|
839
|
+
request_schema: getOldDataBodySchema,
|
|
840
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response }) {
|
|
841
|
+
const data = body;
|
|
842
|
+
const recordId = data.recordId;
|
|
797
843
|
if (recordId === undefined || recordId === null) {
|
|
798
844
|
return { ok: false, error: "Missing recordId" };
|
|
799
845
|
}
|
|
@@ -810,10 +856,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
810
856
|
server.endpoint({
|
|
811
857
|
method: 'POST',
|
|
812
858
|
path: `/plugin/${this.pluginInstanceId}/get_images`,
|
|
813
|
-
|
|
859
|
+
request_schema: getImagesBodySchema,
|
|
860
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response }) {
|
|
861
|
+
const data = body;
|
|
814
862
|
let images = [];
|
|
815
|
-
if (
|
|
816
|
-
for (const record of
|
|
863
|
+
if (data.record) {
|
|
864
|
+
for (const record of data.record) {
|
|
817
865
|
if (this.options.attachFiles) {
|
|
818
866
|
images.push(yield this.options.attachFiles({ record: record }));
|
|
819
867
|
}
|
|
@@ -827,15 +875,17 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
827
875
|
server.endpoint({
|
|
828
876
|
method: 'POST',
|
|
829
877
|
path: `/plugin/${this.pluginInstanceId}/update_fields`,
|
|
830
|
-
|
|
878
|
+
request_schema: updateFieldsBodySchema,
|
|
879
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
880
|
+
const data = body;
|
|
831
881
|
let isAllowedToSave = { ok: true, error: '' };
|
|
832
882
|
if (this.options.isAllowedToSave) {
|
|
833
883
|
isAllowedToSave = yield this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
|
|
834
884
|
}
|
|
835
885
|
if (isAllowedToSave.ok !== false) {
|
|
836
|
-
const selectedIds =
|
|
837
|
-
const fieldsToUpdate =
|
|
838
|
-
const saveImages =
|
|
886
|
+
const selectedIds = data.selectedIds || [];
|
|
887
|
+
const fieldsToUpdate = data.fields || {};
|
|
888
|
+
const saveImages = data.saveImages;
|
|
839
889
|
const outputImageFields = [];
|
|
840
890
|
if (this.options.generateImages) {
|
|
841
891
|
for (const [key, value] of Object.entries(this.options.generateImages)) {
|
|
@@ -928,10 +978,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
928
978
|
server.endpoint({
|
|
929
979
|
method: 'POST',
|
|
930
980
|
path: `/plugin/${this.pluginInstanceId}/get_image_generation_prompts`,
|
|
931
|
-
|
|
981
|
+
request_schema: getImageGenerationPromptsBodySchema,
|
|
982
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, headers, response }) {
|
|
932
983
|
var _b;
|
|
933
|
-
const
|
|
934
|
-
const
|
|
984
|
+
const data = body;
|
|
985
|
+
const Id = data.recordId || [];
|
|
986
|
+
const customPrompt = data.customPrompt || null;
|
|
935
987
|
const record = yield this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ((_b = this.resourceConfig.columns.find(c => c.primaryKey)) === null || _b === void 0 ? void 0 : _b.name, Id)]);
|
|
936
988
|
const compiledGenerationOptions = yield this.compileGenerationFieldTemplates(record, JSON.stringify({ "prompt": customPrompt }));
|
|
937
989
|
return compiledGenerationOptions;
|
|
@@ -951,8 +1003,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
951
1003
|
server.endpoint({
|
|
952
1004
|
method: 'POST',
|
|
953
1005
|
path: `/plugin/${this.pluginInstanceId}/create-job`,
|
|
954
|
-
|
|
955
|
-
|
|
1006
|
+
request_schema: createJobBodySchema,
|
|
1007
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1008
|
+
const data = body;
|
|
1009
|
+
const { actionType, recordId, customPrompt, filterFilledFields, sessionIds } = data;
|
|
956
1010
|
if (this.options.rateLimits) {
|
|
957
1011
|
if (sessionIds && sessionIds.length > 0) {
|
|
958
1012
|
for (const sessionId of sessionIds) {
|
|
@@ -988,15 +1042,15 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
988
1042
|
this.analyze_image(jobId, recordId, adminUser, headers, customPrompt, filterFilledFields);
|
|
989
1043
|
break;
|
|
990
1044
|
case 'regenerate_images':
|
|
991
|
-
if (!
|
|
1045
|
+
if (!data.prompt || !data.fieldName) {
|
|
992
1046
|
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
993
1047
|
break;
|
|
994
1048
|
}
|
|
995
|
-
this.regenerateImage(jobId, recordId,
|
|
1049
|
+
this.regenerateImage(jobId, recordId, data.fieldName, data.prompt, adminUser, headers);
|
|
996
1050
|
break;
|
|
997
1051
|
case 'regenerate_cell':
|
|
998
|
-
const fieldToRegenerate =
|
|
999
|
-
this.regenerateCell(jobId, fieldToRegenerate, recordId,
|
|
1052
|
+
const fieldToRegenerate = data.fieldToRegenerate;
|
|
1053
|
+
this.regenerateCell(jobId, fieldToRegenerate, recordId, data.action, data.prompt);
|
|
1000
1054
|
break;
|
|
1001
1055
|
default:
|
|
1002
1056
|
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
@@ -1010,8 +1064,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1010
1064
|
server.endpoint({
|
|
1011
1065
|
method: 'POST',
|
|
1012
1066
|
path: `/plugin/${this.pluginInstanceId}/get-job-status`,
|
|
1067
|
+
request_schema: jobStatusBodySchema,
|
|
1013
1068
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1014
|
-
const
|
|
1069
|
+
const data = body;
|
|
1070
|
+
const jobId = data.jobId;
|
|
1015
1071
|
if (!jobId) {
|
|
1016
1072
|
response.setStatus(400);
|
|
1017
1073
|
return {
|
|
@@ -1043,9 +1099,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1043
1099
|
server.endpoint({
|
|
1044
1100
|
method: 'POST',
|
|
1045
1101
|
path: `/plugin/${this.pluginInstanceId}/update-rate-limits`,
|
|
1046
|
-
|
|
1102
|
+
request_schema: updateRateLimitsBodySchema,
|
|
1103
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1047
1104
|
var _b, _c, _d;
|
|
1048
|
-
const
|
|
1105
|
+
const data = body;
|
|
1106
|
+
const actionType = data.actionType;
|
|
1049
1107
|
const sessionId = randomUUID();
|
|
1050
1108
|
this.sessionIds.add(sessionId);
|
|
1051
1109
|
if (actionType === 'analyze' && ((_b = this.options.rateLimits) === null || _b === void 0 ? void 0 : _b.fillFieldsFromImages)) {
|
|
@@ -1070,10 +1128,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1070
1128
|
server.endpoint({
|
|
1071
1129
|
method: 'POST',
|
|
1072
1130
|
path: `/plugin/${this.pluginInstanceId}/compile_old_image_link`,
|
|
1073
|
-
|
|
1131
|
+
request_schema: compileOldImageLinkBodySchema,
|
|
1132
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1074
1133
|
var _b, _c;
|
|
1075
|
-
const
|
|
1076
|
-
const
|
|
1134
|
+
const data = body;
|
|
1135
|
+
const image = data.image;
|
|
1136
|
+
const columnName = data.columnName;
|
|
1077
1137
|
if (!image) {
|
|
1078
1138
|
return { ok: false, error: "Can't find image url" };
|
|
1079
1139
|
}
|
|
@@ -1099,7 +1159,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1099
1159
|
server.endpoint({
|
|
1100
1160
|
method: 'POST',
|
|
1101
1161
|
path: `/plugin/${this.pluginInstanceId}/get_filtered_ids`,
|
|
1102
|
-
|
|
1162
|
+
request_schema: getFilteredIdsBodySchema,
|
|
1163
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, query, cookies, requestUrl, response }) {
|
|
1103
1164
|
var _b, _c;
|
|
1104
1165
|
const resource = this.resourceConfig;
|
|
1105
1166
|
for (const hook of ((_c = (_b = resource.hooks) === null || _b === void 0 ? void 0 : _b.list) === null || _c === void 0 ? void 0 : _c.beforeDatasourceRequest) || []) {
|
package/index.ts
CHANGED
|
@@ -5,6 +5,59 @@ import type { PluginOptions } from './types.js';
|
|
|
5
5
|
import Handlebars from 'handlebars';
|
|
6
6
|
import { RateLimiter } from "adminforth";
|
|
7
7
|
import { randomUUID } from "crypto";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
|
|
10
|
+
const getRecordsBodySchema = z.object({
|
|
11
|
+
record: z.array(z.any()).nullish(),
|
|
12
|
+
}).strict();
|
|
13
|
+
|
|
14
|
+
const getImagesBodySchema = z.object({
|
|
15
|
+
record: z.array(z.any()).nullish(),
|
|
16
|
+
}).strict();
|
|
17
|
+
|
|
18
|
+
const getOldDataBodySchema = z.object({
|
|
19
|
+
recordId: z.union([z.string(), z.number()]).nullish(),
|
|
20
|
+
}).strict();
|
|
21
|
+
|
|
22
|
+
const updateFieldsBodySchema = z.object({
|
|
23
|
+
selectedIds: z.array(z.any()).nullish(),
|
|
24
|
+
fields: z.any(),
|
|
25
|
+
saveImages: z.boolean().nullish(),
|
|
26
|
+
}).strict();
|
|
27
|
+
|
|
28
|
+
const getImageGenerationPromptsBodySchema = z.object({
|
|
29
|
+
recordId: z.union([z.string(), z.number()]).nullish(),
|
|
30
|
+
customPrompt: z.string().nullish(),
|
|
31
|
+
}).strict();
|
|
32
|
+
|
|
33
|
+
const createJobBodySchema = z.object({
|
|
34
|
+
actionType: z.string().nullish(),
|
|
35
|
+
recordId: z.union([z.string(), z.number()]).nullish(),
|
|
36
|
+
customPrompt: z.string().nullish(),
|
|
37
|
+
filterFilledFields: z.boolean().nullish(),
|
|
38
|
+
sessionIds: z.array(z.string()).nullish(),
|
|
39
|
+
prompt: z.string().nullish(),
|
|
40
|
+
fieldName: z.string().nullish(),
|
|
41
|
+
fieldToRegenerate: z.string().nullish(),
|
|
42
|
+
action: z.string().nullish(),
|
|
43
|
+
}).strict();
|
|
44
|
+
|
|
45
|
+
const jobStatusBodySchema = z.object({
|
|
46
|
+
jobId: z.string(),
|
|
47
|
+
}).strict();
|
|
48
|
+
|
|
49
|
+
const updateRateLimitsBodySchema = z.object({
|
|
50
|
+
actionType: z.string().nullish(),
|
|
51
|
+
}).strict();
|
|
52
|
+
|
|
53
|
+
const compileOldImageLinkBodySchema = z.object({
|
|
54
|
+
image: z.string().nullish(),
|
|
55
|
+
columnName: z.string().nullish(),
|
|
56
|
+
}).strict();
|
|
57
|
+
|
|
58
|
+
const getFilteredIdsBodySchema = z.object({
|
|
59
|
+
filters: z.any(),
|
|
60
|
+
}).passthrough();
|
|
8
61
|
const STUB_MODE = false;
|
|
9
62
|
const jobs = new Map();
|
|
10
63
|
export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
@@ -110,7 +163,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
110
163
|
return prompt;
|
|
111
164
|
}
|
|
112
165
|
|
|
113
|
-
private async analyze_image(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>, customPrompt? : string, filterFilledFields: boolean = true) {
|
|
166
|
+
private async analyze_image(jobId: string, recordId: string | number, adminUser: any, headers: Record<string, string | string[] | undefined>, customPrompt? : string, filterFilledFields: boolean = true) {
|
|
114
167
|
// TODO: need to do correct check of rate limit
|
|
115
168
|
// if (this.options.rateLimits && this.options.rateLimits.fillFieldsFromImages && await this.checkRateLimit("fillFieldsFromImages" ,this.options.rateLimits.fillFieldsFromImages, headers)) {
|
|
116
169
|
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
@@ -195,7 +248,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
195
248
|
|
|
196
249
|
}
|
|
197
250
|
|
|
198
|
-
private async analyzeNoImages(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>, customPrompt? : string, filterFilledFields: boolean = true) {
|
|
251
|
+
private async analyzeNoImages(jobId: string, recordId: string | number, adminUser: any, headers: Record<string, string | string[] | undefined>, customPrompt? : string, filterFilledFields: boolean = true) {
|
|
199
252
|
// TODO: need to do correct check of rate limit
|
|
200
253
|
// if (this.options.rateLimits && this.options.rateLimits.fillPlainFields && await this.checkRateLimit("fillPlainFields" ,this.options.rateLimits.fillPlainFields, headers)) {
|
|
201
254
|
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
@@ -259,7 +312,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
259
312
|
}
|
|
260
313
|
}
|
|
261
314
|
|
|
262
|
-
private async initialImageGenerate(jobId: string, recordId: string, adminUser: any, headers: Record<string, string | string[] | undefined>, customPrompt? : string, filterFilledFields: boolean = true) {
|
|
315
|
+
private async initialImageGenerate(jobId: string, recordId: string | number, adminUser: any, headers: Record<string, string | string[] | undefined>, customPrompt? : string, filterFilledFields: boolean = true) {
|
|
263
316
|
// TODO: need to do correct check of rate limit
|
|
264
317
|
// if (this.options.rateLimits && this.options.rateLimits.generateImages && await this.checkRateLimit("generateImages" ,this.options.rateLimits.generateImages, headers)) {
|
|
265
318
|
// jobs.set(jobId, { status: 'failed', error: "Rate limit exceeded" });
|
|
@@ -371,7 +424,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
371
424
|
}
|
|
372
425
|
}
|
|
373
426
|
|
|
374
|
-
private async regenerateImage(jobId: string, recordId: string, fieldName: string, prompt: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
427
|
+
private async regenerateImage(jobId: string, recordId: string | number, fieldName: string, prompt: string, adminUser: any, headers: Record<string, string | string[] | undefined>) {
|
|
375
428
|
const Id = recordId;
|
|
376
429
|
let isError = false;
|
|
377
430
|
// TODO: need to do correct check of rate limit
|
|
@@ -779,17 +832,19 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
779
832
|
server.endpoint({
|
|
780
833
|
method: 'POST',
|
|
781
834
|
path: `/plugin/${this.pluginInstanceId}/get_records`,
|
|
782
|
-
|
|
783
|
-
|
|
835
|
+
request_schema: getRecordsBodySchema,
|
|
836
|
+
handler: async ({ body, response }) => {
|
|
837
|
+
const data = body as z.infer<typeof getRecordsBodySchema>;
|
|
838
|
+
if (!Array.isArray(data.record)) {
|
|
784
839
|
return { records: [] };
|
|
785
840
|
}
|
|
786
841
|
let records = [];
|
|
787
842
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
788
|
-
records = await this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name,
|
|
843
|
+
records = await this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name, data.record)]);
|
|
789
844
|
for( const [index, record] of records.entries() ) {
|
|
790
845
|
records[index]._label = this.resourceConfig.recordLabel(records[index]);
|
|
791
846
|
}
|
|
792
|
-
const order = Object.fromEntries(
|
|
847
|
+
const order = Object.fromEntries(data.record.map((id, i) => [id, i]));
|
|
793
848
|
|
|
794
849
|
const sortedRecords = records.sort(
|
|
795
850
|
(a, b) => order[a.id] - order[b.id]
|
|
@@ -804,8 +859,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
804
859
|
server.endpoint({
|
|
805
860
|
method: 'POST',
|
|
806
861
|
path: `/plugin/${this.pluginInstanceId}/get_old_data`,
|
|
807
|
-
|
|
808
|
-
|
|
862
|
+
request_schema: getOldDataBodySchema,
|
|
863
|
+
handler: async ({ body, response }) => {
|
|
864
|
+
const data = body as z.infer<typeof getOldDataBodySchema>;
|
|
865
|
+
const recordId = data.recordId;
|
|
809
866
|
if (recordId === undefined || recordId === null) {
|
|
810
867
|
return { ok: false, error: "Missing recordId" };
|
|
811
868
|
}
|
|
@@ -824,10 +881,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
824
881
|
server.endpoint({
|
|
825
882
|
method: 'POST',
|
|
826
883
|
path: `/plugin/${this.pluginInstanceId}/get_images`,
|
|
827
|
-
|
|
884
|
+
request_schema: getImagesBodySchema,
|
|
885
|
+
handler: async ({ body, response }) => {
|
|
886
|
+
const data = body as z.infer<typeof getImagesBodySchema>;
|
|
828
887
|
let images = [];
|
|
829
|
-
if(
|
|
830
|
-
for( const record of
|
|
888
|
+
if(data.record){
|
|
889
|
+
for( const record of data.record ) {
|
|
831
890
|
if (this.options.attachFiles) {
|
|
832
891
|
images.push(await this.options.attachFiles({ record: record }));
|
|
833
892
|
}
|
|
@@ -843,15 +902,17 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
843
902
|
server.endpoint({
|
|
844
903
|
method: 'POST',
|
|
845
904
|
path: `/plugin/${this.pluginInstanceId}/update_fields`,
|
|
846
|
-
|
|
905
|
+
request_schema: updateFieldsBodySchema,
|
|
906
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
907
|
+
const data = body as z.infer<typeof updateFieldsBodySchema>;
|
|
847
908
|
let isAllowedToSave: any = { ok: true, error: '' };
|
|
848
909
|
if(this.options.isAllowedToSave) {
|
|
849
910
|
isAllowedToSave = await this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
|
|
850
911
|
}
|
|
851
912
|
if (isAllowedToSave.ok !== false) {
|
|
852
|
-
const selectedIds =
|
|
853
|
-
const fieldsToUpdate =
|
|
854
|
-
const saveImages =
|
|
913
|
+
const selectedIds = data.selectedIds || [];
|
|
914
|
+
const fieldsToUpdate = data.fields || {};
|
|
915
|
+
const saveImages = data.saveImages;
|
|
855
916
|
const outputImageFields = [];
|
|
856
917
|
if (this.options.generateImages) {
|
|
857
918
|
for (const [key, value] of Object.entries(this.options.generateImages)) {
|
|
@@ -950,9 +1011,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
950
1011
|
server.endpoint({
|
|
951
1012
|
method: 'POST',
|
|
952
1013
|
path: `/plugin/${this.pluginInstanceId}/get_image_generation_prompts`,
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
const
|
|
1014
|
+
request_schema: getImageGenerationPromptsBodySchema,
|
|
1015
|
+
handler: async ({ body, headers, response }) => {
|
|
1016
|
+
const data = body as z.infer<typeof getImageGenerationPromptsBodySchema>;
|
|
1017
|
+
const Id = data.recordId || [];
|
|
1018
|
+
const customPrompt = data.customPrompt || null;
|
|
956
1019
|
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.resourceConfig.columns.find(c => c.primaryKey)?.name, Id)]);
|
|
957
1020
|
const compiledGenerationOptions = await this.compileGenerationFieldTemplates(record, JSON.stringify({"prompt": customPrompt}));
|
|
958
1021
|
return compiledGenerationOptions;
|
|
@@ -976,8 +1039,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
976
1039
|
server.endpoint({
|
|
977
1040
|
method: 'POST',
|
|
978
1041
|
path: `/plugin/${this.pluginInstanceId}/create-job`,
|
|
979
|
-
|
|
980
|
-
|
|
1042
|
+
request_schema: createJobBodySchema,
|
|
1043
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
1044
|
+
const data = body as z.infer<typeof createJobBodySchema>;
|
|
1045
|
+
const { actionType, recordId, customPrompt, filterFilledFields, sessionIds } = data;
|
|
981
1046
|
if (this.options.rateLimits) {
|
|
982
1047
|
if (sessionIds && sessionIds.length > 0) {
|
|
983
1048
|
for (const sessionId of sessionIds) {
|
|
@@ -1011,15 +1076,15 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1011
1076
|
this.analyze_image(jobId, recordId, adminUser, headers, customPrompt, filterFilledFields);
|
|
1012
1077
|
break;
|
|
1013
1078
|
case 'regenerate_images':
|
|
1014
|
-
if (!
|
|
1079
|
+
if (!data.prompt || !data.fieldName) {
|
|
1015
1080
|
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
1016
1081
|
break;
|
|
1017
1082
|
}
|
|
1018
|
-
this.regenerateImage(jobId, recordId,
|
|
1083
|
+
this.regenerateImage(jobId, recordId, data.fieldName, data.prompt, adminUser, headers);
|
|
1019
1084
|
break;
|
|
1020
1085
|
case 'regenerate_cell':
|
|
1021
|
-
const fieldToRegenerate =
|
|
1022
|
-
this.regenerateCell(jobId, fieldToRegenerate, recordId,
|
|
1086
|
+
const fieldToRegenerate = data.fieldToRegenerate;
|
|
1087
|
+
this.regenerateCell(jobId, fieldToRegenerate, recordId, data.action, data.prompt);
|
|
1023
1088
|
break;
|
|
1024
1089
|
default:
|
|
1025
1090
|
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
@@ -1035,8 +1100,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1035
1100
|
server.endpoint({
|
|
1036
1101
|
method: 'POST',
|
|
1037
1102
|
path: `/plugin/${this.pluginInstanceId}/get-job-status`,
|
|
1103
|
+
request_schema: jobStatusBodySchema,
|
|
1038
1104
|
handler: async ({ body, adminUser, headers, response }) => {
|
|
1039
|
-
const
|
|
1105
|
+
const data = body as z.infer<typeof jobStatusBodySchema>;
|
|
1106
|
+
const jobId = data.jobId;
|
|
1040
1107
|
if (!jobId) {
|
|
1041
1108
|
response.setStatus(400);
|
|
1042
1109
|
|
|
@@ -1073,8 +1140,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1073
1140
|
server.endpoint({
|
|
1074
1141
|
method: 'POST',
|
|
1075
1142
|
path: `/plugin/${this.pluginInstanceId}/update-rate-limits`,
|
|
1076
|
-
|
|
1077
|
-
|
|
1143
|
+
request_schema: updateRateLimitsBodySchema,
|
|
1144
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
1145
|
+
const data = body as z.infer<typeof updateRateLimitsBodySchema>;
|
|
1146
|
+
const actionType = data.actionType;
|
|
1078
1147
|
const sessionId = randomUUID();
|
|
1079
1148
|
this.sessionIds.add(sessionId);
|
|
1080
1149
|
if (actionType === 'analyze' && this.options.rateLimits?.fillFieldsFromImages) {
|
|
@@ -1101,9 +1170,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1101
1170
|
server.endpoint({
|
|
1102
1171
|
method: 'POST',
|
|
1103
1172
|
path: `/plugin/${this.pluginInstanceId}/compile_old_image_link`,
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
const
|
|
1173
|
+
request_schema: compileOldImageLinkBodySchema,
|
|
1174
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
1175
|
+
const data = body as z.infer<typeof compileOldImageLinkBodySchema>;
|
|
1176
|
+
const image = data.image;
|
|
1177
|
+
const columnName = data.columnName;
|
|
1107
1178
|
if (!image) {
|
|
1108
1179
|
return { ok: false, error: "Can't find image url" };
|
|
1109
1180
|
}
|
|
@@ -1131,7 +1202,8 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1131
1202
|
server.endpoint({
|
|
1132
1203
|
method: 'POST',
|
|
1133
1204
|
path: `/plugin/${this.pluginInstanceId}/get_filtered_ids`,
|
|
1134
|
-
|
|
1205
|
+
request_schema: getFilteredIdsBodySchema,
|
|
1206
|
+
handler: async ({ body, adminUser, headers, query, cookies, requestUrl, response }) => {
|
|
1135
1207
|
const resource = this.resourceConfig;
|
|
1136
1208
|
|
|
1137
1209
|
for (const hook of resource.hooks?.list?.beforeDatasourceRequest || []) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminforth/bulk-ai-flow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -25,17 +25,18 @@
|
|
|
25
25
|
"description": "Bulk AI workflow plugin for AdminForth for batch field generation and image processing",
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "latest",
|
|
28
|
-
"adminforth": "^3.
|
|
28
|
+
"adminforth": "^3.8.2",
|
|
29
29
|
"semantic-release": "^24.2.1",
|
|
30
30
|
"semantic-release-slack-bot": "^4.0.2",
|
|
31
31
|
"typescript": "^5.7.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@types/handlebars": "^4.0.40",
|
|
35
|
-
"handlebars": "^4.7.8"
|
|
35
|
+
"handlebars": "^4.7.8",
|
|
36
|
+
"zod": "^4.3.6"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
38
|
-
"adminforth": "^3.
|
|
39
|
+
"adminforth": "^3.8.2"
|
|
39
40
|
},
|
|
40
41
|
"release": {
|
|
41
42
|
"plugins": [
|