Merge branch 'main' into FEATURE/Vision

# Conflicts:
#	packages/server/src/index.ts
This commit is contained in:
vinodkiran
2023-12-06 12:33:56 +05:30
42 changed files with 871 additions and 868 deletions
@@ -3,7 +3,7 @@
"nodes": [
{
"width": 300,
"height": 510,
"height": 491,
"id": "openApiChain_1",
"position": {
"x": 1203.1825726424859,
@@ -13,8 +13,8 @@
"data": {
"id": "openApiChain_1",
"label": "OpenAPI Chain",
"name": "openApiChain",
"version": 1,
"name": "openApiChain",
"type": "OpenAPIChain",
"baseClasses": ["OpenAPIChain", "BaseChain"],
"category": "Chains",
@@ -78,7 +78,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_1",
"position": {
"x": 792.3201947594027,
@@ -88,8 +88,8 @@
"data": {
"id": "chatOpenAI_1",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -259,8 +259,8 @@
"data": {
"id": "chainTool_0",
"label": "Chain Tool",
"name": "chainTool",
"version": 1,
"name": "chainTool",
"type": "ChainTool",
"baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool"],
"category": "Tools",
@@ -334,7 +334,7 @@
"id": "openAIFunctionAgent_0",
"label": "OpenAI Function Agent",
"name": "openAIFunctionAgent",
"version": 2,
"version": 3,
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain"],
"category": "Agents",
@@ -367,8 +367,8 @@
{
"label": "OpenAI/Azure Chat Model",
"name": "model",
"type": "ChatOpenAI | AzureChatOpenAI",
"id": "openAIFunctionAgent_0-input-model-ChatOpenAI | AzureChatOpenAI"
"type": "BaseChatModel",
"id": "openAIFunctionAgent_0-input-model-BaseChatModel"
}
],
"inputs": {
@@ -397,7 +397,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_2",
"position": {
"x": 1645.450699499575,
@@ -407,8 +407,8 @@
"data": {
"id": "chatOpenAI_2",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -578,8 +578,8 @@
"data": {
"id": "bufferMemory_0",
"label": "Buffer Memory",
"name": "bufferMemory",
"version": 1,
"name": "bufferMemory",
"type": "BufferMemory",
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
"category": "Memory",
@@ -657,17 +657,6 @@
"label": ""
}
},
{
"source": "chatOpenAI_2",
"sourceHandle": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "openAIFunctionAgent_0",
"targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
},
{
"source": "bufferMemory_0",
"sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
@@ -678,6 +667,17 @@
"data": {
"label": ""
}
},
{
"source": "chatOpenAI_2",
"sourceHandle": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "openAIFunctionAgent_0",
"targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
}
]
}
@@ -13,8 +13,8 @@
"data": {
"id": "getApiChain_0",
"label": "GET API Chain",
"name": "getApiChain",
"version": 1,
"name": "getApiChain",
"type": "GETApiChain",
"baseClasses": ["GETApiChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -102,8 +102,8 @@
"data": {
"id": "chainTool_0",
"label": "Chain Tool",
"name": "chainTool",
"version": 1,
"name": "chainTool",
"type": "ChainTool",
"baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -176,8 +176,8 @@
"data": {
"id": "bufferMemory_0",
"label": "Buffer Memory",
"name": "bufferMemory",
"version": 1,
"name": "bufferMemory",
"type": "BufferMemory",
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
"category": "Memory",
@@ -233,8 +233,8 @@
"data": {
"id": "chainTool_1",
"label": "Chain Tool",
"name": "chainTool",
"version": 1,
"name": "chainTool",
"type": "ChainTool",
"baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -307,8 +307,8 @@
"data": {
"id": "postApiChain_0",
"label": "POST API Chain",
"name": "postApiChain",
"version": 1,
"name": "postApiChain",
"type": "POSTApiChain",
"baseClasses": ["POSTApiChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -386,7 +386,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_2",
"position": {
"x": 572.8941615312035,
@@ -396,8 +396,8 @@
"data": {
"id": "chatOpenAI_2",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -557,7 +557,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_1",
"position": {
"x": 828.7788305309582,
@@ -567,8 +567,8 @@
"data": {
"id": "chatOpenAI_1",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -728,7 +728,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_3",
"position": {
"x": 1148.338912314111,
@@ -738,8 +738,8 @@
"data": {
"id": "chatOpenAI_3",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -869,7 +869,7 @@
}
],
"inputs": {
"modelName": "gpt-3.5-turbo",
"modelName": "gpt-3.5-turbo-16k",
"temperature": 0.9,
"maxTokens": "",
"topP": "",
@@ -902,17 +902,17 @@
"height": 383,
"id": "conversationalAgent_0",
"position": {
"x": 2114.071431691489,
"y": 941.7926368551367
"x": 2090.570467632979,
"y": 969.5131357270544
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"version": 2,
"name": "conversationalAgent",
"version": 1,
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain"],
"baseClasses": ["AgentExecutor", "BaseChain", "Runnable"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
@@ -938,8 +938,8 @@
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
"id": "conversationalAgent_0-input-model-BaseLanguageModel"
"type": "BaseChatModel",
"id": "conversationalAgent_0-input-model-BaseChatModel"
},
{
"label": "Memory",
@@ -956,21 +956,21 @@
},
"outputAnchors": [
{
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain",
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|Runnable",
"name": "conversationalAgent",
"label": "AgentExecutor",
"type": "AgentExecutor | BaseChain"
"type": "AgentExecutor | BaseChain | Runnable"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 2114.071431691489,
"y": 941.7926368551367
}
"x": 2090.570467632979,
"y": 969.5131357270544
},
"dragging": false
}
],
"edges": [
@@ -1044,9 +1044,9 @@
"source": "chatOpenAI_3",
"sourceHandle": "chatOpenAI_3-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
"targetHandle": "conversationalAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_3-chatOpenAI_3-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
"id": "chatOpenAI_3-chatOpenAI_3-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
@@ -13,8 +13,8 @@
"data": {
"id": "calculator_1",
"label": "Calculator",
"name": "calculator",
"version": 1,
"name": "calculator",
"type": "Calculator",
"baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -52,8 +52,8 @@
"data": {
"id": "bufferMemory_1",
"label": "Buffer Memory",
"name": "bufferMemory",
"version": 1,
"name": "bufferMemory",
"type": "BufferMemory",
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
"category": "Memory",
@@ -109,8 +109,8 @@
"data": {
"id": "serpAPI_0",
"label": "Serp API",
"name": "serpAPI",
"version": 1,
"name": "serpAPI",
"type": "SerpAPI",
"baseClasses": ["SerpAPI", "Tool", "StructuredTool"],
"category": "Tools",
@@ -146,7 +146,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_0",
"position": {
"x": 97.01321406237057,
@@ -156,8 +156,8 @@
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -287,7 +287,7 @@
}
],
"inputs": {
"modelName": "gpt-3.5-turbo",
"modelName": "gpt-3.5-turbo-16k",
"temperature": 0.9,
"maxTokens": "",
"topP": "",
@@ -320,17 +320,17 @@
"height": 383,
"id": "conversationalAgent_0",
"position": {
"x": 1164.4550359451973,
"y": 283.40041124403075
"x": 1191.1524476753796,
"y": 324.2479396683294
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"version": 2,
"name": "conversationalAgent",
"version": 1,
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain"],
"baseClasses": ["AgentExecutor", "BaseChain", "Runnable"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
@@ -356,8 +356,8 @@
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
"id": "conversationalAgent_0-input-model-BaseLanguageModel"
"type": "BaseChatModel",
"id": "conversationalAgent_0-input-model-BaseChatModel"
},
{
"label": "Memory",
@@ -374,10 +374,10 @@
},
"outputAnchors": [
{
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain",
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|Runnable",
"name": "conversationalAgent",
"label": "AgentExecutor",
"type": "AgentExecutor | BaseChain"
"type": "AgentExecutor | BaseChain | Runnable"
}
],
"outputs": {},
@@ -385,8 +385,8 @@
},
"selected": false,
"positionAbsolute": {
"x": 1164.4550359451973,
"y": 283.40041124403075
"x": 1191.1524476753796,
"y": 324.2479396683294
},
"dragging": false
}
@@ -418,9 +418,9 @@
"source": "chatOpenAI_0",
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
"targetHandle": "conversationalAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
@@ -98,7 +98,7 @@
"data": {
"id": "conversationalRetrievalAgent_0",
"label": "Conversational Retrieval Agent",
"version": 2,
"version": 3,
"name": "conversationalRetrievalAgent",
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain", "Runnable"],
@@ -132,8 +132,8 @@
{
"label": "OpenAI/Azure Chat Model",
"name": "model",
"type": "ChatOpenAI | AzureChatOpenAI",
"id": "conversationalRetrievalAgent_0-input-model-ChatOpenAI | AzureChatOpenAI"
"type": "BaseChatModel",
"id": "conversationalRetrievalAgent_0-input-model-BaseChatModel"
}
],
"inputs": {
@@ -642,9 +642,9 @@
"source": "chatOpenAI_0",
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable",
"target": "conversationalRetrievalAgent_0",
"targetHandle": "conversationalRetrievalAgent_0-input-model-ChatOpenAI",
"targetHandle": "conversationalRetrievalAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable-conversationalRetrievalAgent_0-conversationalRetrievalAgent_0-input-model-ChatOpenAI",
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable-conversationalRetrievalAgent_0-conversationalRetrievalAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
@@ -205,7 +205,7 @@
"data": {
"id": "ZepMemory_0",
"label": "Zep Memory",
"version": 1,
"version": 2,
"name": "ZepMemory",
"type": "ZepMemory",
"baseClasses": ["ZepMemory", "BaseChatMemory", "BaseMemory"],
@@ -228,13 +228,6 @@
"default": "http://127.0.0.1:8000",
"id": "ZepMemory_0-input-baseURL-string"
},
{
"label": "Auto Summary",
"name": "autoSummary",
"type": "boolean",
"default": true,
"id": "ZepMemory_0-input-autoSummary-boolean"
},
{
"label": "Session Id",
"name": "sessionId",
@@ -251,17 +244,10 @@
"type": "number",
"default": "10",
"step": 1,
"additionalParams": true,
"description": "Window of size k to surface the last k back-and-forths to use as memory.",
"id": "ZepMemory_0-input-k-number"
},
{
"label": "Auto Summary Template",
"name": "autoSummaryTemplate",
"type": "string",
"default": "This is the summary of the following conversation:\n{summary}",
"additionalParams": true,
"id": "ZepMemory_0-input-autoSummaryTemplate-string"
},
{
"label": "AI Prefix",
"name": "aiPrefix",
@@ -306,10 +292,8 @@
"inputAnchors": [],
"inputs": {
"baseURL": "http://127.0.0.1:8000",
"autoSummary": true,
"sessionId": "",
"k": "10",
"autoSummaryTemplate": "This is the summary of the following conversation:\n{summary}",
"aiPrefix": "ai",
"humanPrefix": "human",
"memoryKey": "chat_history",
@@ -1127,81 +1127,6 @@
},
"dragging": false
},
{
"width": 300,
"height": 383,
"id": "conversationalAgent_0",
"position": {
"x": 2506.011817109287,
"y": -241.58006840004734
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"version": 1,
"name": "conversationalAgent",
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain", "Runnable"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
{
"label": "System Message",
"name": "systemMessage",
"type": "string",
"rows": 4,
"default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
"optional": true,
"additionalParams": true,
"id": "conversationalAgent_0-input-systemMessage-string"
}
],
"inputAnchors": [
{
"label": "Allowed Tools",
"name": "tools",
"type": "Tool",
"list": true,
"id": "conversationalAgent_0-input-tools-Tool"
},
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
"id": "conversationalAgent_0-input-model-BaseLanguageModel"
},
{
"label": "Memory",
"name": "memory",
"type": "BaseChatMemory",
"id": "conversationalAgent_0-input-memory-BaseChatMemory"
}
],
"inputs": {
"tools": ["{{chainTool_2.data.instance}}", "{{chainTool_3.data.instance}}"],
"model": "{{chatOpenAI_2.data.instance}}",
"memory": "{{bufferMemory_0.data.instance}}",
"systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
},
"outputAnchors": [
{
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|Runnable",
"name": "conversationalAgent",
"label": "AgentExecutor",
"type": "AgentExecutor | BaseChain | Runnable"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 2506.011817109287,
"y": -241.58006840004734
},
"dragging": false
},
{
"width": 300,
"height": 574,
@@ -1602,6 +1527,81 @@
"y": 75.96855802341503
},
"dragging": false
},
{
"width": 300,
"height": 383,
"id": "conversationalAgent_0",
"position": {
"x": 2432.125364763489,
"y": -105.27942167533908
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"version": 2,
"name": "conversationalAgent",
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain", "Runnable"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
{
"label": "System Message",
"name": "systemMessage",
"type": "string",
"rows": 4,
"default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
"optional": true,
"additionalParams": true,
"id": "conversationalAgent_0-input-systemMessage-string"
}
],
"inputAnchors": [
{
"label": "Allowed Tools",
"name": "tools",
"type": "Tool",
"list": true,
"id": "conversationalAgent_0-input-tools-Tool"
},
{
"label": "Language Model",
"name": "model",
"type": "BaseChatModel",
"id": "conversationalAgent_0-input-model-BaseChatModel"
},
{
"label": "Memory",
"name": "memory",
"type": "BaseChatMemory",
"id": "conversationalAgent_0-input-memory-BaseChatMemory"
}
],
"inputs": {
"tools": ["{{chainTool_2.data.instance}}", "{{chainTool_3.data.instance}}"],
"model": "{{chatOpenAI_2.data.instance}}",
"memory": "{{bufferMemory_0.data.instance}}",
"systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
},
"outputAnchors": [
{
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|Runnable",
"name": "conversationalAgent",
"label": "AgentExecutor",
"type": "AgentExecutor | BaseChain | Runnable"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 2432.125364763489,
"y": -105.27942167533908
},
"dragging": false
}
],
"edges": [
@@ -1704,6 +1704,28 @@
"label": ""
}
},
{
"source": "plainText_1",
"sourceHandle": "plainText_1-output-document-Document",
"target": "faiss_0",
"targetHandle": "faiss_0-input-document-Document",
"type": "buttonedge",
"id": "plainText_1-plainText_1-output-document-Document-faiss_0-faiss_0-input-document-Document",
"data": {
"label": ""
}
},
{
"source": "recursiveCharacterTextSplitter_0",
"sourceHandle": "recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer|Runnable",
"target": "plainText_1",
"targetHandle": "plainText_1-input-textSplitter-TextSplitter",
"type": "buttonedge",
"id": "recursiveCharacterTextSplitter_0-recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer|Runnable-plainText_1-plainText_1-input-textSplitter-TextSplitter",
"data": {
"label": ""
}
},
{
"source": "chainTool_2",
"sourceHandle": "chainTool_2-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
@@ -1730,9 +1752,9 @@
"source": "chatOpenAI_2",
"sourceHandle": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
"targetHandle": "conversationalAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
"id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|Runnable-conversationalAgent_0-conversationalAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
@@ -1747,28 +1769,6 @@
"data": {
"label": ""
}
},
{
"source": "plainText_1",
"sourceHandle": "plainText_1-output-document-Document",
"target": "faiss_0",
"targetHandle": "faiss_0-input-document-Document",
"type": "buttonedge",
"id": "plainText_1-plainText_1-output-document-Document-faiss_0-faiss_0-input-document-Document",
"data": {
"label": ""
}
},
{
"source": "recursiveCharacterTextSplitter_0",
"sourceHandle": "recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer|Runnable",
"target": "plainText_1",
"targetHandle": "plainText_1-input-textSplitter-TextSplitter",
"type": "buttonedge",
"id": "recursiveCharacterTextSplitter_0-recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer|Runnable-plainText_1-plainText_1-input-textSplitter-TextSplitter",
"data": {
"label": ""
}
}
]
}
@@ -13,8 +13,8 @@
"data": {
"id": "calculator_0",
"label": "Calculator",
"name": "calculator",
"version": 1,
"name": "calculator",
"type": "Calculator",
"baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain", "Serializable"],
"category": "Tools",
@@ -52,8 +52,8 @@
"data": {
"id": "bufferMemory_0",
"label": "Buffer Memory",
"name": "bufferMemory",
"version": 1,
"name": "bufferMemory",
"type": "BufferMemory",
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
"category": "Memory",
@@ -109,8 +109,8 @@
"data": {
"id": "customTool_0",
"label": "Custom Tool",
"name": "customTool",
"version": 1,
"name": "customTool",
"type": "CustomTool",
"baseClasses": ["CustomTool", "Tool", "StructuredTool"],
"category": "Tools",
@@ -158,8 +158,8 @@
"data": {
"id": "serper_0",
"label": "Serper",
"name": "serper",
"version": 1,
"name": "serper",
"type": "Serper",
"baseClasses": ["Serper", "Tool", "StructuredTool"],
"category": "Tools",
@@ -206,7 +206,7 @@
"id": "openAIFunctionAgent_0",
"label": "OpenAI Function Agent",
"name": "openAIFunctionAgent",
"version": 2,
"version": 3,
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain"],
"category": "Agents",
@@ -239,8 +239,8 @@
{
"label": "OpenAI/Azure Chat Model",
"name": "model",
"type": "ChatOpenAI | AzureChatOpenAI",
"id": "openAIFunctionAgent_0-input-model-ChatOpenAI | AzureChatOpenAI"
"type": "BaseChatModel",
"id": "openAIFunctionAgent_0-input-model-BaseChatModel"
}
],
"inputs": {
@@ -269,7 +269,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_0",
"position": {
"x": 817.8210275868742,
@@ -279,8 +279,8 @@
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -473,17 +473,6 @@
"label": ""
}
},
{
"source": "chatOpenAI_0",
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "openAIFunctionAgent_0",
"targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
},
{
"source": "bufferMemory_0",
"sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
@@ -494,6 +483,17 @@
"data": {
"label": ""
}
},
{
"source": "chatOpenAI_0",
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "openAIFunctionAgent_0",
"targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
}
]
}
@@ -14,7 +14,7 @@
"data": {
"id": "openAIAssistant_0",
"label": "OpenAI Assistant",
"version": 1,
"version": 2,
"name": "openAIAssistant",
"type": "OpenAIAssistant",
"baseClasses": ["OpenAIAssistant"],
@@ -27,6 +27,15 @@
"type": "asyncOptions",
"loadMethod": "listAssistants",
"id": "openAIAssistant_0-input-selectedAssistant-asyncOptions"
},
{
"label": "Disable File Download",
"name": "disableFileDownload",
"type": "boolean",
"description": "Messages can contain text, images, or files. In some cases, you may want to prevent others from downloading the files. Learn more from OpenAI File Annotation <a target=\"_blank\" href=\"https://platform.openai.com/docs/assistants/how-it-works/managing-threads-and-messages\">docs</a>",
"optional": true,
"additionalParams": true,
"id": "openAIAssistant_0-input-disableFileDownload-boolean"
}
],
"inputAnchors": [
@@ -13,8 +13,8 @@
"data": {
"id": "bufferMemory_0",
"label": "Buffer Memory",
"name": "bufferMemory",
"version": 1,
"name": "bufferMemory",
"type": "BufferMemory",
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
"category": "Memory",
@@ -70,8 +70,8 @@
"data": {
"id": "webBrowser_0",
"label": "Web Browser",
"name": "webBrowser",
"version": 1,
"name": "webBrowser",
"type": "WebBrowser",
"baseClasses": ["WebBrowser", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -115,82 +115,7 @@
},
{
"width": 300,
"height": 383,
"id": "conversationalAgent_0",
"position": {
"x": 1464.513303631911,
"y": 155.73036805253955
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"name": "conversationalAgent",
"version": 1,
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
{
"label": "System Message",
"name": "systemMessage",
"type": "string",
"rows": 4,
"default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
"optional": true,
"additionalParams": true,
"id": "conversationalAgent_0-input-systemMessage-string"
}
],
"inputAnchors": [
{
"label": "Allowed Tools",
"name": "tools",
"type": "Tool",
"list": true,
"id": "conversationalAgent_0-input-tools-Tool"
},
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
"id": "conversationalAgent_0-input-model-BaseLanguageModel"
},
{
"label": "Memory",
"name": "memory",
"type": "BaseChatMemory",
"id": "conversationalAgent_0-input-memory-BaseChatMemory"
}
],
"inputs": {
"tools": ["{{webBrowser_0.data.instance}}"],
"model": "{{chatOpenAI_1.data.instance}}",
"memory": "{{bufferMemory_0.data.instance}}",
"systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
},
"outputAnchors": [
{
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain",
"name": "conversationalAgent",
"label": "AgentExecutor",
"type": "AgentExecutor | BaseChain"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1464.513303631911,
"y": 155.73036805253955
},
"dragging": false
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_0",
"position": {
"x": 734.7477982032904,
@@ -200,8 +125,8 @@
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -371,8 +296,8 @@
"data": {
"id": "openAIEmbeddings_0",
"label": "OpenAI Embeddings",
"name": "openAIEmbeddings",
"version": 1,
"name": "openAIEmbeddings",
"type": "OpenAIEmbeddings",
"baseClasses": ["OpenAIEmbeddings", "Embeddings"],
"category": "Embeddings",
@@ -445,7 +370,7 @@
},
{
"width": 300,
"height": 523,
"height": 574,
"id": "chatOpenAI_1",
"position": {
"x": 68.312124033115,
@@ -455,8 +380,8 @@
"data": {
"id": "chatOpenAI_1",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"version": 2,
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
@@ -586,7 +511,7 @@
}
],
"inputs": {
"modelName": "gpt-3.5-turbo",
"modelName": "gpt-3.5-turbo-16k",
"temperature": 0.9,
"maxTokens": "",
"topP": "",
@@ -613,6 +538,81 @@
"y": -239.65476709991256
},
"dragging": false
},
{
"width": 300,
"height": 383,
"id": "conversationalAgent_0",
"position": {
"x": 1518.944765840293,
"y": 212.2513364217197
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"version": 2,
"name": "conversationalAgent",
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain", "Runnable"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
{
"label": "System Message",
"name": "systemMessage",
"type": "string",
"rows": 4,
"default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
"optional": true,
"additionalParams": true,
"id": "conversationalAgent_0-input-systemMessage-string"
}
],
"inputAnchors": [
{
"label": "Allowed Tools",
"name": "tools",
"type": "Tool",
"list": true,
"id": "conversationalAgent_0-input-tools-Tool"
},
{
"label": "Language Model",
"name": "model",
"type": "BaseChatModel",
"id": "conversationalAgent_0-input-model-BaseChatModel"
},
{
"label": "Memory",
"name": "memory",
"type": "BaseChatMemory",
"id": "conversationalAgent_0-input-memory-BaseChatMemory"
}
],
"inputs": {
"tools": ["{{webBrowser_0.data.instance}}"],
"model": "{{chatOpenAI_1.data.instance}}",
"memory": "{{bufferMemory_0.data.instance}}",
"systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
},
"outputAnchors": [
{
"id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|Runnable",
"name": "conversationalAgent",
"label": "AgentExecutor",
"type": "AgentExecutor | BaseChain | Runnable"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1518.944765840293,
"y": 212.2513364217197
},
"dragging": false
}
],
"edges": [
@@ -638,17 +638,6 @@
"label": ""
}
},
{
"source": "chatOpenAI_1",
"sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
"type": "buttonedge",
"id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
},
{
"source": "webBrowser_0",
"sourceHandle": "webBrowser_0-output-webBrowser-WebBrowser|Tool|StructuredTool|BaseLangChain",
@@ -660,6 +649,17 @@
"label": ""
}
},
{
"source": "chatOpenAI_1",
"sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-model-BaseChatModel",
"type": "buttonedge",
"id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseChatModel",
"data": {
"label": ""
}
},
{
"source": "bufferMemory_0",
"sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
-6
View File
@@ -192,12 +192,6 @@ export interface IOverrideConfig {
type: string
}
export interface IDatabaseExport {
chatmessages: IChatMessage[]
chatflows: IChatFlow[]
apikeys: ICommonObject[]
}
export type ICredentialDataDecrypted = ICommonObject
// Plain credential object sent to server
+30 -68
View File
@@ -17,7 +17,6 @@ import {
IReactFlowNode,
IReactFlowObject,
INodeData,
IDatabaseExport,
ICredentialReturnResponse,
chatType,
IChatMessage,
@@ -31,18 +30,11 @@ import {
constructGraphs,
resolveVariables,
isStartNodeDependOnInput,
getAPIKeys,
addAPIKey,
updateAPIKey,
deleteAPIKey,
compareKeys,
mapMimeTypeToInputField,
findAvailableConfigs,
isSameOverrideConfig,
replaceAllAPIKeys,
isFlowValidForStream,
databaseEntities,
getApiKey,
transformToCredentialEntity,
decryptCredentialData,
clearAllSessionMemory,
@@ -50,7 +42,8 @@ import {
getEncryptionKey,
checkMemorySessionId,
clearSessionMemoryFromViewMessageDialog,
getUserHome
getUserHome,
replaceChatHistory
} from './utils'
import { cloneDeep, omit, uniqWith, isEqual } from 'lodash'
import { getDataSource } from './DataSource'
@@ -62,8 +55,9 @@ import { Tool } from './database/entities/Tool'
import { Assistant } from './database/entities/Assistant'
import { ChatflowPool } from './ChatflowPool'
import { CachePool } from './CachePool'
import { ICommonObject, INodeOptionsValue } from 'flowise-components'
import { ICommonObject, IMessage, INodeOptionsValue } from 'flowise-components'
import { createRateLimiter, getRateLimiter, initializeRateLimiter } from './utils/rateLimit'
import { addAPIKey, compareKeys, deleteAPIKey, getApiKey, getAPIKeys, updateAPIKey } from './utils/apiKey'
export class App {
app: express.Application
@@ -1036,57 +1030,6 @@ export class App {
}
})
// ----------------------------------------
// Export Load Chatflow & ChatMessage & Apikeys
// ----------------------------------------
this.app.get('/api/v1/database/export', async (req: Request, res: Response) => {
const chatmessages = await this.AppDataSource.getRepository(ChatMessage).find()
const chatflows = await this.AppDataSource.getRepository(ChatFlow).find()
const apikeys = await getAPIKeys()
const result: IDatabaseExport = {
chatmessages,
chatflows,
apikeys
}
return res.json(result)
})
this.app.post('/api/v1/database/load', async (req: Request, res: Response) => {
const databaseItems: IDatabaseExport = req.body
await this.AppDataSource.getRepository(ChatFlow).delete({})
await this.AppDataSource.getRepository(ChatMessage).delete({})
let error = ''
// Get a new query runner instance
const queryRunner = this.AppDataSource.createQueryRunner()
// Start a new transaction
await queryRunner.startTransaction()
try {
const chatflows: ChatFlow[] = databaseItems.chatflows
const chatmessages: ChatMessage[] = databaseItems.chatmessages
await queryRunner.manager.insert(ChatFlow, chatflows)
await queryRunner.manager.insert(ChatMessage, chatmessages)
await queryRunner.commitTransaction()
} catch (err: any) {
error = err?.message ?? 'Error loading database'
await queryRunner.rollbackTransaction()
} finally {
await queryRunner.release()
}
await replaceAllAPIKeys(databaseItems.apikeys)
if (error) return res.status(500).send(error)
return res.status(201).send('OK')
})
// ----------------------------------------
// Upsert
// ----------------------------------------
@@ -1363,14 +1306,14 @@ export class App {
* @param {IReactFlowEdge[]} edges
* @returns {string | undefined}
*/
findMemoryLabel(nodes: IReactFlowNode[], edges: IReactFlowEdge[]): string | undefined {
findMemoryLabel(nodes: IReactFlowNode[], edges: IReactFlowEdge[]): IReactFlowNode | undefined {
const memoryNodes = nodes.filter((node) => node.data.category === 'Memory')
const memoryNodeIds = memoryNodes.map((mem) => mem.data.id)
for (const edge of edges) {
if (memoryNodeIds.includes(edge.source)) {
const memoryNode = nodes.find((node) => node.data.id === edge.source)
return memoryNode ? memoryNode.data.label : undefined
return memoryNode
}
}
return undefined
@@ -1508,6 +1451,19 @@ export class App {
isStreamValid = isFlowValidForStream(nodes, endingNodeData)
let chatHistory: IMessage[] | string = incomingInput.history
if (
endingNodeData.inputs?.memory &&
!incomingInput.history &&
(incomingInput.chatId || incomingInput.overrideConfig?.sessionId)
) {
const memoryNodeId = endingNodeData.inputs?.memory.split('.')[0].replace('{{', '')
const memoryNode = nodes.find((node) => node.data.id === memoryNodeId)
if (memoryNode) {
chatHistory = await replaceChatHistory(memoryNode, incomingInput, this.AppDataSource, databaseEntities, logger)
}
}
/*** Get Starting Nodes with Non-Directed Graph ***/
const constructedObj = constructGraphs(nodes, edges, true)
const nonDirectedGraph = constructedObj.graph
@@ -1522,7 +1478,7 @@ export class App {
depthQueue,
this.nodesPool.componentNodes,
incomingInput.question,
incomingInput.history,
chatHistory,
chatId,
chatflowid,
this.AppDataSource,
@@ -1542,7 +1498,7 @@ export class App {
nodeToExecute.data,
reactFlowNodes,
incomingInput.question,
incomingInput.history
chatHistory
)
nodeToExecuteData = reactFlowNodeData
@@ -1559,12 +1515,18 @@ export class App {
let sessionId = undefined
if (nodeToExecuteData.instance) sessionId = checkMemorySessionId(nodeToExecuteData.instance, chatId)
const memoryType = this.findMemoryLabel(nodes, edges)
const memoryNode = this.findMemoryLabel(nodes, edges)
const memoryType = memoryNode?.data.label
let chatHistory: IMessage[] | string = incomingInput.history
if (memoryNode && !incomingInput.history && (incomingInput.chatId || incomingInput.overrideConfig?.sessionId)) {
chatHistory = await replaceChatHistory(memoryNode, incomingInput, this.AppDataSource, databaseEntities, logger)
}
let result = isStreamValid
? await nodeInstance.run(nodeToExecuteData, incomingInput.question, {
uploads: incomingInput.uploads,
chatHistory: incomingInput.history,
chatHistory,
socketIO,
socketIOClientId: incomingInput.socketIOClientId,
logger,
@@ -1575,7 +1537,7 @@ export class App {
})
: await nodeInstance.run(nodeToExecuteData, incomingInput.question, {
uploads: incomingInput.uploads,
chatHistory: incomingInput.history,
chatHistory,
logger,
appDataSource: this.AppDataSource,
databaseEntities,
+147
View File
@@ -0,0 +1,147 @@
import { randomBytes, scryptSync, timingSafeEqual } from 'crypto'
import { ICommonObject } from 'flowise-components'
import moment from 'moment'
import fs from 'fs'
import path from 'path'
import logger from './logger'
/**
* Returns the api key path
* @returns {string}
*/
export const getAPIKeyPath = (): string => {
return process.env.APIKEY_PATH ? path.join(process.env.APIKEY_PATH, 'api.json') : path.join(__dirname, '..', '..', 'api.json')
}
/**
* Generate the api key
* @returns {string}
*/
export const generateAPIKey = (): string => {
const buffer = randomBytes(32)
return buffer.toString('base64')
}
/**
* Generate the secret key
* @param {string} apiKey
* @returns {string}
*/
export const generateSecretHash = (apiKey: string): string => {
const salt = randomBytes(8).toString('hex')
const buffer = scryptSync(apiKey, salt, 64) as Buffer
return `${buffer.toString('hex')}.${salt}`
}
/**
* Verify valid keys
* @param {string} storedKey
* @param {string} suppliedKey
* @returns {boolean}
*/
export const compareKeys = (storedKey: string, suppliedKey: string): boolean => {
const [hashedPassword, salt] = storedKey.split('.')
const buffer = scryptSync(suppliedKey, salt, 64) as Buffer
return timingSafeEqual(Buffer.from(hashedPassword, 'hex'), buffer)
}
/**
* Get API keys
* @returns {Promise<ICommonObject[]>}
*/
export const getAPIKeys = async (): Promise<ICommonObject[]> => {
try {
const content = await fs.promises.readFile(getAPIKeyPath(), 'utf8')
return JSON.parse(content)
} catch (error) {
const keyName = 'DefaultKey'
const apiKey = generateAPIKey()
const apiSecret = generateSecretHash(apiKey)
const content = [
{
keyName,
apiKey,
apiSecret,
createdAt: moment().format('DD-MMM-YY'),
id: randomBytes(16).toString('hex')
}
]
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
return content
}
}
/**
* Add new API key
* @param {string} keyName
* @returns {Promise<ICommonObject[]>}
*/
export const addAPIKey = async (keyName: string): Promise<ICommonObject[]> => {
const existingAPIKeys = await getAPIKeys()
const apiKey = generateAPIKey()
const apiSecret = generateSecretHash(apiKey)
const content = [
...existingAPIKeys,
{
keyName,
apiKey,
apiSecret,
createdAt: moment().format('DD-MMM-YY'),
id: randomBytes(16).toString('hex')
}
]
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
return content
}
/**
* Get API Key details
* @param {string} apiKey
* @returns {Promise<ICommonObject[]>}
*/
export const getApiKey = async (apiKey: string) => {
const existingAPIKeys = await getAPIKeys()
const keyIndex = existingAPIKeys.findIndex((key) => key.apiKey === apiKey)
if (keyIndex < 0) return undefined
return existingAPIKeys[keyIndex]
}
/**
* Update existing API key
* @param {string} keyIdToUpdate
* @param {string} newKeyName
* @returns {Promise<ICommonObject[]>}
*/
export const updateAPIKey = async (keyIdToUpdate: string, newKeyName: string): Promise<ICommonObject[]> => {
const existingAPIKeys = await getAPIKeys()
const keyIndex = existingAPIKeys.findIndex((key) => key.id === keyIdToUpdate)
if (keyIndex < 0) return []
existingAPIKeys[keyIndex].keyName = newKeyName
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(existingAPIKeys), 'utf8')
return existingAPIKeys
}
/**
* Delete API key
* @param {string} keyIdToDelete
* @returns {Promise<ICommonObject[]>}
*/
export const deleteAPIKey = async (keyIdToDelete: string): Promise<ICommonObject[]> => {
const existingAPIKeys = await getAPIKeys()
const result = existingAPIKeys.filter((key) => key.id !== keyIdToDelete)
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(result), 'utf8')
return result
}
/**
* Replace all api keys
* @param {ICommonObject[]} content
* @returns {Promise<void>}
*/
export const replaceAllAPIKeys = async (content: ICommonObject[]): Promise<void> => {
try {
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
} catch (error) {
logger.error(error)
}
}
+99 -162
View File
@@ -1,33 +1,33 @@
import path from 'path'
import fs from 'fs'
import moment from 'moment'
import logger from './logger'
import {
IComponentCredentials,
IComponentNodes,
ICredentialDataDecrypted,
ICredentialReqBody,
IDepthQueue,
IExploredNode,
INodeData,
INodeDependencies,
INodeDirectedGraph,
INodeQueue,
IOverrideConfig,
IReactFlowEdge,
IReactFlowNode,
IVariableDict,
INodeData,
IOverrideConfig,
ICredentialDataDecrypted,
IComponentCredentials,
ICredentialReqBody
IncomingInput
} from '../Interface'
import { cloneDeep, get, isEqual } from 'lodash'
import {
ICommonObject,
convertChatHistoryToText,
getInputVariables,
IDatabaseEntity,
handleEscapeCharacters,
IMessage,
convertChatHistoryToText
ICommonObject,
IDatabaseEntity,
IMessage
} from 'flowise-components'
import { scryptSync, randomBytes, timingSafeEqual } from 'crypto'
import { randomBytes } from 'crypto'
import { AES, enc } from 'crypto-js'
import { ChatFlow } from '../database/entities/ChatFlow'
@@ -217,7 +217,7 @@ export const buildLangchain = async (
depthQueue: IDepthQueue,
componentNodes: IComponentNodes,
question: string,
chatHistory: IMessage[],
chatHistory: IMessage[] | string,
chatId: string,
chatflowid: string,
appDataSource: DataSource,
@@ -348,8 +348,8 @@ export const clearAllSessionMemory = async (
node.data.inputs.sessionId = sessionId
}
if (newNodeInstance.clearSessionMemory) {
await newNodeInstance?.clearSessionMemory(node.data, { chatId, appDataSource, databaseEntities, logger })
if (newNodeInstance.memoryMethods && newNodeInstance.memoryMethods.clearSessionMemory) {
await newNodeInstance.memoryMethods.clearSessionMemory(node.data, { chatId, appDataSource, databaseEntities, logger })
}
}
}
@@ -381,8 +381,8 @@ export const clearSessionMemoryFromViewMessageDialog = async (
if (sessionId && node.data.inputs) node.data.inputs.sessionId = sessionId
if (newNodeInstance.clearSessionMemory) {
await newNodeInstance?.clearSessionMemory(node.data, { chatId, appDataSource, databaseEntities, logger })
if (newNodeInstance.memoryMethods && newNodeInstance.memoryMethods.clearSessionMemory) {
await newNodeInstance.memoryMethods.clearSessionMemory(node.data, { chatId, appDataSource, databaseEntities, logger })
return
}
}
@@ -400,7 +400,7 @@ export const getVariableValue = (
paramValue: string,
reactFlowNodes: IReactFlowNode[],
question: string,
chatHistory: IMessage[],
chatHistory: IMessage[] | string,
isAcceptVariable = false
) => {
let returnVal = paramValue
@@ -433,7 +433,10 @@ export const getVariableValue = (
}
if (isAcceptVariable && variableFullPath === CHAT_HISTORY_VAR_PREFIX) {
variableDict[`{{${variableFullPath}}}`] = handleEscapeCharacters(convertChatHistoryToText(chatHistory), false)
variableDict[`{{${variableFullPath}}}`] = handleEscapeCharacters(
typeof chatHistory === 'string' ? chatHistory : convertChatHistoryToText(chatHistory),
false
)
}
// Split by first occurrence of '.' to get just nodeId
@@ -476,7 +479,7 @@ export const resolveVariables = (
reactFlowNodeData: INodeData,
reactFlowNodes: IReactFlowNode[],
question: string,
chatHistory: IMessage[]
chatHistory: IMessage[] | string
): INodeData => {
let flowNodeData = cloneDeep(reactFlowNodeData)
const types = 'inputs'
@@ -555,9 +558,20 @@ export const isStartNodeDependOnInput = (startingNodes: IReactFlowNode[], nodes:
if (inputVariables.length > 0) return true
}
}
const whitelistNodeNames = ['vectorStoreToDocument', 'autoGPT']
const whitelistNodeNames = ['vectorStoreToDocument', 'autoGPT', 'chatPromptTemplate', 'promptTemplate'] //If these nodes are found, chatflow cannot be reused
for (const node of nodes) {
if (whitelistNodeNames.includes(node.data.name)) return true
if (node.data.name === 'chatPromptTemplate' || node.data.name === 'promptTemplate') {
let promptValues: ICommonObject = {}
const promptValuesRaw = node.data.inputs?.promptValues
if (promptValuesRaw) {
try {
promptValues = typeof promptValuesRaw === 'object' ? promptValuesRaw : JSON.parse(promptValuesRaw)
} catch (exception) {
console.error(exception)
}
}
if (getAllValuesFromJson(promptValues).includes(`{{${QUESTION_VAR_PREFIX}}}`)) return true
} else if (whitelistNodeNames.includes(node.data.name)) return true
}
return false
}
@@ -593,147 +607,6 @@ export const isSameOverrideConfig = (
return false
}
/**
* Returns the api key path
* @returns {string}
*/
export const getAPIKeyPath = (): string => {
return process.env.APIKEY_PATH ? path.join(process.env.APIKEY_PATH, 'api.json') : path.join(__dirname, '..', '..', 'api.json')
}
/**
* Generate the api key
* @returns {string}
*/
export const generateAPIKey = (): string => {
const buffer = randomBytes(32)
return buffer.toString('base64')
}
/**
* Generate the secret key
* @param {string} apiKey
* @returns {string}
*/
export const generateSecretHash = (apiKey: string): string => {
const salt = randomBytes(8).toString('hex')
const buffer = scryptSync(apiKey, salt, 64) as Buffer
return `${buffer.toString('hex')}.${salt}`
}
/**
* Verify valid keys
* @param {string} storedKey
* @param {string} suppliedKey
* @returns {boolean}
*/
export const compareKeys = (storedKey: string, suppliedKey: string): boolean => {
const [hashedPassword, salt] = storedKey.split('.')
const buffer = scryptSync(suppliedKey, salt, 64) as Buffer
return timingSafeEqual(Buffer.from(hashedPassword, 'hex'), buffer)
}
/**
* Get API keys
* @returns {Promise<ICommonObject[]>}
*/
export const getAPIKeys = async (): Promise<ICommonObject[]> => {
try {
const content = await fs.promises.readFile(getAPIKeyPath(), 'utf8')
return JSON.parse(content)
} catch (error) {
const keyName = 'DefaultKey'
const apiKey = generateAPIKey()
const apiSecret = generateSecretHash(apiKey)
const content = [
{
keyName,
apiKey,
apiSecret,
createdAt: moment().format('DD-MMM-YY'),
id: randomBytes(16).toString('hex')
}
]
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
return content
}
}
/**
* Add new API key
* @param {string} keyName
* @returns {Promise<ICommonObject[]>}
*/
export const addAPIKey = async (keyName: string): Promise<ICommonObject[]> => {
const existingAPIKeys = await getAPIKeys()
const apiKey = generateAPIKey()
const apiSecret = generateSecretHash(apiKey)
const content = [
...existingAPIKeys,
{
keyName,
apiKey,
apiSecret,
createdAt: moment().format('DD-MMM-YY'),
id: randomBytes(16).toString('hex')
}
]
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
return content
}
/**
* Get API Key details
* @param {string} apiKey
* @returns {Promise<ICommonObject[]>}
*/
export const getApiKey = async (apiKey: string) => {
const existingAPIKeys = await getAPIKeys()
const keyIndex = existingAPIKeys.findIndex((key) => key.apiKey === apiKey)
if (keyIndex < 0) return undefined
return existingAPIKeys[keyIndex]
}
/**
* Update existing API key
* @param {string} keyIdToUpdate
* @param {string} newKeyName
* @returns {Promise<ICommonObject[]>}
*/
export const updateAPIKey = async (keyIdToUpdate: string, newKeyName: string): Promise<ICommonObject[]> => {
const existingAPIKeys = await getAPIKeys()
const keyIndex = existingAPIKeys.findIndex((key) => key.id === keyIdToUpdate)
if (keyIndex < 0) return []
existingAPIKeys[keyIndex].keyName = newKeyName
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(existingAPIKeys), 'utf8')
return existingAPIKeys
}
/**
* Delete API key
* @param {string} keyIdToDelete
* @returns {Promise<ICommonObject[]>}
*/
export const deleteAPIKey = async (keyIdToDelete: string): Promise<ICommonObject[]> => {
const existingAPIKeys = await getAPIKeys()
const result = existingAPIKeys.filter((key) => key.id !== keyIdToDelete)
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(result), 'utf8')
return result
}
/**
* Replace all api keys
* @param {ICommonObject[]} content
* @returns {Promise<void>}
*/
export const replaceAllAPIKeys = async (content: ICommonObject[]): Promise<void> => {
try {
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
} catch (error) {
logger.error(error)
}
}
/**
* Map MimeType to InputField
* @param {string} mimeType
@@ -1015,3 +888,67 @@ export const checkMemorySessionId = (instance: any, chatId: string): string | un
return instance.memory.chatHistory.sessionId
return undefined
}
/**
* Replace chatHistory if incomingInput.history is empty and sessionId/chatId is provided
* @param {IReactFlowNode} memoryNode
* @param {IncomingInput} incomingInput
* @param {DataSource} appDataSource
* @param {IDatabaseEntity} databaseEntities
* @param {any} logger
* @returns {string}
*/
export const replaceChatHistory = async (
memoryNode: IReactFlowNode,
incomingInput: IncomingInput,
appDataSource: DataSource,
databaseEntities: IDatabaseEntity,
logger: any
): Promise<string> => {
const nodeInstanceFilePath = memoryNode.data.filePath as string
const nodeModule = await import(nodeInstanceFilePath)
const newNodeInstance = new nodeModule.nodeClass()
if (incomingInput.overrideConfig?.sessionId && memoryNode.data.inputs) {
memoryNode.data.inputs.sessionId = incomingInput.overrideConfig.sessionId
}
if (newNodeInstance.memoryMethods && newNodeInstance.memoryMethods.getChatMessages) {
return await newNodeInstance.memoryMethods.getChatMessages(memoryNode.data, {
chatId: incomingInput.chatId,
appDataSource,
databaseEntities,
logger
})
}
return ''
}
/**
* Get all values from a JSON object
* @param {any} obj
* @returns {any[]}
*/
export const getAllValuesFromJson = (obj: any): any[] => {
const values: any[] = []
function extractValues(data: any) {
if (typeof data === 'object' && data !== null) {
if (Array.isArray(data)) {
for (const item of data) {
extractValues(item)
}
} else {
for (const key in data) {
extractValues(data[key])
}
}
} else {
values.push(data)
}
}
extractValues(obj)
return values
}