@@ -783,6 +783,7 @@ async function handleBlockOperationTx(
783783
784784 const existingBlock = await tx
785785 . select ( {
786+ id : workflowBlocks . id ,
786787 type : workflowBlocks . type ,
787788 subBlocks : workflowBlocks . subBlocks ,
788789 data : workflowBlocks . data ,
@@ -799,12 +800,15 @@ async function handleBlockOperationTx(
799800 }
800801
801802 if ( existingBlock [ 0 ] ) {
802- await assertAgentToolPermissionModeEnabled ( [
803- {
804- ...existingBlock [ 0 ] ,
805- data : { ...currentData , canonicalModes } ,
806- } ,
807- ] )
803+ await assertAgentToolPermissionModeEnabled (
804+ [
805+ {
806+ ...existingBlock [ 0 ] ,
807+ data : { ...currentData , canonicalModes } ,
808+ } ,
809+ ] ,
810+ existingBlock
811+ )
808812 }
809813
810814 const updateResult = await tx
@@ -834,30 +838,48 @@ async function handleBlockOperationTx(
834838 throw new Error ( 'Missing required fields for replace canonical modes operation' )
835839 }
836840
837- const existingBlock = await tx
841+ const allBlocks = await tx
838842 . select ( {
843+ id : workflowBlocks . id ,
844+ locked : workflowBlocks . locked ,
839845 type : workflowBlocks . type ,
840846 subBlocks : workflowBlocks . subBlocks ,
841847 data : workflowBlocks . data ,
842848 } )
843849 . from ( workflowBlocks )
844- . where ( and ( eq ( workflowBlocks . id , payload . id ) , eq ( workflowBlocks . workflowId , workflowId ) ) )
845- . limit ( 1 )
850+ . where ( eq ( workflowBlocks . workflowId , workflowId ) )
851+ const blocksById = Object . fromEntries (
852+ allBlocks . map ( ( block : { id : string ; locked : boolean ; data : Record < string , unknown > } ) => [
853+ block . id ,
854+ block ,
855+ ] )
856+ )
857+ if ( isWorkflowBlockProtected ( payload . id , blocksById ) ) {
858+ throw new Error ( `Block ${ payload . id } is locked or inside a locked container` )
859+ }
860+ const existingBlock = allBlocks . filter ( ( block : { id : string } ) => block . id === payload . id )
846861
847862 const currentData = ( existingBlock ?. [ 0 ] ?. data as Record < string , unknown > ) || { }
848863
864+ const subBlocks = { ...( existingBlock [ 0 ] ?. subBlocks || { } ) , ...( payload . subBlocks || { } ) }
865+
849866 if ( existingBlock [ 0 ] ) {
850- await assertAgentToolPermissionModeEnabled ( [
851- {
852- ...existingBlock [ 0 ] ,
853- data : { ...currentData , canonicalModes : payload . data . canonicalModes } ,
854- } ,
855- ] )
867+ await assertAgentToolPermissionModeEnabled (
868+ [
869+ {
870+ ...existingBlock [ 0 ] ,
871+ subBlocks,
872+ data : { ...currentData , canonicalModes : payload . data . canonicalModes } ,
873+ } ,
874+ ] ,
875+ existingBlock
876+ )
856877 }
857878
858879 const updateResult = await tx
859880 . update ( workflowBlocks )
860881 . set ( {
882+ ...( payload . subBlocks ? { subBlocks } : { } ) ,
861883 data : {
862884 ...currentData ,
863885 canonicalModes : payload . data . canonicalModes ,
@@ -946,7 +968,13 @@ async function handleBlocksOperationTx(
946968 if ( blocks && blocks . length > 0 ) {
947969 // Fetch existing blocks to check for locked parents
948970 const existingBlocks = await tx
949- . select ( { id : workflowBlocks . id , locked : workflowBlocks . locked } )
971+ . select ( {
972+ id : workflowBlocks . id ,
973+ type : workflowBlocks . type ,
974+ subBlocks : workflowBlocks . subBlocks ,
975+ data : workflowBlocks . data ,
976+ locked : workflowBlocks . locked ,
977+ } )
950978 . from ( workflowBlocks )
951979 . where ( eq ( workflowBlocks . workflowId , workflowId ) )
952980
@@ -1002,7 +1030,7 @@ async function handleBlocksOperationTx(
10021030 }
10031031 } )
10041032
1005- await assertAgentToolPermissionModeEnabled ( blockValues )
1033+ await assertAgentToolPermissionModeEnabled ( blockValues , existingBlocks )
10061034
10071035 await tx
10081036 . insert ( workflowBlocks )
@@ -2076,7 +2104,7 @@ async function handleSubblockOperationTx(
20762104 : { id : subblockId , type : 'unknown' , value }
20772105
20782106 if ( subblockId === 'tools' ) {
2079- await assertAgentToolPermissionModeEnabled ( [ { ...block , subBlocks } ] )
2107+ await assertAgentToolPermissionModeEnabled ( [ { ...block , subBlocks } ] , [ block ] )
20802108 }
20812109
20822110 await tx
@@ -2190,7 +2218,16 @@ async function handleWorkflowOperationTx(
21902218 }
21912219
21922220 const { blocks, edges, loops, parallels } = payload . state
2193- await assertAgentToolPermissionModeEnabled ( Object . values ( blocks || { } ) )
2221+ const previousBlocks = await tx
2222+ . select ( {
2223+ id : workflowBlocks . id ,
2224+ type : workflowBlocks . type ,
2225+ subBlocks : workflowBlocks . subBlocks ,
2226+ data : workflowBlocks . data ,
2227+ } )
2228+ . from ( workflowBlocks )
2229+ . where ( eq ( workflowBlocks . workflowId , workflowId ) )
2230+ await assertAgentToolPermissionModeEnabled ( Object . values ( blocks || { } ) , previousBlocks )
21942231
21952232 logger . info ( `Replacing workflow state for ${ workflowId } ` , {
21962233 blockCount : Object . keys ( blocks || { } ) . length ,
0 commit comments