@@ -29,6 +29,93 @@ class GetBlocksMetadataTool extends BaseCopilotTool<GetBlocksMetadataParams, Blo
2929// Export the tool instance
3030export const getBlocksMetadataTool = new GetBlocksMetadataTool ( )
3131
32+ /**
33+ * Safely resolve subblock options, handling both static arrays and functions
34+ */
35+ function resolveSubBlockOptions ( options : any ) : any [ ] {
36+ try {
37+ if ( typeof options === 'function' ) {
38+ const resolved = options ( )
39+ return Array . isArray ( resolved ) ? resolved : [ ]
40+ }
41+ return Array . isArray ( options ) ? options : [ ]
42+ } catch ( error ) {
43+ logger . warn ( 'Failed to resolve subblock options:' , error )
44+ return [ ]
45+ }
46+ }
47+
48+ /**
49+ * Process subBlocks configuration to include all UI metadata
50+ */
51+ function processSubBlocks ( subBlocks : any [ ] ) : any [ ] {
52+ if ( ! Array . isArray ( subBlocks ) ) {
53+ return [ ]
54+ }
55+
56+ return subBlocks . map ( ( subBlock ) => {
57+ const processedSubBlock : any = {
58+ id : subBlock . id ,
59+ title : subBlock . title ,
60+ type : subBlock . type ,
61+ layout : subBlock . layout ,
62+ mode : subBlock . mode ,
63+ required : subBlock . required ,
64+ placeholder : subBlock . placeholder ,
65+ description : subBlock . description ,
66+ hidden : subBlock . hidden ,
67+ condition : subBlock . condition ,
68+ // Slider specific
69+ min : subBlock . min ,
70+ max : subBlock . max ,
71+ step : subBlock . step ,
72+ integer : subBlock . integer ,
73+ // Input specific
74+ rows : subBlock . rows ,
75+ password : subBlock . password ,
76+ multiSelect : subBlock . multiSelect ,
77+ // Code specific
78+ language : subBlock . language ,
79+ generationType : subBlock . generationType ,
80+ // OAuth specific
81+ provider : subBlock . provider ,
82+ serviceId : subBlock . serviceId ,
83+ requiredScopes : subBlock . requiredScopes ,
84+ // File specific
85+ mimeType : subBlock . mimeType ,
86+ acceptedTypes : subBlock . acceptedTypes ,
87+ multiple : subBlock . multiple ,
88+ maxSize : subBlock . maxSize ,
89+ // Other properties
90+ connectionDroppable : subBlock . connectionDroppable ,
91+ columns : subBlock . columns ,
92+ value : typeof subBlock . value === 'function' ? 'function' : undefined , // Don't serialize functions
93+ wandConfig : subBlock . wandConfig ,
94+ }
95+
96+ // Resolve options if present
97+ if ( subBlock . options ) {
98+ try {
99+ const resolvedOptions = resolveSubBlockOptions ( subBlock . options )
100+ processedSubBlock . options = resolvedOptions . map ( ( option ) => ( {
101+ label : option . label ,
102+ id : option . id ,
103+ // Note: Icons are React components, so we'll just indicate if they exist
104+ hasIcon : ! ! option . icon ,
105+ } ) )
106+ } catch ( error ) {
107+ logger . warn ( `Failed to resolve options for subBlock ${ subBlock . id } :` , error )
108+ processedSubBlock . options = [ ]
109+ }
110+ }
111+
112+ // Remove undefined properties to keep the response clean
113+ return Object . fromEntries (
114+ Object . entries ( processedSubBlock ) . filter ( ( [ _ , value ] ) => value !== undefined )
115+ )
116+ } )
117+ }
118+
32119// Implementation function
33120export async function getBlocksMetadata (
34121 params : GetBlocksMetadataParams
@@ -80,9 +167,23 @@ export async function getBlocksMetadata(
80167 id : blockId ,
81168 name : blockConfig . name || blockId ,
82169 description : blockConfig . description || '' ,
170+ longDescription : blockConfig . longDescription ,
171+ category : blockConfig . category ,
172+ bgColor : blockConfig . bgColor ,
83173 inputs : blockConfig . inputs || { } ,
84174 outputs : blockConfig . outputs || { } ,
85175 tools : blockConfig . tools ?. access || [ ] ,
176+ hideFromToolbar : blockConfig . hideFromToolbar ,
177+ }
178+
179+ // Process and include subBlocks configuration
180+ if ( blockConfig . subBlocks && Array . isArray ( blockConfig . subBlocks ) ) {
181+ logger . info ( `Processing ${ blockConfig . subBlocks . length } subBlocks for ${ blockId } ` )
182+ metadata . subBlocks = processSubBlocks ( blockConfig . subBlocks )
183+ logger . info ( `✓ Processed subBlocks for ${ blockId } :` , metadata . subBlocks . length )
184+ } else {
185+ logger . info ( `No subBlocks found for ${ blockId } ` )
186+ metadata . subBlocks = [ ]
86187 }
87188 }
88189
@@ -146,6 +247,7 @@ export async function getBlocksMetadata(
146247
147248 logger . info ( `Final metadata keys for ${ blockId } :` , Object . keys ( metadata ) )
148249 logger . info ( `Has YAML documentation: ${ ! ! metadata . yamlDocumentation } ` )
250+ logger . info ( `Has subBlocks: ${ ! ! metadata . subBlocks && metadata . subBlocks . length > 0 } ` )
149251
150252 result [ blockId ] = metadata
151253 }
@@ -214,6 +316,43 @@ const SPECIAL_BLOCKS_METADATA: Record<string, any> = {
214316 totalIterations : 'number' ,
215317 } ,
216318 tools : { access : [ ] } ,
319+ subBlocks : [
320+ {
321+ id : 'loopType' ,
322+ title : 'Loop Type' ,
323+ type : 'dropdown' ,
324+ required : true ,
325+ options : [
326+ { label : 'For Loop (count)' , id : 'for' } ,
327+ { label : 'For Each (collection)' , id : 'forEach' } ,
328+ ] ,
329+ } ,
330+ {
331+ id : 'iterations' ,
332+ title : 'Iterations' ,
333+ type : 'slider' ,
334+ min : 1 ,
335+ max : 1000 ,
336+ integer : true ,
337+ condition : { field : 'loopType' , value : 'for' } ,
338+ } ,
339+ {
340+ id : 'collection' ,
341+ title : 'Collection' ,
342+ type : 'short-input' ,
343+ placeholder : 'Array or object to iterate over...' ,
344+ condition : { field : 'loopType' , value : 'forEach' } ,
345+ } ,
346+ {
347+ id : 'maxConcurrency' ,
348+ title : 'Max Concurrency' ,
349+ type : 'slider' ,
350+ min : 1 ,
351+ max : 10 ,
352+ integer : true ,
353+ default : 1 ,
354+ } ,
355+ ] ,
217356 } ,
218357 parallel : {
219358 type : 'parallel' ,
@@ -232,5 +371,42 @@ const SPECIAL_BLOCKS_METADATA: Record<string, any> = {
232371 totalBranches : 'number' ,
233372 } ,
234373 tools : { access : [ ] } ,
374+ subBlocks : [
375+ {
376+ id : 'parallelType' ,
377+ title : 'Parallel Type' ,
378+ type : 'dropdown' ,
379+ required : true ,
380+ options : [
381+ { label : 'Count (number)' , id : 'count' } ,
382+ { label : 'Collection (array)' , id : 'collection' } ,
383+ ] ,
384+ } ,
385+ {
386+ id : 'count' ,
387+ title : 'Count' ,
388+ type : 'slider' ,
389+ min : 1 ,
390+ max : 100 ,
391+ integer : true ,
392+ condition : { field : 'parallelType' , value : 'count' } ,
393+ } ,
394+ {
395+ id : 'collection' ,
396+ title : 'Collection' ,
397+ type : 'short-input' ,
398+ placeholder : 'Array to process in parallel...' ,
399+ condition : { field : 'parallelType' , value : 'collection' } ,
400+ } ,
401+ {
402+ id : 'maxConcurrency' ,
403+ title : 'Max Concurrency' ,
404+ type : 'slider' ,
405+ min : 1 ,
406+ max : 50 ,
407+ integer : true ,
408+ default : 10 ,
409+ } ,
410+ ] ,
235411 } ,
236412}
0 commit comments