@@ -73,58 +73,30 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
7373 const columns = this . resourceConfig . columns ;
7474 let columnEnums = [ ] ;
7575 if ( this . options . fillFieldsFromImages ) {
76- if ( ! this . options . attachFiles ) {
77- throw new Error ( '⚠️ attachFiles function must be provided in options when fillFieldsFromImages is used' ) ;
78- }
79- if ( ! this . options . visionAdapter ) {
80- throw new Error ( '⚠️ visionAdapter must be provided in options when fillFieldsFromImages is used' ) ;
81- }
82-
8376 for ( const [ key , value ] of Object . entries ( ( this . options . fillFieldsFromImages ) ) ) {
8477 const column = columns . find ( c => c . name . toLowerCase ( ) === key . toLowerCase ( ) ) ;
85- if ( column ) {
86- if ( column . enum ) {
87- ( this . options . fillFieldsFromImages as any ) [ key ] = `${ value } Select ${ key } from the list (USE ONLY VALUE FIELD. USE ONLY VALUES FROM THIS LIST): ${ JSON . stringify ( column . enum ) } ` ;
88- columnEnums . push ( {
89- name : key ,
90- enum : column . enum ,
91- } ) ;
92- }
93- } else {
94- throw new Error ( `⚠️ No column found for key "${ key } "` ) ;
78+ if ( column && column . enum ) {
79+ ( this . options . fillFieldsFromImages as any ) [ key ] = `${ value } Select ${ key } from the list (USE ONLY VALUE FIELD. USE ONLY VALUES FROM THIS LIST): ${ JSON . stringify ( column . enum ) } ` ;
80+ columnEnums . push ( {
81+ name : key ,
82+ enum : column . enum ,
83+ } ) ;
9584 }
9685 }
9786 }
9887
9988 if ( this . options . fillPlainFields ) {
100- if ( ! this . options . textCompleteAdapter ) {
101- throw new Error ( '⚠️ textCompleteAdapter must be provided in options when fillPlainFields is used' ) ;
102- }
103-
10489 for ( const [ key , value ] of Object . entries ( ( this . options . fillPlainFields ) ) ) {
10590 const column = columns . find ( c => c . name . toLowerCase ( ) === key . toLowerCase ( ) ) ;
106- if ( column ) {
107- if ( column . enum ) {
108- ( this . options . fillPlainFields as any ) [ key ] = `${ value } Select ${ key } from the list (USE ONLY VALUE FIELD. USE ONLY VALUES FROM THIS LIST): ${ JSON . stringify ( column . enum ) } ` ;
109- columnEnums . push ( {
110- name : key ,
111- enum : column . enum ,
112- } ) ;
113- }
114- } else {
115- throw new Error ( `⚠️ No column found for key "${ key } "` ) ;
116- }
117- }
118- }
119-
120- if ( this . options . generateImages && ! this . options . imageGenerationAdapter ) {
121- for ( const [ key , value ] of Object . entries ( this . options . generateImages ) ) {
122- if ( ! this . options . generateImages [ key ] . adapter ) {
123- throw new Error ( `⚠️ No image generation adapter found for key "${ key } "` ) ;
91+ if ( column && column . enum ) {
92+ ( this . options . fillPlainFields as any ) [ key ] = `${ value } Select ${ key } from the list (USE ONLY VALUE FIELD. USE ONLY VALUES FROM THIS LIST): ${ JSON . stringify ( column . enum ) } ` ;
93+ columnEnums . push ( {
94+ name : key ,
95+ enum : column . enum ,
96+ } ) ;
12497 }
12598 }
126- }
127-
99+ }
128100
129101 const outputImageFields = [ ] ;
130102 if ( this . options . generateImages ) {
@@ -136,25 +108,13 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
136108 //check if Upload plugin is installed on all attachment fields
137109 if ( this . options . generateImages ) {
138110 for ( const [ key , value ] of Object . entries ( this . options . generateImages ) ) {
139- const column = columns . find ( c => c . name . toLowerCase ( ) === key . toLowerCase ( ) ) ;
140- if ( ! column ) {
141- throw new Error ( `⚠️ No column found for key "${ key } "` ) ;
142- }
143111 const plugin = adminforth . activatedPlugins . find ( p =>
144112 p . resourceConfig ! . resourceId === this . resourceConfig . resourceId &&
145113 p . pluginOptions . pathColumnName === key
146114 ) ;
147- if ( ! plugin ) {
148- throw new Error ( `Plugin for attachment field ' ${ key } ' not found in resource ' ${ this . resourceConfig . resourceId } ', please check if Upload Plugin is installed on the field ${ key } ` ) ;
115+ if ( plugin && plugin . pluginOptions . storageAdapter . objectCanBeAccesedPublicly ( ) ) {
116+ outputImagesPluginInstanceIds [ key ] = plugin . pluginInstanceId ;
149117 }
150- if ( ! plugin . pluginOptions . storageAdapter . objectCanBeAccesedPublicly ( ) ) {
151- throw new Error ( `Upload Plugin for attachment field '${ key } ' in resource '${ this . resourceConfig . resourceId } '
152- uses adapter which is not configured to store objects in public way, so it will produce only signed private URLs which can not be used in HTML text of blog posts.
153- Please configure adapter in such way that it will store objects publicly (e.g. for S3 use 'public-read' ACL).
154- ` ) ;
155- }
156-
157- outputImagesPluginInstanceIds [ key ] = plugin . pluginInstanceId ;
158118 }
159119 }
160120
@@ -168,7 +128,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
168128 const primaryKeyColumn = this . resourceConfig . columns . find ( ( col ) => col . primaryKey ) ;
169129
170130 const pageInjection = {
171- file : this . componentPath ( 'visionAction .vue' ) ,
131+ file : this . componentPath ( 'VisionAction .vue' ) ,
172132 meta : {
173133 pluginInstanceId : this . pluginInstanceId ,
174134 outputFields : outputFields ,
@@ -199,18 +159,65 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
199159 }
200160
201161 validateConfigAfterDiscover ( adminforth : IAdminForth , resourceConfig : AdminForthResource ) {
202- // optional method where you can safely check field types after database discovery was performed
162+ const columns = this . resourceConfig . columns ;
163+ if ( this . options . fillFieldsFromImages ) {
164+ if ( ! this . options . attachFiles ) {
165+ throw new Error ( '⚠️ attachFiles function must be provided when fillFieldsFromImages is used' ) ;
166+ }
167+ if ( ! this . options . visionAdapter ) {
168+ throw new Error ( '⚠️ visionAdapter must be provided when fillFieldsFromImages is used' ) ;
169+ }
170+ for ( const key of Object . keys ( this . options . fillFieldsFromImages ) ) {
171+ const column = columns . find ( c => c . name . toLowerCase ( ) === key . toLowerCase ( ) ) ;
172+ if ( ! column ) {
173+ throw new Error ( `⚠️ No column found for key "${ key } "` ) ;
174+ }
175+ }
176+ }
177+ if ( this . options . fillPlainFields ) {
178+ if ( ! this . options . textCompleteAdapter ) {
179+ throw new Error ( '⚠️ textCompleteAdapter must be provided when fillPlainFields is used' ) ;
180+ }
181+ for ( const key of Object . keys ( this . options . fillPlainFields ) ) {
182+ const column = columns . find ( c => c . name . toLowerCase ( ) === key . toLowerCase ( ) ) ;
183+ if ( ! column ) {
184+ throw new Error ( `⚠️ No column found for key "${ key } "` ) ;
185+ }
186+ }
187+ }
188+ if ( this . options . generateImages ) {
189+ for ( const key of Object . keys ( this . options . generateImages ) ) {
190+ const column = columns . find ( c => c . name . toLowerCase ( ) === key . toLowerCase ( ) ) ;
191+ if ( ! column ) {
192+ throw new Error ( `⚠️ No column found for key "${ key } "` ) ;
193+ }
194+ const perKeyAdapter = this . options . generateImages [ key ] . adapter ;
195+ if ( ! perKeyAdapter && ! this . options . imageGenerationAdapter ) {
196+ throw new Error ( `⚠️ No image generation adapter provided for key "${ key } "` ) ;
197+ }
198+
199+ const plugin = adminforth . activatedPlugins . find ( p =>
200+ p . resourceConfig ! . resourceId === this . resourceConfig . resourceId &&
201+ p . pluginOptions . pathColumnName === key
202+ ) ;
203+ if ( ! plugin ) {
204+ throw new Error ( `Plugin for attachment field '${ key } ' not found in resource '${ this . resourceConfig . resourceId } ', please check if Upload Plugin is installed on the field ${ key } ` ) ;
205+ }
206+ if ( ! plugin . pluginOptions . storageAdapter . objectCanBeAccesedPublicly ( ) ) {
207+ throw new Error ( `Upload Plugin for attachment field '${ key } ' in resource '${ this . resourceConfig . resourceId } '
208+ uses adapter which is not configured to store objects in public way, so it will produce only signed private URLs which can not be used in HTML text of blog posts.
209+ Please configure adapter in such way that it will store objects publicly (e.g. for S3 use 'public-read' ACL).
210+ ` ) ;
211+ }
212+ }
213+ }
203214 }
204215
205216 instanceUniqueRepresentation ( pluginOptions : any ) : string {
206- // optional method to return unique string representation of plugin instance.
207- // Needed if plugin can have multiple instances on one resource
208217 return `${ this . pluginOptions . actionName } ` ;
209218 }
210219
211220 setupEndpoints ( server : IHttpServer ) {
212-
213-
214221 server . endpoint ( {
215222 method : 'POST' ,
216223 path : `/plugin/${ this . pluginInstanceId } /analyze` ,
@@ -224,7 +231,7 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
224231 const tasks = selectedIds . map ( async ( ID ) => {
225232 // Fetch the record using the provided ID
226233 const primaryKeyColumn = this . resourceConfig . columns . find ( ( col ) => col . primaryKey ) ;
227- const record = await this . adminforth . resource ( this . resourceConfig . resourceId ) . get ( [ Filters . EQ ( primaryKeyColumn . name , ID ) ] ) ;
234+ const record = await this . adminforth . resource ( this . resourceConfig . resourceId ) . get ( [ Filters . EQ ( primaryKeyColumn . name , ID ) ] ) ;
228235
229236 //recieve image URLs to analyze
230237 const attachmentFiles = await this . options . attachFiles ( { record : record } ) ;
@@ -274,26 +281,20 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
274281 }
275282 }
276283 const tasks = selectedIds . map ( async ( ID ) => {
277- // Fetch the record using the provided ID
278284 const primaryKeyColumn = this . resourceConfig . columns . find ( ( col ) => col . primaryKey ) ;
279285 const record = await this . adminforth . resource ( this . resourceConfig . resourceId ) . get ( [ Filters . EQ ( primaryKeyColumn . name , ID ) ] ) ;
280286
281- //create prompt for OpenAI
282287 const compiledOutputFields = this . compileOutputFieldsTemplatesNoImage ( record ) ;
283288 const prompt = `Analyze the following fields and return a single JSON in format like: {'param1': 'value1', 'param2': 'value2'}.
284289 Do NOT return array of objects. Do NOT include any Markdown, code blocks, explanations, or extra text. Only return valid JSON.
285290 Each object must contain the following fields: ${ JSON . stringify ( compiledOutputFields ) } Use the exact field names.
286291 If it's number field - return only number.` ;
287- //send prompt to OpenAI and get response
288292 const { content : chatResponse } = await this . options . textCompleteAdapter . complete ( prompt , [ ] , 500 ) ;
289-
290293 const resp : any = ( chatResponse as any ) . response ;
291294 const topLevelError = ( chatResponse as any ) . error ;
292295 if ( topLevelError || resp ?. error ) {
293296 throw new Error ( `ERROR: ${ JSON . stringify ( topLevelError || resp ?. error ) } ` ) ;
294297 }
295-
296- //parse response and update record
297298 const resData = JSON . parse ( chatResponse ) ;
298299
299300 return resData ;
@@ -304,8 +305,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
304305 return { result } ;
305306 }
306307 } ) ;
307-
308-
309308 server . endpoint ( {
310309 method : 'POST' ,
311310 path : `/plugin/${ this . pluginInstanceId } /get_records` ,
@@ -321,8 +320,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
321320 } ;
322321 }
323322 } ) ;
324-
325-
326323 server . endpoint ( {
327324 method : 'POST' ,
328325 path : `/plugin/${ this . pluginInstanceId } /get_images` ,
@@ -340,8 +337,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
340337 } ;
341338 }
342339 } ) ;
343-
344-
345340 server . endpoint ( {
346341 method : 'POST' ,
347342 path : `/plugin/${ this . pluginInstanceId } /update_fields` ,
@@ -396,8 +391,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
396391 }
397392 }
398393 } ) ;
399-
400-
401394 server . endpoint ( {
402395 method : 'POST' ,
403396 path : `/plugin/${ this . pluginInstanceId } /regenerate_images` ,
@@ -449,8 +442,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
449442 return { images } ;
450443 }
451444 } ) ;
452-
453-
454445 server . endpoint ( {
455446 method : 'POST' ,
456447 path : `/plugin/${ this . pluginInstanceId } /initial_image_generate` ,
@@ -518,8 +509,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
518509 return { result } ;
519510 }
520511 } ) ;
521-
522-
523512 server . endpoint ( {
524513 method : 'POST' ,
525514 path : `/plugin/${ this . pluginInstanceId } /get_generation_prompts` ,
@@ -530,8 +519,6 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
530519 return { generationOptions : compiledGenerationOptions } ;
531520 }
532521 } ) ;
533-
534-
535522 server . endpoint ( {
536523 method : 'GET' ,
537524 path : `/plugin/${ this . pluginInstanceId } /averageDuration` ,
@@ -543,8 +530,5 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
543530 } ;
544531 }
545532 } ) ;
546-
547-
548-
549533 }
550534}
0 commit comments