@adminforth/bulk-ai-flow 1.26.9 → 1.27.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 +1 -1
- package/dist/index.js +113 -31
- package/index.ts +113 -30
- package/package.json +5 -4
package/build.log
CHANGED
package/dist/index.js
CHANGED
|
@@ -7,11 +7,54 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { AdminForthFilterOperators, AdminForthPlugin, Filters } from "adminforth";
|
|
10
|
+
import { AdminForthFilterOperators, AdminForthPlugin, parseBody, Filters } from "adminforth";
|
|
11
11
|
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.any().optional(),
|
|
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,21 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
771
814
|
server.endpoint({
|
|
772
815
|
method: 'POST',
|
|
773
816
|
path: `/plugin/${this.pluginInstanceId}/get_records`,
|
|
774
|
-
handler: (
|
|
775
|
-
|
|
776
|
-
if (
|
|
817
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response }) {
|
|
818
|
+
const parsed = parseBody(getRecordsBodySchema, body, response);
|
|
819
|
+
if ('error' in parsed)
|
|
820
|
+
return parsed.error;
|
|
821
|
+
const data = parsed.data;
|
|
822
|
+
if (!Array.isArray(data.record)) {
|
|
777
823
|
return { records: [] };
|
|
778
824
|
}
|
|
779
825
|
let records = [];
|
|
780
826
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
781
|
-
records = yield this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name,
|
|
827
|
+
records = yield this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name, data.record)]);
|
|
782
828
|
for (const [index, record] of records.entries()) {
|
|
783
829
|
records[index]._label = this.resourceConfig.recordLabel(records[index]);
|
|
784
830
|
}
|
|
785
|
-
const order = Object.fromEntries(
|
|
831
|
+
const order = Object.fromEntries(data.record.map((id, i) => [id, i]));
|
|
786
832
|
const sortedRecords = records.sort((a, b) => order[a.id] - order[b.id]);
|
|
787
833
|
return {
|
|
788
834
|
records: sortedRecords,
|
|
@@ -792,8 +838,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
792
838
|
server.endpoint({
|
|
793
839
|
method: 'POST',
|
|
794
840
|
path: `/plugin/${this.pluginInstanceId}/get_old_data`,
|
|
795
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body }) {
|
|
796
|
-
const
|
|
841
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response }) {
|
|
842
|
+
const parsed = parseBody(getOldDataBodySchema, body, response);
|
|
843
|
+
if ('error' in parsed)
|
|
844
|
+
return parsed.error;
|
|
845
|
+
const data = parsed.data;
|
|
846
|
+
const recordId = data.recordId;
|
|
797
847
|
if (recordId === undefined || recordId === null) {
|
|
798
848
|
return { ok: false, error: "Missing recordId" };
|
|
799
849
|
}
|
|
@@ -810,10 +860,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
810
860
|
server.endpoint({
|
|
811
861
|
method: 'POST',
|
|
812
862
|
path: `/plugin/${this.pluginInstanceId}/get_images`,
|
|
813
|
-
handler: (
|
|
863
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response }) {
|
|
864
|
+
const parsed = parseBody(getImagesBodySchema, body, response);
|
|
865
|
+
if ('error' in parsed)
|
|
866
|
+
return parsed.error;
|
|
867
|
+
const data = parsed.data;
|
|
814
868
|
let images = [];
|
|
815
|
-
if (
|
|
816
|
-
for (const record of
|
|
869
|
+
if (data.record) {
|
|
870
|
+
for (const record of data.record) {
|
|
817
871
|
if (this.options.attachFiles) {
|
|
818
872
|
images.push(yield this.options.attachFiles({ record: record }));
|
|
819
873
|
}
|
|
@@ -827,15 +881,19 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
827
881
|
server.endpoint({
|
|
828
882
|
method: 'POST',
|
|
829
883
|
path: `/plugin/${this.pluginInstanceId}/update_fields`,
|
|
830
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
|
|
884
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
885
|
+
const parsed = parseBody(updateFieldsBodySchema, body, response);
|
|
886
|
+
if ('error' in parsed)
|
|
887
|
+
return parsed.error;
|
|
888
|
+
const data = parsed.data;
|
|
831
889
|
let isAllowedToSave = { ok: true, error: '' };
|
|
832
890
|
if (this.options.isAllowedToSave) {
|
|
833
891
|
isAllowedToSave = yield this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
|
|
834
892
|
}
|
|
835
893
|
if (isAllowedToSave.ok !== false) {
|
|
836
|
-
const selectedIds =
|
|
837
|
-
const fieldsToUpdate =
|
|
838
|
-
const saveImages =
|
|
894
|
+
const selectedIds = data.selectedIds || [];
|
|
895
|
+
const fieldsToUpdate = data.fields || {};
|
|
896
|
+
const saveImages = data.saveImages;
|
|
839
897
|
const outputImageFields = [];
|
|
840
898
|
if (this.options.generateImages) {
|
|
841
899
|
for (const [key, value] of Object.entries(this.options.generateImages)) {
|
|
@@ -928,10 +986,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
928
986
|
server.endpoint({
|
|
929
987
|
method: 'POST',
|
|
930
988
|
path: `/plugin/${this.pluginInstanceId}/get_image_generation_prompts`,
|
|
931
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, headers }) {
|
|
989
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, headers, response }) {
|
|
932
990
|
var _b;
|
|
933
|
-
const
|
|
934
|
-
|
|
991
|
+
const parsed = parseBody(getImageGenerationPromptsBodySchema, body, response);
|
|
992
|
+
if ('error' in parsed)
|
|
993
|
+
return parsed.error;
|
|
994
|
+
const data = parsed.data;
|
|
995
|
+
const Id = data.recordId || [];
|
|
996
|
+
const customPrompt = data.customPrompt || null;
|
|
935
997
|
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
998
|
const compiledGenerationOptions = yield this.compileGenerationFieldTemplates(record, JSON.stringify({ "prompt": customPrompt }));
|
|
937
999
|
return compiledGenerationOptions;
|
|
@@ -951,8 +1013,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
951
1013
|
server.endpoint({
|
|
952
1014
|
method: 'POST',
|
|
953
1015
|
path: `/plugin/${this.pluginInstanceId}/create-job`,
|
|
954
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
|
|
955
|
-
const
|
|
1016
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1017
|
+
const parsed = parseBody(createJobBodySchema, body, response);
|
|
1018
|
+
if ('error' in parsed)
|
|
1019
|
+
return parsed.error;
|
|
1020
|
+
const data = parsed.data;
|
|
1021
|
+
const { actionType, recordId, customPrompt, filterFilledFields, sessionIds } = data;
|
|
956
1022
|
if (this.options.rateLimits) {
|
|
957
1023
|
if (sessionIds && sessionIds.length > 0) {
|
|
958
1024
|
for (const sessionId of sessionIds) {
|
|
@@ -988,15 +1054,15 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
988
1054
|
this.analyze_image(jobId, recordId, adminUser, headers, customPrompt, filterFilledFields);
|
|
989
1055
|
break;
|
|
990
1056
|
case 'regenerate_images':
|
|
991
|
-
if (!
|
|
1057
|
+
if (!data.prompt || !data.fieldName) {
|
|
992
1058
|
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
993
1059
|
break;
|
|
994
1060
|
}
|
|
995
|
-
this.regenerateImage(jobId, recordId,
|
|
1061
|
+
this.regenerateImage(jobId, recordId, data.fieldName, data.prompt, adminUser, headers);
|
|
996
1062
|
break;
|
|
997
1063
|
case 'regenerate_cell':
|
|
998
|
-
const fieldToRegenerate =
|
|
999
|
-
this.regenerateCell(jobId, fieldToRegenerate, recordId,
|
|
1064
|
+
const fieldToRegenerate = data.fieldToRegenerate;
|
|
1065
|
+
this.regenerateCell(jobId, fieldToRegenerate, recordId, data.action, data.prompt);
|
|
1000
1066
|
break;
|
|
1001
1067
|
default:
|
|
1002
1068
|
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
@@ -1011,7 +1077,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1011
1077
|
method: 'POST',
|
|
1012
1078
|
path: `/plugin/${this.pluginInstanceId}/get-job-status`,
|
|
1013
1079
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1014
|
-
const
|
|
1080
|
+
const parsed = parseBody(jobStatusBodySchema, body, response);
|
|
1081
|
+
if ('error' in parsed)
|
|
1082
|
+
return parsed.error;
|
|
1083
|
+
const data = parsed.data;
|
|
1084
|
+
const jobId = data.jobId;
|
|
1015
1085
|
if (!jobId) {
|
|
1016
1086
|
response.setStatus(400);
|
|
1017
1087
|
return {
|
|
@@ -1043,9 +1113,13 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1043
1113
|
server.endpoint({
|
|
1044
1114
|
method: 'POST',
|
|
1045
1115
|
path: `/plugin/${this.pluginInstanceId}/update-rate-limits`,
|
|
1046
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
|
|
1116
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1047
1117
|
var _b, _c, _d;
|
|
1048
|
-
const
|
|
1118
|
+
const parsed = parseBody(updateRateLimitsBodySchema, body, response);
|
|
1119
|
+
if ('error' in parsed)
|
|
1120
|
+
return parsed.error;
|
|
1121
|
+
const data = parsed.data;
|
|
1122
|
+
const actionType = data.actionType;
|
|
1049
1123
|
const sessionId = randomUUID();
|
|
1050
1124
|
this.sessionIds.add(sessionId);
|
|
1051
1125
|
if (actionType === 'analyze' && ((_b = this.options.rateLimits) === null || _b === void 0 ? void 0 : _b.fillFieldsFromImages)) {
|
|
@@ -1070,10 +1144,14 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1070
1144
|
server.endpoint({
|
|
1071
1145
|
method: 'POST',
|
|
1072
1146
|
path: `/plugin/${this.pluginInstanceId}/compile_old_image_link`,
|
|
1073
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
|
|
1147
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, response }) {
|
|
1074
1148
|
var _b, _c;
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1149
|
+
const parsed = parseBody(compileOldImageLinkBodySchema, body, response);
|
|
1150
|
+
if ('error' in parsed)
|
|
1151
|
+
return parsed.error;
|
|
1152
|
+
const data = parsed.data;
|
|
1153
|
+
const image = data.image;
|
|
1154
|
+
const columnName = data.columnName;
|
|
1077
1155
|
if (!image) {
|
|
1078
1156
|
return { ok: false, error: "Can't find image url" };
|
|
1079
1157
|
}
|
|
@@ -1099,8 +1177,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1099
1177
|
server.endpoint({
|
|
1100
1178
|
method: 'POST',
|
|
1101
1179
|
path: `/plugin/${this.pluginInstanceId}/get_filtered_ids`,
|
|
1102
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, query, cookies, requestUrl }) {
|
|
1180
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers, query, cookies, requestUrl, response }) {
|
|
1103
1181
|
var _b, _c;
|
|
1182
|
+
const parsed = parseBody(getFilteredIdsBodySchema, body, response);
|
|
1183
|
+
if ('error' in parsed)
|
|
1184
|
+
return parsed.error;
|
|
1185
|
+
const data = parsed.data;
|
|
1104
1186
|
const resource = this.resourceConfig;
|
|
1105
1187
|
for (const hook of ((_c = (_b = resource.hooks) === null || _b === void 0 ? void 0 : _b.list) === null || _c === void 0 ? void 0 : _c.beforeDatasourceRequest) || []) {
|
|
1106
1188
|
const filterTools = filtersTools.get(body);
|
package/index.ts
CHANGED
|
@@ -1,10 +1,63 @@
|
|
|
1
|
-
import { AdminForthFilterOperators, AdminForthPlugin, Filters } from "adminforth";
|
|
1
|
+
import { AdminForthFilterOperators, AdminForthPlugin, parseBody, Filters } from "adminforth";
|
|
2
2
|
import type { IAdminForth, IHttpServer, AdminForthComponentDeclaration, AdminForthResource } from "adminforth";
|
|
3
3
|
import { suggestIfTypo, filtersTools } from "adminforth";
|
|
4
4
|
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.any().optional(),
|
|
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 {
|
|
@@ -779,17 +832,20 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
779
832
|
server.endpoint({
|
|
780
833
|
method: 'POST',
|
|
781
834
|
path: `/plugin/${this.pluginInstanceId}/get_records`,
|
|
782
|
-
handler: async ( body ) => {
|
|
783
|
-
|
|
835
|
+
handler: async ({ body, response }) => {
|
|
836
|
+
const parsed = parseBody(getRecordsBodySchema, body, response);
|
|
837
|
+
if ('error' in parsed) return parsed.error;
|
|
838
|
+
const data = parsed.data;
|
|
839
|
+
if (!Array.isArray(data.record)) {
|
|
784
840
|
return { records: [] };
|
|
785
841
|
}
|
|
786
842
|
let records = [];
|
|
787
843
|
const primaryKeyColumn = this.resourceConfig.columns.find((col) => col.primaryKey);
|
|
788
|
-
records = await this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name,
|
|
844
|
+
records = await this.adminforth.resource(this.resourceConfig.resourceId).list([Filters.IN(primaryKeyColumn.name, data.record)]);
|
|
789
845
|
for( const [index, record] of records.entries() ) {
|
|
790
846
|
records[index]._label = this.resourceConfig.recordLabel(records[index]);
|
|
791
847
|
}
|
|
792
|
-
const order = Object.fromEntries(
|
|
848
|
+
const order = Object.fromEntries(data.record.map((id, i) => [id, i]));
|
|
793
849
|
|
|
794
850
|
const sortedRecords = records.sort(
|
|
795
851
|
(a, b) => order[a.id] - order[b.id]
|
|
@@ -804,8 +860,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
804
860
|
server.endpoint({
|
|
805
861
|
method: 'POST',
|
|
806
862
|
path: `/plugin/${this.pluginInstanceId}/get_old_data`,
|
|
807
|
-
handler: async ({ body }) => {
|
|
808
|
-
const
|
|
863
|
+
handler: async ({ body, response }) => {
|
|
864
|
+
const parsed = parseBody(getOldDataBodySchema, body, response);
|
|
865
|
+
if ('error' in parsed) return parsed.error;
|
|
866
|
+
const data = parsed.data;
|
|
867
|
+
const recordId = data.recordId;
|
|
809
868
|
if (recordId === undefined || recordId === null) {
|
|
810
869
|
return { ok: false, error: "Missing recordId" };
|
|
811
870
|
}
|
|
@@ -824,10 +883,13 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
824
883
|
server.endpoint({
|
|
825
884
|
method: 'POST',
|
|
826
885
|
path: `/plugin/${this.pluginInstanceId}/get_images`,
|
|
827
|
-
handler: async ( body ) => {
|
|
886
|
+
handler: async ({ body, response }) => {
|
|
887
|
+
const parsed = parseBody(getImagesBodySchema, body, response);
|
|
888
|
+
if ('error' in parsed) return parsed.error;
|
|
889
|
+
const data = parsed.data;
|
|
828
890
|
let images = [];
|
|
829
|
-
if(
|
|
830
|
-
for( const record of
|
|
891
|
+
if(data.record){
|
|
892
|
+
for( const record of data.record ) {
|
|
831
893
|
if (this.options.attachFiles) {
|
|
832
894
|
images.push(await this.options.attachFiles({ record: record }));
|
|
833
895
|
}
|
|
@@ -843,15 +905,18 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
843
905
|
server.endpoint({
|
|
844
906
|
method: 'POST',
|
|
845
907
|
path: `/plugin/${this.pluginInstanceId}/update_fields`,
|
|
846
|
-
handler: async ({ body, adminUser, headers }) => {
|
|
908
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
909
|
+
const parsed = parseBody(updateFieldsBodySchema, body, response);
|
|
910
|
+
if ('error' in parsed) return parsed.error;
|
|
911
|
+
const data = parsed.data;
|
|
847
912
|
let isAllowedToSave: any = { ok: true, error: '' };
|
|
848
913
|
if(this.options.isAllowedToSave) {
|
|
849
914
|
isAllowedToSave = await this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
|
|
850
915
|
}
|
|
851
916
|
if (isAllowedToSave.ok !== false) {
|
|
852
|
-
const selectedIds =
|
|
853
|
-
const fieldsToUpdate =
|
|
854
|
-
const saveImages =
|
|
917
|
+
const selectedIds = data.selectedIds || [];
|
|
918
|
+
const fieldsToUpdate = data.fields || {};
|
|
919
|
+
const saveImages = data.saveImages;
|
|
855
920
|
const outputImageFields = [];
|
|
856
921
|
if (this.options.generateImages) {
|
|
857
922
|
for (const [key, value] of Object.entries(this.options.generateImages)) {
|
|
@@ -950,9 +1015,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
950
1015
|
server.endpoint({
|
|
951
1016
|
method: 'POST',
|
|
952
1017
|
path: `/plugin/${this.pluginInstanceId}/get_image_generation_prompts`,
|
|
953
|
-
handler: async ({ body, headers }) => {
|
|
954
|
-
const
|
|
955
|
-
|
|
1018
|
+
handler: async ({ body, headers, response }) => {
|
|
1019
|
+
const parsed = parseBody(getImageGenerationPromptsBodySchema, body, response);
|
|
1020
|
+
if ('error' in parsed) return parsed.error;
|
|
1021
|
+
const data = parsed.data;
|
|
1022
|
+
const Id = data.recordId || [];
|
|
1023
|
+
const customPrompt = data.customPrompt || null;
|
|
956
1024
|
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.resourceConfig.columns.find(c => c.primaryKey)?.name, Id)]);
|
|
957
1025
|
const compiledGenerationOptions = await this.compileGenerationFieldTemplates(record, JSON.stringify({"prompt": customPrompt}));
|
|
958
1026
|
return compiledGenerationOptions;
|
|
@@ -976,8 +1044,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
976
1044
|
server.endpoint({
|
|
977
1045
|
method: 'POST',
|
|
978
1046
|
path: `/plugin/${this.pluginInstanceId}/create-job`,
|
|
979
|
-
handler: async ({ body, adminUser, headers }) => {
|
|
980
|
-
const
|
|
1047
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
1048
|
+
const parsed = parseBody(createJobBodySchema, body, response);
|
|
1049
|
+
if ('error' in parsed) return parsed.error;
|
|
1050
|
+
const data = parsed.data;
|
|
1051
|
+
const { actionType, recordId, customPrompt, filterFilledFields, sessionIds } = data;
|
|
981
1052
|
if (this.options.rateLimits) {
|
|
982
1053
|
if (sessionIds && sessionIds.length > 0) {
|
|
983
1054
|
for (const sessionId of sessionIds) {
|
|
@@ -1011,15 +1082,15 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1011
1082
|
this.analyze_image(jobId, recordId, adminUser, headers, customPrompt, filterFilledFields);
|
|
1012
1083
|
break;
|
|
1013
1084
|
case 'regenerate_images':
|
|
1014
|
-
if (!
|
|
1085
|
+
if (!data.prompt || !data.fieldName) {
|
|
1015
1086
|
jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
|
|
1016
1087
|
break;
|
|
1017
1088
|
}
|
|
1018
|
-
this.regenerateImage(jobId, recordId,
|
|
1089
|
+
this.regenerateImage(jobId, recordId, data.fieldName, data.prompt, adminUser, headers);
|
|
1019
1090
|
break;
|
|
1020
1091
|
case 'regenerate_cell':
|
|
1021
|
-
const fieldToRegenerate =
|
|
1022
|
-
this.regenerateCell(jobId, fieldToRegenerate, recordId,
|
|
1092
|
+
const fieldToRegenerate = data.fieldToRegenerate;
|
|
1093
|
+
this.regenerateCell(jobId, fieldToRegenerate, recordId, data.action, data.prompt);
|
|
1023
1094
|
break;
|
|
1024
1095
|
default:
|
|
1025
1096
|
jobs.set(jobId, { status: "failed", error: "Unknown action type" });
|
|
@@ -1036,7 +1107,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1036
1107
|
method: 'POST',
|
|
1037
1108
|
path: `/plugin/${this.pluginInstanceId}/get-job-status`,
|
|
1038
1109
|
handler: async ({ body, adminUser, headers, response }) => {
|
|
1039
|
-
const
|
|
1110
|
+
const parsed = parseBody(jobStatusBodySchema, body, response);
|
|
1111
|
+
if ('error' in parsed) return parsed.error;
|
|
1112
|
+
const data = parsed.data;
|
|
1113
|
+
const jobId = data.jobId;
|
|
1040
1114
|
if (!jobId) {
|
|
1041
1115
|
response.setStatus(400);
|
|
1042
1116
|
|
|
@@ -1073,8 +1147,11 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1073
1147
|
server.endpoint({
|
|
1074
1148
|
method: 'POST',
|
|
1075
1149
|
path: `/plugin/${this.pluginInstanceId}/update-rate-limits`,
|
|
1076
|
-
handler: async ({ body, adminUser, headers }) => {
|
|
1077
|
-
const
|
|
1150
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
1151
|
+
const parsed = parseBody(updateRateLimitsBodySchema, body, response);
|
|
1152
|
+
if ('error' in parsed) return parsed.error;
|
|
1153
|
+
const data = parsed.data;
|
|
1154
|
+
const actionType = data.actionType;
|
|
1078
1155
|
const sessionId = randomUUID();
|
|
1079
1156
|
this.sessionIds.add(sessionId);
|
|
1080
1157
|
if (actionType === 'analyze' && this.options.rateLimits?.fillFieldsFromImages) {
|
|
@@ -1101,9 +1178,12 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1101
1178
|
server.endpoint({
|
|
1102
1179
|
method: 'POST',
|
|
1103
1180
|
path: `/plugin/${this.pluginInstanceId}/compile_old_image_link`,
|
|
1104
|
-
handler: async ({ body, adminUser, headers }) => {
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1181
|
+
handler: async ({ body, adminUser, headers, response }) => {
|
|
1182
|
+
const parsed = parseBody(compileOldImageLinkBodySchema, body, response);
|
|
1183
|
+
if ('error' in parsed) return parsed.error;
|
|
1184
|
+
const data = parsed.data;
|
|
1185
|
+
const image = data.image;
|
|
1186
|
+
const columnName = data.columnName;
|
|
1107
1187
|
if (!image) {
|
|
1108
1188
|
return { ok: false, error: "Can't find image url" };
|
|
1109
1189
|
}
|
|
@@ -1131,7 +1211,10 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
|
|
|
1131
1211
|
server.endpoint({
|
|
1132
1212
|
method: 'POST',
|
|
1133
1213
|
path: `/plugin/${this.pluginInstanceId}/get_filtered_ids`,
|
|
1134
|
-
handler: async ({ body, adminUser, headers, query, cookies, requestUrl }) => {
|
|
1214
|
+
handler: async ({ body, adminUser, headers, query, cookies, requestUrl, response }) => {
|
|
1215
|
+
const parsed = parseBody(getFilteredIdsBodySchema, body, response);
|
|
1216
|
+
if ('error' in parsed) return parsed.error;
|
|
1217
|
+
const data = parsed.data;
|
|
1135
1218
|
const resource = this.resourceConfig;
|
|
1136
1219
|
|
|
1137
1220
|
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.0",
|
|
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.7.1",
|
|
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.7.1"
|
|
39
40
|
},
|
|
40
41
|
"release": {
|
|
41
42
|
"plugins": [
|