@@ -19,7 +19,9 @@ const logger = createLogger('FunctionExecuteAPI')
1919function resolveCodeVariables (
2020 code : string ,
2121 params : Record < string , any > ,
22- envVars : Record < string , string > = { }
22+ envVars : Record < string , string > = { } ,
23+ blockData : Record < string , any > = { } ,
24+ blockNameMapping : Record < string , string > = { }
2325) : { resolvedCode : string ; contextVariables : Record < string , any > } {
2426 let resolvedCode = code
2527 const contextVariables : Record < string , any > = { }
@@ -41,11 +43,54 @@ function resolveCodeVariables(
4143
4244 // Resolve tags with <tag_name> syntax (including nested paths like <block.response.data>)
4345 const tagMatches = resolvedCode . match ( / < ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ . ] * [ a - z A - Z 0 - 9 _ ] ) > / g) || [ ]
46+
47+
4448 for ( const match of tagMatches ) {
4549 const tagName = match . slice ( 1 , - 1 ) . trim ( )
4650
47- // Handle nested paths like "getrecord.response.data"
48- const tagValue = getNestedValue ( params , tagName ) || ''
51+
52+ // Handle nested paths like "getrecord.response.data" or "function1.response.result"
53+ // First try params, then blockData directly, then try with block name mapping
54+ let tagValue = getNestedValue ( params , tagName ) || getNestedValue ( blockData , tagName ) || ''
55+
56+ // If not found and the path starts with a block name, try mapping the block name to ID
57+ if ( ! tagValue && tagName . includes ( '.' ) ) {
58+ const pathParts = tagName . split ( '.' )
59+ const normalizedBlockName = pathParts [ 0 ] // This should already be normalized like "function1"
60+
61+ // Find the block ID by looking for a block name that normalizes to this value
62+ let blockId = null
63+ let matchedBlockName = null
64+
65+ for ( const [ blockName , id ] of Object . entries ( blockNameMapping ) ) {
66+ // Apply the same normalization logic as the UI: remove spaces and lowercase
67+ const normalizedName = blockName . replace ( / \s + / g, '' ) . toLowerCase ( )
68+ if ( normalizedName === normalizedBlockName ) {
69+ blockId = id
70+ matchedBlockName = blockName
71+ break
72+ }
73+ }
74+
75+ if ( blockId ) {
76+ const remainingPath = pathParts . slice ( 1 ) . join ( '.' )
77+ const fullPath = `${ blockId } .${ remainingPath } `
78+ tagValue = getNestedValue ( blockData , fullPath ) || ''
79+
80+ }
81+ }
82+
83+
84+
85+ // If the value is a stringified JSON, parse it back to object
86+ if ( typeof tagValue === 'string' && tagValue . length > 100 &&
87+ ( tagValue . startsWith ( '{' ) || tagValue . startsWith ( '[' ) ) ) {
88+ try {
89+ tagValue = JSON . parse ( tagValue )
90+ } catch ( e ) {
91+ // Keep as string if parsing fails
92+ }
93+ }
4994
5095 // Instead of injecting large JSON directly, create a variable reference
5196 const safeVarName = `__tag_${ tagName . replace ( / [ ^ a - z A - Z 0 - 9 _ ] / g, '_' ) } `
@@ -89,6 +134,8 @@ export async function POST(req: NextRequest) {
89134 params = { } ,
90135 timeout = 5000 ,
91136 envVars = { } ,
137+ blockData = { } ,
138+ blockNameMapping = { } ,
92139 workflowId,
93140 isCustomTool = false ,
94141 } = body
@@ -106,7 +153,14 @@ export async function POST(req: NextRequest) {
106153 } )
107154
108155 // Resolve variables in the code with workflow environment variables
109- const { resolvedCode, contextVariables } = resolveCodeVariables ( code , executionParams , envVars )
156+ logger . info ( `[${ requestId } ] Original code:` , code . substring ( 0 , 200 ) )
157+ logger . info ( `[${ requestId } ] Execution params keys:` , Object . keys ( executionParams ) )
158+
159+
160+ const { resolvedCode, contextVariables } = resolveCodeVariables ( code , executionParams , envVars , blockData , blockNameMapping )
161+
162+ logger . info ( `[${ requestId } ] Resolved code:` , resolvedCode . substring ( 0 , 200 ) )
163+ logger . info ( `[${ requestId } ] Context variables keys:` , Object . keys ( contextVariables ) )
110164
111165 const executionMethod = 'vm' // Default execution method
112166
0 commit comments