@@ -8,7 +8,7 @@ import TurndownService from 'turndown'
88import { DataSource , Equal } from 'typeorm'
99import { ICommonObject , IDatabaseEntity , IFileUpload , IMessage , INodeData , IVariable , MessageContentImageUrl } from './Interface'
1010import { AES , enc } from 'crypto-js'
11- import { omit } from 'lodash'
11+ import { omit , get } from 'lodash'
1212import { AIMessage , HumanMessage , BaseMessage } from '@langchain/core/messages'
1313import { Document } from '@langchain/core/documents'
1414import { getFileFromStorage } from './storageUtils'
@@ -1609,3 +1609,50 @@ export const createCodeExecutionSandbox = (
16091609
16101610 return sandbox
16111611}
1612+
1613+ /**
1614+ * Process template variables in state object, replacing {{ output }} and {{ output.property }} patterns
1615+ * @param {ICommonObject } state - The state object to process
1616+ * @param {any } finalOutput - The output value to substitute
1617+ * @returns {ICommonObject } - The processed state object
1618+ */
1619+ export const processTemplateVariables = ( state : ICommonObject , finalOutput : any ) : ICommonObject => {
1620+ if ( ! state || Object . keys ( state ) . length === 0 ) {
1621+ return state
1622+ }
1623+
1624+ const newState = { ...state }
1625+
1626+ for ( const key in newState ) {
1627+ const stateValue = newState [ key ] . toString ( )
1628+ if ( stateValue . includes ( '{{ output' ) || stateValue . includes ( '{{output' ) ) {
1629+ // Handle simple output replacement (with or without spaces)
1630+ if ( stateValue === '{{ output }}' || stateValue === '{{output}}' ) {
1631+ newState [ key ] = finalOutput
1632+ continue
1633+ }
1634+
1635+ // Handle JSON path expressions like {{ output.updated }} or {{output.updated}}
1636+ // eslint-disable-next-line
1637+ const match = stateValue . match ( / \{ \{ \s * o u t p u t \. ( [ \w \. ] + ) \s * \} \} / )
1638+ if ( match ) {
1639+ try {
1640+ // Parse the response if it's JSON
1641+ const jsonResponse = typeof finalOutput === 'string' ? JSON . parse ( finalOutput ) : finalOutput
1642+ // Get the value using lodash get
1643+ const path = match [ 1 ]
1644+ const value = get ( jsonResponse , path )
1645+ newState [ key ] = value ?? stateValue // Fall back to original if path not found
1646+ } catch ( e ) {
1647+ // If JSON parsing fails, keep original template
1648+ newState [ key ] = stateValue
1649+ }
1650+ } else {
1651+ // Handle simple {{ output }} replacement for backward compatibility
1652+ newState [ key ] = newState [ key ] . replaceAll ( '{{ output }}' , finalOutput )
1653+ }
1654+ }
1655+ }
1656+
1657+ return newState
1658+ }
0 commit comments