add vector to prompt

This commit is contained in:
Henry
2023-08-16 01:43:11 +01:00
parent af5efaa751
commit 94461025dc
11 changed files with 1194 additions and 40 deletions
+35 -7
View File
@@ -19,7 +19,14 @@ import {
ICredentialReqBody
} from '../Interface'
import { cloneDeep, get, omit, merge, isEqual } from 'lodash'
import { ICommonObject, getInputVariables, IDatabaseEntity, handleEscapeCharacters } from 'flowise-components'
import {
ICommonObject,
getInputVariables,
IDatabaseEntity,
handleEscapeCharacters,
IMessage,
convertChatHistoryToText
} from 'flowise-components'
import { scryptSync, randomBytes, timingSafeEqual } from 'crypto'
import { lib, PBKDF2, AES, enc } from 'crypto-js'
@@ -30,6 +37,7 @@ import { Tool } from '../entity/Tool'
import { DataSource } from 'typeorm'
const QUESTION_VAR_PREFIX = 'question'
const CHAT_HISTORY_VAR_PREFIX = 'chat_history'
const REDACTED_CREDENTIAL_VALUE = '_FLOWISE_BLANK_07167752-1a71-43b1-bf8f-4f32252165db'
export const databaseEntities: IDatabaseEntity = { ChatFlow: ChatFlow, ChatMessage: ChatMessage, Tool: Tool, Credential: Credential }
@@ -199,6 +207,7 @@ export const buildLangchain = async (
depthQueue: IDepthQueue,
componentNodes: IComponentNodes,
question: string,
chatHistory: IMessage[],
chatId: string,
appDataSource: DataSource,
overrideConfig?: ICommonObject
@@ -231,7 +240,7 @@ export const buildLangchain = async (
let flowNodeData = cloneDeep(reactFlowNode.data)
if (overrideConfig) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig)
const reactFlowNodeData: INodeData = resolveVariables(flowNodeData, flowNodes, question)
const reactFlowNodeData: INodeData = resolveVariables(flowNodeData, flowNodes, question, chatHistory)
logger.debug(`[server]: Initializing ${reactFlowNode.data.label} (${reactFlowNode.data.id})`)
flowNodes[nodeIndex].data.instance = await newNodeInstance.init(reactFlowNodeData, question, {
@@ -315,7 +324,13 @@ export const clearSessionMemory = async (
* @param {boolean} isAcceptVariable
* @returns {string}
*/
export const getVariableValue = (paramValue: string, reactFlowNodes: IReactFlowNode[], question: string, isAcceptVariable = false) => {
export const getVariableValue = (
paramValue: string,
reactFlowNodes: IReactFlowNode[],
question: string,
chatHistory: IMessage[],
isAcceptVariable = false
) => {
let returnVal = paramValue
const variableStack = []
const variableDict = {} as IVariableDict
@@ -345,6 +360,10 @@ export const getVariableValue = (paramValue: string, reactFlowNodes: IReactFlowN
variableDict[`{{${variableFullPath}}}`] = handleEscapeCharacters(question, false)
}
if (isAcceptVariable && variableFullPath === CHAT_HISTORY_VAR_PREFIX) {
variableDict[`{{${variableFullPath}}}`] = handleEscapeCharacters(convertChatHistoryToText(chatHistory), false)
}
// Split by first occurrence of '.' to get just nodeId
const [variableNodeId, _] = variableFullPath.split('.')
const executedNode = reactFlowNodes.find((nd) => nd.id === variableNodeId)
@@ -400,7 +419,12 @@ export const isVectorStoreFaiss = (flowNodeData: INodeData) => {
* @param {string} question
* @returns {INodeData}
*/
export const resolveVariables = (reactFlowNodeData: INodeData, reactFlowNodes: IReactFlowNode[], question: string): INodeData => {
export const resolveVariables = (
reactFlowNodeData: INodeData,
reactFlowNodes: IReactFlowNode[],
question: string,
chatHistory: IMessage[]
): INodeData => {
let flowNodeData = cloneDeep(reactFlowNodeData)
if (reactFlowNodeData.instance && isVectorStoreFaiss(reactFlowNodeData)) {
// omit and merge because cloneDeep of instance gives "Illegal invocation" Exception
@@ -415,13 +439,13 @@ export const resolveVariables = (reactFlowNodeData: INodeData, reactFlowNodes: I
if (Array.isArray(paramValue)) {
const resolvedInstances = []
for (const param of paramValue) {
const resolvedInstance = getVariableValue(param, reactFlowNodes, question)
const resolvedInstance = getVariableValue(param, reactFlowNodes, question, chatHistory)
resolvedInstances.push(resolvedInstance)
}
paramsObj[key] = resolvedInstances
} else {
const isAcceptVariable = reactFlowNodeData.inputParams.find((param) => param.name === key)?.acceptVariable ?? false
const resolvedInstance = getVariableValue(paramValue, reactFlowNodes, question, isAcceptVariable)
const resolvedInstance = getVariableValue(paramValue, reactFlowNodes, question, chatHistory, isAcceptVariable)
paramsObj[key] = resolvedInstance
}
}
@@ -474,13 +498,17 @@ export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig:
* @param {IReactFlowNode[]} startingNodes
* @returns {boolean}
*/
export const isStartNodeDependOnInput = (startingNodes: IReactFlowNode[]): boolean => {
export const isStartNodeDependOnInput = (startingNodes: IReactFlowNode[], nodes: IReactFlowNode[]): boolean => {
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
}
}
const whitelistNodeNames = ['vectorStoreToDocument']
for (const node of nodes) {
if (whitelistNodeNames.includes(node.data.name)) return true
}
return false
}