@@ -8,7 +8,7 @@ import TurndownService from 'turndown'
8
8
import { DataSource , Equal } from 'typeorm'
9
9
import { ICommonObject , IDatabaseEntity , IFileUpload , IMessage , INodeData , IVariable , MessageContentImageUrl } from './Interface'
10
10
import { AES , enc } from 'crypto-js'
11
- import { omit } from 'lodash'
11
+ import { omit , get } from 'lodash'
12
12
import { AIMessage , HumanMessage , BaseMessage } from '@langchain/core/messages'
13
13
import { Document } from '@langchain/core/documents'
14
14
import { getFileFromStorage } from './storageUtils'
@@ -1609,3 +1609,50 @@ export const createCodeExecutionSandbox = (
1609
1609
1610
1610
return sandbox
1611
1611
}
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