add format prompt values to prompt template

This commit is contained in:
Henry
2023-04-18 23:27:05 +01:00
parent cd8a5b96eb
commit 17207e01db
13 changed files with 675 additions and 599 deletions
+30 -25
View File
@@ -12,7 +12,7 @@ import {
getEndingNode,
constructGraphs,
resolveVariables,
checkIfFlowNeedToRebuild
checkStartNodeDependOnInput
} from './utils'
import { cloneDeep } from 'lodash'
import { getDataSource } from './DataSource'
@@ -203,6 +203,7 @@ export class App {
let nodeToExecuteData: INodeData
/*** Get chatflows and prepare data ***/
const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({
id: chatflowid
})
@@ -213,36 +214,40 @@ export class App {
const nodes = parsedFlowData.nodes
const edges = parsedFlowData.edges
// Check if node data exists in pool && not out of sync, prevent building whole flow again
/*** Get Ending Node with Directed Graph ***/
const { graph, nodeDependencies } = constructGraphs(nodes, edges)
const directedGraph = graph
const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
if (!endingNodeId) return res.status(500).send(`Ending node must be either a Chain or Agent`)
const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
if (!endingNodeData) return res.status(500).send(`Ending node must be either a Chain or Agent`)
if (endingNodeData.outputs && !Object.values(endingNodeData.outputs).includes(endingNodeData.name)) {
return res
.status(500)
.send(
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
)
}
/*** Get Starting Nodes with Non-Directed Graph ***/
const constructedObj = constructGraphs(nodes, edges, true)
const nonDirectedGraph = constructedObj.graph
const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
/* Check if:
* - Node Data already exists in pool
* - Still in sync (i.e the flow has not been modified since)
* - Flow doesn't start with nodes that depend on incomingInput.question
***/
if (
Object.prototype.hasOwnProperty.call(this.chatflowPool.activeChatflows, chatflowid) &&
this.chatflowPool.activeChatflows[chatflowid].inSync &&
!checkIfFlowNeedToRebuild(nodes, this.chatflowPool.activeChatflows[chatflowid].endingNodeData)
!checkStartNodeDependOnInput(nodes, startingNodeIds)
) {
nodeToExecuteData = this.chatflowPool.activeChatflows[chatflowid].endingNodeData
} else {
/*** Get Ending Node with Directed Graph ***/
const { graph, nodeDependencies } = constructGraphs(nodes, edges)
const directedGraph = graph
const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
if (!endingNodeId) return res.status(500).send(`Ending node must be either a Chain or Agent`)
const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
if (!endingNodeData) return res.status(500).send(`Ending node must be either a Chain or Agent`)
if (endingNodeData.outputs && !Object.values(endingNodeData.outputs).includes(endingNodeData.name)) {
return res
.status(500)
.send(
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
)
}
/*** Get Starting Nodes with Non-Directed Graph ***/
const constructedObj = constructGraphs(nodes, edges, true)
const nonDirectedGraph = constructedObj.graph
const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
/*** BFS to traverse from Starting Nodes to Ending Node ***/
const reactFlowNodes = await buildLangchain(
startingNodeIds,
+9 -12
View File
@@ -13,7 +13,7 @@ import {
INodeData
} from '../Interface'
import { cloneDeep, get } from 'lodash'
import { ICommonObject } from 'flowise-components'
import { ICommonObject, getInputVariables } from 'flowise-components'
const QUESTION_VAR_PREFIX = 'question'
@@ -351,19 +351,16 @@ export const resolveVariables = (reactFlowNodeData: INodeData, reactFlowNodes: I
* Rebuild flow if LLMChain has dependency on other chains
* User Question => Prompt_0 => LLMChain_0 => Prompt-1 => LLMChain_1
* @param {IReactFlowNode[]} nodes
* @param {INodeData} nodeData
* @param {string[]} startingNodeIds
* @returns {boolean}
*/
export const checkIfFlowNeedToRebuild = (nodes: IReactFlowNode[], nodeData: INodeData) => {
if (nodeData.name !== 'llmChain') return false
const node = nodes.find((nd) => nd.id === nodeData.id)
if (!node) throw new Error(`Node ${nodeData.id} not found`)
const inputs = node.data.inputs
for (const key in inputs) {
const isInputAcceptVariable = node.data.inputParams.find((param) => param.name === key)?.acceptVariable || false
if (isInputAcceptVariable && inputs[key].includes('{{') && inputs[key].includes('}}')) return true
export const checkStartNodeDependOnInput = (nodes: IReactFlowNode[], startingNodeIds: string[]) => {
const startingNodes = nodes.filter((nd) => startingNodeIds.includes(nd.id) && nd.id.toLowerCase().includes('prompttemplate'))
for (const node of startingNodes) {
for (const inputName in node.data.inputs) {
const inputVariables = getInputVariables(node.data.inputs[inputName])
if (inputVariables.length > 0) return true
}
}
return false
}