@@ -416,21 +416,6 @@ export class Serializer {
416416 return
417417 }
418418
419- // Get the tool configuration to check parameter visibility
420- const toolAccess = blockConfig . tools ?. access
421- if ( ! toolAccess || toolAccess . length === 0 ) {
422- return // No tools to validate against
423- }
424-
425- // Determine the current tool ID using the same logic as the serializer
426- const currentToolId = this . selectToolId ( blockConfig , params )
427-
428- // Get the specific tool to validate against
429- const currentTool = getTool ( currentToolId )
430- if ( ! currentTool ) {
431- return // Tool not found, skip validation
432- }
433-
434419 const missingFields : string [ ] = [ ]
435420 const displayAdvancedOptions = block . advancedMode ?? false
436421 const isTriggerContext = block . triggerMode ?? false
@@ -439,55 +424,105 @@ export class Serializer {
439424 const canonicalModeOverrides = block . data ?. canonicalModes
440425 const allValues = buildSubBlockValues ( block . subBlocks )
441426
442- // Iterate through the tool's parameters, not the block's subBlocks
443- Object . entries ( currentTool . params || { } ) . forEach ( ( [ paramId , paramConfig ] ) => {
444- if ( paramConfig . required && paramConfig . visibility === 'user-only' ) {
445- const matchingConfigs = blockConfig . subBlocks ?. filter ( ( sb : any ) => sb . id === paramId ) || [ ]
446-
447- let shouldValidateParam = true
448-
449- if ( matchingConfigs . length > 0 ) {
450- shouldValidateParam = matchingConfigs . some ( ( subBlockConfig : any ) => {
451- const includedByMode = shouldSerializeSubBlock (
452- subBlockConfig ,
453- allValues ,
454- displayAdvancedOptions ,
455- isTriggerContext ,
456- isTriggerCategory ,
457- canonicalIndex ,
458- canonicalModeOverrides
427+ // Get the tool configuration to check parameter visibility
428+ const toolAccess = blockConfig . tools ?. access
429+ const currentToolId = toolAccess ?. length > 0 ? this . selectToolId ( blockConfig , params ) : null
430+ const currentTool = currentToolId ? getTool ( currentToolId ) : null
431+
432+ // Validate tool parameters (for blocks with tools)
433+ if ( currentTool ) {
434+ Object . entries ( currentTool . params || { } ) . forEach ( ( [ paramId , paramConfig ] ) => {
435+ if ( paramConfig . required && paramConfig . visibility === 'user-only' ) {
436+ const matchingConfigs =
437+ blockConfig . subBlocks ?. filter ( ( sb : any ) => sb . id === paramId ) || [ ]
438+
439+ let shouldValidateParam = true
440+
441+ if ( matchingConfigs . length > 0 ) {
442+ shouldValidateParam = matchingConfigs . some ( ( subBlockConfig : any ) => {
443+ const includedByMode = shouldSerializeSubBlock (
444+ subBlockConfig ,
445+ allValues ,
446+ displayAdvancedOptions ,
447+ isTriggerContext ,
448+ isTriggerCategory ,
449+ canonicalIndex ,
450+ canonicalModeOverrides
451+ )
452+
453+ const isRequired = ( ( ) => {
454+ if ( ! subBlockConfig . required ) return false
455+ if ( typeof subBlockConfig . required === 'boolean' ) return subBlockConfig . required
456+ return evaluateSubBlockCondition ( subBlockConfig . required , params )
457+ } ) ( )
458+
459+ return includedByMode && isRequired
460+ } )
461+ }
462+
463+ if ( ! shouldValidateParam ) {
464+ return
465+ }
466+
467+ const fieldValue = params [ paramId ]
468+ if ( fieldValue === undefined || fieldValue === null || fieldValue === '' ) {
469+ const activeConfig = matchingConfigs . find ( ( config : any ) =>
470+ shouldSerializeSubBlock (
471+ config ,
472+ allValues ,
473+ displayAdvancedOptions ,
474+ isTriggerContext ,
475+ isTriggerCategory ,
476+ canonicalIndex ,
477+ canonicalModeOverrides
478+ )
459479 )
480+ const displayName = activeConfig ?. title || paramId
481+ missingFields . push ( displayName )
482+ }
483+ }
484+ } )
485+ }
460486
461- const isRequired = ( ( ) => {
462- if ( ! subBlockConfig . required ) return false
463- if ( typeof subBlockConfig . required === 'boolean' ) return subBlockConfig . required
464- return evaluateSubBlockCondition ( subBlockConfig . required , params )
465- } ) ( )
487+ // Validate required subBlocks not covered by tool params (e.g., blocks with empty tools.access)
488+ const validatedByTool = new Set ( currentTool ? Object . keys ( currentTool . params || { } ) : [ ] )
466489
467- return includedByMode && isRequired
468- } )
469- }
490+ blockConfig . subBlocks ?. forEach ( ( subBlockConfig : SubBlockConfig ) => {
491+ // Skip if already validated via tool params
492+ if ( validatedByTool . has ( subBlockConfig . id ) ) {
493+ return
494+ }
470495
471- if ( ! shouldValidateParam ) {
472- return
473- }
496+ // Check if subBlock is visible
497+ const isVisible = shouldSerializeSubBlock (
498+ subBlockConfig ,
499+ allValues ,
500+ displayAdvancedOptions ,
501+ isTriggerContext ,
502+ isTriggerCategory ,
503+ canonicalIndex ,
504+ canonicalModeOverrides
505+ )
506+
507+ if ( ! isVisible ) {
508+ return
509+ }
474510
475- const fieldValue = params [ paramId ]
476- if ( fieldValue === undefined || fieldValue === null || fieldValue === '' ) {
477- const activeConfig = matchingConfigs . find ( ( config : any ) =>
478- shouldSerializeSubBlock (
479- config ,
480- allValues ,
481- displayAdvancedOptions ,
482- isTriggerContext ,
483- isTriggerCategory ,
484- canonicalIndex ,
485- canonicalModeOverrides
486- )
487- )
488- const displayName = activeConfig ?. title || paramId
489- missingFields . push ( displayName )
490- }
511+ // Check if subBlock is required
512+ const isRequired = ( ( ) => {
513+ if ( ! subBlockConfig . required ) return false
514+ if ( typeof subBlockConfig . required === 'boolean' ) return subBlockConfig . required
515+ return evaluateSubBlockCondition ( subBlockConfig . required , params )
516+ } ) ( )
517+
518+ if ( ! isRequired ) {
519+ return
520+ }
521+
522+ // Check if value is missing
523+ const fieldValue = params [ subBlockConfig . id ]
524+ if ( fieldValue === undefined || fieldValue === null || fieldValue === '' ) {
525+ missingFields . push ( subBlockConfig . title || subBlockConfig . id )
491526 }
492527 } )
493528
0 commit comments