@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.
@@ -11,6 +11,7 @@
11
11
  "license": "ISC",
12
12
  "dependencies": {
13
13
  "@iconify-prerendered/vue-mdi": "^0.25.1718880438",
14
- "medium-zoom": "^1.1.0"
14
+ "medium-zoom": "^1.1.0",
15
+ "swiper": "^11.2.10"
15
16
  }
16
17
  }
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
- jobs.set(jobId, { status: 'completed', result: {} });
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 attachment files found" });
114
- return { ok: false, error: "No attachment files found" };
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
- jobs.set(jobId, { status: 'failed', error: "No attachment files found" });
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
- images = `https://pic.re/image`;
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
- jobs.set(jobId, { status: 'failed', error: "No attachment files found" });
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
- switch (actionType) {
604
- case 'generate_images':
605
- this.initialImageGenerate(jobId, recordId, adminUser, headers);
606
- break;
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
- this.regenerateImage(jobId, recordId, body.fieldName, body.prompt, adminUser, headers);
619
- break;
620
- default:
621
- jobs.set(jobId, { status: "failed", error: "Unknown action type" });
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
- jobs.set(jobId, { status: 'completed', result: {} });
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 attachment files found" });
126
- return { ok: false, error: "No attachment files found" };
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
- jobs.set(jobId, { status: 'failed', error: "No attachment files found" });
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
- images = `https://pic.re/image`;
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
- jobs.set(jobId, { status: 'failed', error: "No attachment files found" });
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
- switch(actionType) {
644
- case 'generate_images':
645
- this.initialImageGenerate(jobId, recordId, adminUser, headers);
646
- break;
647
- case 'analyze_no_images':
648
- this.analyzeNoImages(jobId, recordId, adminUser, headers);
649
- break;
650
- case 'analyze':
651
- this.analyze_image(jobId, recordId, adminUser, headers);
652
- break;
653
- case 'regenerate_images':
654
- if (!body.prompt || !body.fieldName) {
655
- jobs.set(jobId, { status: "failed", error: "Missing prompt or field name" });
656
- break;
657
- }
658
- this.regenerateImage(jobId, recordId, body.fieldName, body.prompt, adminUser, headers);
659
- break;
660
- default:
661
- jobs.set(jobId, { status: "failed", error: "Unknown action type" });
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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/bulk-ai-flow",
3
- "version": "1.10.2",
3
+ "version": "1.11.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },