Feature/Indexing (#1802)

* indexing

* fix for multiple files upsert

* fix default Postgres port

* fix SQLite node description

* add MySQLRecordManager node

* fix MySQL unique index

* add upsert history

* update jsx ui

* lint-fix

* update dialog details

* update llamaindex pinecone

---------

Co-authored-by: chungyau97 <chungyau97@gmail.com>
This commit is contained in:
Henry Heng
2024-04-02 23:47:19 +01:00
committed by GitHub
parent 957694a912
commit e422ce287b
67 changed files with 3006 additions and 246 deletions
+86 -2
View File
@@ -237,6 +237,84 @@ export const getEndingNodes = (nodeDependencies: INodeDependencies, graph: INode
return endingNodeIds
}
/**
* Get file name from base64 string
* @param {string} fileBase64
*/
export const getFileName = (fileBase64: string): string => {
let fileNames = []
if (fileBase64.startsWith('[') && fileBase64.endsWith(']')) {
const files = JSON.parse(fileBase64)
for (const file of files) {
const splitDataURI = file.split(',')
const filename = splitDataURI[splitDataURI.length - 1].split(':')[1]
fileNames.push(filename)
}
return fileNames.join(', ')
} else {
const splitDataURI = fileBase64.split(',')
const filename = splitDataURI[splitDataURI.length - 1].split(':')[1]
return filename
}
}
/**
* Save upsert flowData
* @param {INodeData} nodeData
* @param {Record<string, any>} upsertHistory
*/
export const saveUpsertFlowData = (nodeData: INodeData, upsertHistory: Record<string, any>): ICommonObject[] => {
const existingUpsertFlowData = upsertHistory['flowData'] ?? []
const paramValues: ICommonObject[] = []
for (const input in nodeData.inputs) {
const inputParam = nodeData.inputParams.find((inp) => inp.name === input)
if (!inputParam) continue
let paramValue: ICommonObject = {}
if (!nodeData.inputs[input]) {
continue
}
if (
typeof nodeData.inputs[input] === 'string' &&
nodeData.inputs[input].startsWith('{{') &&
nodeData.inputs[input].endsWith('}}')
) {
continue
}
// Get file name instead of the base64 string
if (nodeData.category === 'Document Loaders' && nodeData.inputParams.find((inp) => inp.name === input)?.type === 'file') {
paramValue = {
label: inputParam?.label,
name: inputParam?.name,
type: inputParam?.type,
value: getFileName(nodeData.inputs[input])
}
paramValues.push(paramValue)
continue
}
paramValue = {
label: inputParam?.label,
name: inputParam?.name,
type: inputParam?.type,
value: nodeData.inputs[input]
}
paramValues.push(paramValue)
}
const newFlowData = {
label: nodeData.label,
name: nodeData.name,
category: nodeData.category,
id: nodeData.id,
paramValues
}
existingUpsertFlowData.push(newFlowData)
return existingUpsertFlowData
}
/**
* Build langchain from start to end
* @param {string[]} startingNodeIds
@@ -272,6 +350,8 @@ export const buildFlow = async (
) => {
const flowNodes = cloneDeep(reactFlowNodes)
let upsertHistory: Record<string, any> = {}
// Create a Queue and add our initial node in it
const nodeQueue = [] as INodeQueue[]
const exploredNode = {} as IExploredNode
@@ -302,12 +382,15 @@ export const buildFlow = async (
let flowNodeData = cloneDeep(reactFlowNode.data)
if (overrideConfig) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig)
if (isUpsert) upsertHistory['flowData'] = saveUpsertFlowData(flowNodeData, upsertHistory)
const reactFlowNodeData: INodeData = resolveVariables(flowNodeData, flowNodes, question, chatHistory)
// TODO: Avoid processing Text Splitter + Doc Loader once Upsert & Load Existing Vector Nodes are deprecated
if (isUpsert && stopNodeId && nodeId === stopNodeId) {
logger.debug(`[server]: Upserting ${reactFlowNode.data.label} (${reactFlowNode.data.id})`)
await newNodeInstance.vectorStoreMethods!['upsert']!.call(newNodeInstance, reactFlowNodeData, {
const indexResult = await newNodeInstance.vectorStoreMethods!['upsert']!.call(newNodeInstance, reactFlowNodeData, {
chatId,
sessionId,
chatflowid,
@@ -319,6 +402,7 @@ export const buildFlow = async (
dynamicVariables,
uploads
})
if (indexResult) upsertHistory['result'] = indexResult
logger.debug(`[server]: Finished upserting ${reactFlowNode.data.label} (${reactFlowNode.data.id})`)
break
} else {
@@ -422,7 +506,7 @@ export const buildFlow = async (
flowNodes.push(flowNodes.splice(index, 1)[0])
}
}
return flowNodes
return isUpsert ? (upsertHistory as any) : flowNodes
}
/**