mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 21:00:58 +03:00
- add refine chain type custom system message
- allow all memory type to conver_re_qa_chain - fix startsWith undefined where override config file is not passed - ability to generate new session id when sharing chatbot
This commit is contained in:
+45
-13
@@ -1,9 +1,9 @@
|
|||||||
import { BaseLanguageModel } from 'langchain/base_language'
|
import { BaseLanguageModel } from 'langchain/base_language'
|
||||||
import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
|
import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
|
||||||
import { getBaseClasses } from '../../../src/utils'
|
import { getBaseClasses } from '../../../src/utils'
|
||||||
import { ConversationalRetrievalQAChain } from 'langchain/chains'
|
import { ConversationalRetrievalQAChain, QAChainParams } from 'langchain/chains'
|
||||||
import { AIMessage, BaseRetriever, HumanMessage } from 'langchain/schema'
|
import { AIMessage, BaseRetriever, HumanMessage } from 'langchain/schema'
|
||||||
import { BaseChatMemory, BufferMemory, ChatMessageHistory } from 'langchain/memory'
|
import { BaseChatMemory, BufferMemory, ChatMessageHistory, BufferMemoryInput } from 'langchain/memory'
|
||||||
import { PromptTemplate } from 'langchain/prompts'
|
import { PromptTemplate } from 'langchain/prompts'
|
||||||
import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
|
import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
|
||||||
import {
|
import {
|
||||||
@@ -11,7 +11,9 @@ import {
|
|||||||
default_qa_template,
|
default_qa_template,
|
||||||
qa_template,
|
qa_template,
|
||||||
map_reduce_template,
|
map_reduce_template,
|
||||||
CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT
|
CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT,
|
||||||
|
refine_question_template,
|
||||||
|
refine_template
|
||||||
} from './prompts'
|
} from './prompts'
|
||||||
|
|
||||||
class ConversationalRetrievalQAChain_Chains implements INode {
|
class ConversationalRetrievalQAChain_Chains implements INode {
|
||||||
@@ -46,9 +48,9 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
|||||||
{
|
{
|
||||||
label: 'Memory',
|
label: 'Memory',
|
||||||
name: 'memory',
|
name: 'memory',
|
||||||
type: 'DynamoDBChatMemory | RedisBackedChatMemory | ZepMemory',
|
type: 'BaseMemory',
|
||||||
optional: true,
|
optional: true,
|
||||||
description: 'If no memory connected, default BufferMemory will be used'
|
description: 'If left empty, a default BufferMemory will be used'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Return Source Documents',
|
label: 'Return Source Documents',
|
||||||
@@ -115,28 +117,43 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
|||||||
combinePrompt: PromptTemplate.fromTemplate(
|
combinePrompt: PromptTemplate.fromTemplate(
|
||||||
systemMessagePrompt ? `${systemMessagePrompt}\n${map_reduce_template}` : default_map_reduce_template
|
systemMessagePrompt ? `${systemMessagePrompt}\n${map_reduce_template}` : default_map_reduce_template
|
||||||
)
|
)
|
||||||
}
|
} as QAChainParams
|
||||||
} else if (chainOption === 'refine') {
|
} else if (chainOption === 'refine') {
|
||||||
// TODO: Add custom system message
|
const qprompt = new PromptTemplate({
|
||||||
|
inputVariables: ['context', 'question'],
|
||||||
|
template: refine_question_template(systemMessagePrompt)
|
||||||
|
})
|
||||||
|
const rprompt = new PromptTemplate({
|
||||||
|
inputVariables: ['context', 'question', 'existing_answer'],
|
||||||
|
template: refine_template
|
||||||
|
})
|
||||||
|
obj.qaChainOptions = {
|
||||||
|
type: 'refine',
|
||||||
|
questionPrompt: qprompt,
|
||||||
|
refinePrompt: rprompt
|
||||||
|
} as QAChainParams
|
||||||
} else {
|
} else {
|
||||||
obj.qaChainOptions = {
|
obj.qaChainOptions = {
|
||||||
type: 'stuff',
|
type: 'stuff',
|
||||||
prompt: PromptTemplate.fromTemplate(systemMessagePrompt ? `${systemMessagePrompt}\n${qa_template}` : default_qa_template)
|
prompt: PromptTemplate.fromTemplate(systemMessagePrompt ? `${systemMessagePrompt}\n${qa_template}` : default_qa_template)
|
||||||
}
|
} as QAChainParams
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memory) {
|
if (memory) {
|
||||||
memory.inputKey = 'question'
|
memory.inputKey = 'question'
|
||||||
memory.outputKey = 'text'
|
|
||||||
memory.memoryKey = 'chat_history'
|
memory.memoryKey = 'chat_history'
|
||||||
|
if (chainOption === 'refine') memory.outputKey = 'output_text'
|
||||||
|
else memory.outputKey = 'text'
|
||||||
obj.memory = memory
|
obj.memory = memory
|
||||||
} else {
|
} else {
|
||||||
obj.memory = new BufferMemory({
|
const fields: BufferMemoryInput = {
|
||||||
memoryKey: 'chat_history',
|
memoryKey: 'chat_history',
|
||||||
inputKey: 'question',
|
inputKey: 'question',
|
||||||
outputKey: 'text',
|
|
||||||
returnMessages: true
|
returnMessages: true
|
||||||
})
|
}
|
||||||
|
if (chainOption === 'refine') fields.outputKey = 'output_text'
|
||||||
|
else fields.outputKey = 'text'
|
||||||
|
obj.memory = new BufferMemory(fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
const chain = ConversationalRetrievalQAChain.fromLLM(model, vectorStoreRetriever, obj)
|
const chain = ConversationalRetrievalQAChain.fromLLM(model, vectorStoreRetriever, obj)
|
||||||
@@ -147,6 +164,7 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
|||||||
const chain = nodeData.instance as ConversationalRetrievalQAChain
|
const chain = nodeData.instance as ConversationalRetrievalQAChain
|
||||||
const returnSourceDocuments = nodeData.inputs?.returnSourceDocuments as boolean
|
const returnSourceDocuments = nodeData.inputs?.returnSourceDocuments as boolean
|
||||||
const memory = nodeData.inputs?.memory
|
const memory = nodeData.inputs?.memory
|
||||||
|
const chainOption = nodeData.inputs?.chainOption as string
|
||||||
|
|
||||||
let model = nodeData.inputs?.model
|
let model = nodeData.inputs?.model
|
||||||
|
|
||||||
@@ -176,8 +194,22 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
|||||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||||
|
|
||||||
if (options.socketIO && options.socketIOClientId) {
|
if (options.socketIO && options.socketIOClientId) {
|
||||||
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, undefined, returnSourceDocuments)
|
const handler = new CustomChainHandler(
|
||||||
|
options.socketIO,
|
||||||
|
options.socketIOClientId,
|
||||||
|
chainOption === 'refine' ? 4 : undefined,
|
||||||
|
returnSourceDocuments
|
||||||
|
)
|
||||||
const res = await chain.call(obj, [loggerHandler, handler])
|
const res = await chain.call(obj, [loggerHandler, handler])
|
||||||
|
if (chainOption === 'refine') {
|
||||||
|
if (res.output_text && res.sourceDocuments) {
|
||||||
|
return {
|
||||||
|
text: res.output_text,
|
||||||
|
sourceDocuments: res.sourceDocuments
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res?.output_text
|
||||||
|
}
|
||||||
if (res.text && res.sourceDocuments) return res
|
if (res.text && res.sourceDocuments) return res
|
||||||
return res?.text
|
return res?.text
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -27,7 +27,36 @@ export const map_reduce_template = `Given the following extracted parts of a lon
|
|||||||
Question: {question}
|
Question: {question}
|
||||||
Helpful Answer:`
|
Helpful Answer:`
|
||||||
|
|
||||||
export const CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language. include it in the standalone question.
|
export const refine_question_template = (sysPrompt?: string) => {
|
||||||
|
let returnPrompt = ''
|
||||||
|
if (sysPrompt)
|
||||||
|
returnPrompt = `Context information is below.
|
||||||
|
---------------------
|
||||||
|
{context}
|
||||||
|
---------------------
|
||||||
|
Given the context information and not prior knowledge, ${sysPrompt}
|
||||||
|
Answer the question: {question}.
|
||||||
|
Answer:`
|
||||||
|
if (!sysPrompt)
|
||||||
|
returnPrompt = `Context information is below.
|
||||||
|
---------------------
|
||||||
|
{context}
|
||||||
|
---------------------
|
||||||
|
Given the context information and not prior knowledge, answer the question: {question}.
|
||||||
|
Answer:`
|
||||||
|
return returnPrompt
|
||||||
|
}
|
||||||
|
|
||||||
|
export const refine_template = `The original question is as follows: {question}
|
||||||
|
We have provided an existing answer: {existing_answer}
|
||||||
|
We have the opportunity to refine the existing answer (only if needed) with some more context below.
|
||||||
|
------------
|
||||||
|
{context}
|
||||||
|
------------
|
||||||
|
Given the new context, refine the original answer to better answer the question.
|
||||||
|
If you can't find answer from the context, return the original answer.`
|
||||||
|
|
||||||
|
export const CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, answer in the same language as the follow up question. include it in the standalone question.
|
||||||
|
|
||||||
Chat History:
|
Chat History:
|
||||||
{chat_history}
|
{chat_history}
|
||||||
|
|||||||
@@ -58,70 +58,6 @@
|
|||||||
},
|
},
|
||||||
"dragging": false
|
"dragging": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"width": 300,
|
|
||||||
"height": 392,
|
|
||||||
"id": "textFile_1",
|
|
||||||
"position": {
|
|
||||||
"x": 810.6456923854021,
|
|
||||||
"y": 61.45989039390216
|
|
||||||
},
|
|
||||||
"type": "customNode",
|
|
||||||
"data": {
|
|
||||||
"id": "textFile_1",
|
|
||||||
"label": "Text File",
|
|
||||||
"name": "textFile",
|
|
||||||
"type": "Document",
|
|
||||||
"baseClasses": ["Document"],
|
|
||||||
"category": "Document Loaders",
|
|
||||||
"description": "Load data from text files",
|
|
||||||
"inputParams": [
|
|
||||||
{
|
|
||||||
"label": "Txt File",
|
|
||||||
"name": "txtFile",
|
|
||||||
"type": "file",
|
|
||||||
"fileType": ".txt",
|
|
||||||
"id": "textFile_1-input-txtFile-file"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Metadata",
|
|
||||||
"name": "metadata",
|
|
||||||
"type": "json",
|
|
||||||
"optional": true,
|
|
||||||
"additionalParams": true,
|
|
||||||
"id": "textFile_1-input-metadata-json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputAnchors": [
|
|
||||||
{
|
|
||||||
"label": "Text Splitter",
|
|
||||||
"name": "textSplitter",
|
|
||||||
"type": "TextSplitter",
|
|
||||||
"optional": true,
|
|
||||||
"id": "textFile_1-input-textSplitter-TextSplitter"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputs": {
|
|
||||||
"textSplitter": "{{recursiveCharacterTextSplitter_1.data.instance}}"
|
|
||||||
},
|
|
||||||
"outputAnchors": [
|
|
||||||
{
|
|
||||||
"id": "textFile_1-output-textFile-Document",
|
|
||||||
"name": "textFile",
|
|
||||||
"label": "Document",
|
|
||||||
"type": "Document"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outputs": {},
|
|
||||||
"selected": false
|
|
||||||
},
|
|
||||||
"selected": false,
|
|
||||||
"positionAbsolute": {
|
|
||||||
"x": 810.6456923854021,
|
|
||||||
"y": 61.45989039390216
|
|
||||||
},
|
|
||||||
"dragging": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"width": 300,
|
"width": 300,
|
||||||
"height": 330,
|
"height": 330,
|
||||||
@@ -203,118 +139,6 @@
|
|||||||
},
|
},
|
||||||
"dragging": false
|
"dragging": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"width": 300,
|
|
||||||
"height": 702,
|
|
||||||
"id": "pineconeUpsert_1",
|
|
||||||
"position": {
|
|
||||||
"x": 1201.3427203075867,
|
|
||||||
"y": 545.1800202023215
|
|
||||||
},
|
|
||||||
"type": "customNode",
|
|
||||||
"data": {
|
|
||||||
"id": "pineconeUpsert_1",
|
|
||||||
"label": "Pinecone Upsert Document",
|
|
||||||
"name": "pineconeUpsert",
|
|
||||||
"type": "Pinecone",
|
|
||||||
"baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
|
|
||||||
"category": "Vector Stores",
|
|
||||||
"description": "Upsert documents to Pinecone",
|
|
||||||
"inputParams": [
|
|
||||||
{
|
|
||||||
"label": "Pinecone Api Key",
|
|
||||||
"name": "pineconeApiKey",
|
|
||||||
"type": "password",
|
|
||||||
"id": "pineconeUpsert_1-input-pineconeApiKey-password"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Pinecone Environment",
|
|
||||||
"name": "pineconeEnv",
|
|
||||||
"type": "string",
|
|
||||||
"id": "pineconeUpsert_1-input-pineconeEnv-string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Pinecone Index",
|
|
||||||
"name": "pineconeIndex",
|
|
||||||
"type": "string",
|
|
||||||
"id": "pineconeUpsert_1-input-pineconeIndex-string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Pinecone Namespace",
|
|
||||||
"name": "pineconeNamespace",
|
|
||||||
"type": "string",
|
|
||||||
"placeholder": "my-first-namespace",
|
|
||||||
"optional": true,
|
|
||||||
"additionalParams": true,
|
|
||||||
"id": "pineconeUpsert_1-input-pineconeNamespace-string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Top K",
|
|
||||||
"name": "topK",
|
|
||||||
"description": "Number of top results to fetch. Default to 4",
|
|
||||||
"placeholder": "4",
|
|
||||||
"type": "number",
|
|
||||||
"additionalParams": true,
|
|
||||||
"optional": true,
|
|
||||||
"id": "pineconeUpsert_1-input-topK-number"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputAnchors": [
|
|
||||||
{
|
|
||||||
"label": "Document",
|
|
||||||
"name": "document",
|
|
||||||
"type": "Document",
|
|
||||||
"list": true,
|
|
||||||
"id": "pineconeUpsert_1-input-document-Document"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Embeddings",
|
|
||||||
"name": "embeddings",
|
|
||||||
"type": "Embeddings",
|
|
||||||
"id": "pineconeUpsert_1-input-embeddings-Embeddings"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputs": {
|
|
||||||
"document": ["{{textFile_1.data.instance}}"],
|
|
||||||
"embeddings": "{{openAIEmbeddings_1.data.instance}}",
|
|
||||||
"pineconeEnv": "us-west4-gcp",
|
|
||||||
"pineconeIndex": "myindex",
|
|
||||||
"pineconeNamespace": "mynamespace"
|
|
||||||
},
|
|
||||||
"outputAnchors": [
|
|
||||||
{
|
|
||||||
"name": "output",
|
|
||||||
"label": "Output",
|
|
||||||
"type": "options",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"id": "pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
|
|
||||||
"name": "retriever",
|
|
||||||
"label": "Pinecone Retriever",
|
|
||||||
"type": "Pinecone | VectorStoreRetriever | BaseRetriever"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "pineconeUpsert_1-output-vectorStore-Pinecone|VectorStore",
|
|
||||||
"name": "vectorStore",
|
|
||||||
"label": "Pinecone Vector Store",
|
|
||||||
"type": "Pinecone | VectorStore"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default": "retriever"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outputs": {
|
|
||||||
"output": "retriever"
|
|
||||||
},
|
|
||||||
"selected": false
|
|
||||||
},
|
|
||||||
"selected": false,
|
|
||||||
"dragging": false,
|
|
||||||
"positionAbsolute": {
|
|
||||||
"x": 1201.3427203075867,
|
|
||||||
"y": 545.1800202023215
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"width": 300,
|
"width": 300,
|
||||||
"height": 524,
|
"height": 524,
|
||||||
@@ -468,7 +292,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"width": 300,
|
"width": 300,
|
||||||
"height": 280,
|
"height": 480,
|
||||||
"id": "conversationalRetrievalQAChain_0",
|
"id": "conversationalRetrievalQAChain_0",
|
||||||
"position": {
|
"position": {
|
||||||
"x": 1627.1855024401737,
|
"x": 1627.1855024401737,
|
||||||
@@ -551,7 +375,7 @@
|
|||||||
],
|
],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"model": "{{chatOpenAI_0.data.instance}}",
|
"model": "{{chatOpenAI_0.data.instance}}",
|
||||||
"vectorStoreRetriever": "{{pineconeUpsert_1.data.instance}}"
|
"vectorStoreRetriever": "{{pineconeUpsert_0.data.instance}}"
|
||||||
},
|
},
|
||||||
"outputAnchors": [
|
"outputAnchors": [
|
||||||
{
|
{
|
||||||
@@ -570,42 +394,186 @@
|
|||||||
"y": 394.42287890442145
|
"y": 394.42287890442145
|
||||||
},
|
},
|
||||||
"dragging": false
|
"dragging": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 300,
|
||||||
|
"height": 411,
|
||||||
|
"id": "textFile_0",
|
||||||
|
"position": {
|
||||||
|
"x": 806.1207502345,
|
||||||
|
"y": 98.75458062792087
|
||||||
|
},
|
||||||
|
"type": "customNode",
|
||||||
|
"data": {
|
||||||
|
"id": "textFile_0",
|
||||||
|
"label": "Text File",
|
||||||
|
"name": "textFile",
|
||||||
|
"type": "Document",
|
||||||
|
"baseClasses": ["Document"],
|
||||||
|
"category": "Document Loaders",
|
||||||
|
"description": "Load data from text files",
|
||||||
|
"inputParams": [
|
||||||
|
{
|
||||||
|
"label": "Txt File",
|
||||||
|
"name": "txtFile",
|
||||||
|
"type": "file",
|
||||||
|
"fileType": ".txt",
|
||||||
|
"id": "textFile_0-input-txtFile-file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Metadata",
|
||||||
|
"name": "metadata",
|
||||||
|
"type": "json",
|
||||||
|
"optional": true,
|
||||||
|
"additionalParams": true,
|
||||||
|
"id": "textFile_0-input-metadata-json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputAnchors": [
|
||||||
|
{
|
||||||
|
"label": "Text Splitter",
|
||||||
|
"name": "textSplitter",
|
||||||
|
"type": "TextSplitter",
|
||||||
|
"optional": true,
|
||||||
|
"id": "textFile_0-input-textSplitter-TextSplitter"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": {
|
||||||
|
"textSplitter": "{{recursiveCharacterTextSplitter_1.data.instance}}",
|
||||||
|
"metadata": ""
|
||||||
|
},
|
||||||
|
"outputAnchors": [
|
||||||
|
{
|
||||||
|
"id": "textFile_0-output-textFile-Document",
|
||||||
|
"name": "textFile",
|
||||||
|
"label": "Document",
|
||||||
|
"type": "Document"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": {},
|
||||||
|
"selected": false
|
||||||
|
},
|
||||||
|
"positionAbsolute": {
|
||||||
|
"x": 806.1207502345,
|
||||||
|
"y": 98.75458062792087
|
||||||
|
},
|
||||||
|
"selected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 300,
|
||||||
|
"height": 655,
|
||||||
|
"id": "pineconeUpsert_0",
|
||||||
|
"position": {
|
||||||
|
"x": 1206.7979889462367,
|
||||||
|
"y": 526.4616330622748
|
||||||
|
},
|
||||||
|
"type": "customNode",
|
||||||
|
"data": {
|
||||||
|
"id": "pineconeUpsert_0",
|
||||||
|
"label": "Pinecone Upsert Document",
|
||||||
|
"name": "pineconeUpsert",
|
||||||
|
"type": "Pinecone",
|
||||||
|
"baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
|
||||||
|
"category": "Vector Stores",
|
||||||
|
"description": "Upsert documents to Pinecone",
|
||||||
|
"inputParams": [
|
||||||
|
{
|
||||||
|
"label": "Pinecone Api Key",
|
||||||
|
"name": "pineconeApiKey",
|
||||||
|
"type": "password",
|
||||||
|
"id": "pineconeUpsert_0-input-pineconeApiKey-password"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Pinecone Environment",
|
||||||
|
"name": "pineconeEnv",
|
||||||
|
"type": "string",
|
||||||
|
"id": "pineconeUpsert_0-input-pineconeEnv-string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Pinecone Index",
|
||||||
|
"name": "pineconeIndex",
|
||||||
|
"type": "string",
|
||||||
|
"id": "pineconeUpsert_0-input-pineconeIndex-string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Pinecone Namespace",
|
||||||
|
"name": "pineconeNamespace",
|
||||||
|
"type": "string",
|
||||||
|
"placeholder": "my-first-namespace",
|
||||||
|
"additionalParams": true,
|
||||||
|
"optional": true,
|
||||||
|
"id": "pineconeUpsert_0-input-pineconeNamespace-string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Top K",
|
||||||
|
"name": "topK",
|
||||||
|
"description": "Number of top results to fetch. Default to 4",
|
||||||
|
"placeholder": "4",
|
||||||
|
"type": "number",
|
||||||
|
"additionalParams": true,
|
||||||
|
"optional": true,
|
||||||
|
"id": "pineconeUpsert_0-input-topK-number"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputAnchors": [
|
||||||
|
{
|
||||||
|
"label": "Document",
|
||||||
|
"name": "document",
|
||||||
|
"type": "Document",
|
||||||
|
"list": true,
|
||||||
|
"id": "pineconeUpsert_0-input-document-Document"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Embeddings",
|
||||||
|
"name": "embeddings",
|
||||||
|
"type": "Embeddings",
|
||||||
|
"id": "pineconeUpsert_0-input-embeddings-Embeddings"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": {
|
||||||
|
"document": ["{{textFile_0.data.instance}}"],
|
||||||
|
"embeddings": "{{openAIEmbeddings_1.data.instance}}",
|
||||||
|
"pineconeEnv": "",
|
||||||
|
"pineconeIndex": "",
|
||||||
|
"pineconeNamespace": "",
|
||||||
|
"topK": ""
|
||||||
|
},
|
||||||
|
"outputAnchors": [
|
||||||
|
{
|
||||||
|
"name": "output",
|
||||||
|
"label": "Output",
|
||||||
|
"type": "options",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
|
||||||
|
"name": "retriever",
|
||||||
|
"label": "Pinecone Retriever",
|
||||||
|
"type": "Pinecone | VectorStoreRetriever | BaseRetriever"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "pineconeUpsert_0-output-vectorStore-Pinecone|VectorStore",
|
||||||
|
"name": "vectorStore",
|
||||||
|
"label": "Pinecone Vector Store",
|
||||||
|
"type": "Pinecone | VectorStore"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": "retriever"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": {
|
||||||
|
"output": "retriever"
|
||||||
|
},
|
||||||
|
"selected": false
|
||||||
|
},
|
||||||
|
"selected": false,
|
||||||
|
"positionAbsolute": {
|
||||||
|
"x": 1206.7979889462367,
|
||||||
|
"y": 526.4616330622748
|
||||||
|
},
|
||||||
|
"dragging": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"edges": [
|
"edges": [
|
||||||
{
|
|
||||||
"source": "openAIEmbeddings_1",
|
|
||||||
"sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
|
|
||||||
"target": "pineconeUpsert_1",
|
|
||||||
"targetHandle": "pineconeUpsert_1-input-embeddings-Embeddings",
|
|
||||||
"type": "buttonedge",
|
|
||||||
"id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_1-pineconeUpsert_1-input-embeddings-Embeddings",
|
|
||||||
"data": {
|
|
||||||
"label": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "textFile_1",
|
|
||||||
"sourceHandle": "textFile_1-output-textFile-Document",
|
|
||||||
"target": "pineconeUpsert_1",
|
|
||||||
"targetHandle": "pineconeUpsert_1-input-document-Document",
|
|
||||||
"type": "buttonedge",
|
|
||||||
"id": "textFile_1-textFile_1-output-textFile-Document-pineconeUpsert_1-pineconeUpsert_1-input-document-Document",
|
|
||||||
"data": {
|
|
||||||
"label": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "recursiveCharacterTextSplitter_1",
|
|
||||||
"sourceHandle": "recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
|
|
||||||
"target": "textFile_1",
|
|
||||||
"targetHandle": "textFile_1-input-textSplitter-TextSplitter",
|
|
||||||
"type": "buttonedge",
|
|
||||||
"id": "recursiveCharacterTextSplitter_1-recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter-textFile_1-textFile_1-input-textSplitter-TextSplitter",
|
|
||||||
"data": {
|
|
||||||
"label": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"source": "chatOpenAI_0",
|
"source": "chatOpenAI_0",
|
||||||
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
|
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
|
||||||
@@ -618,12 +586,45 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "pineconeUpsert_1",
|
"source": "recursiveCharacterTextSplitter_1",
|
||||||
"sourceHandle": "pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
|
"sourceHandle": "recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
|
||||||
|
"target": "textFile_0",
|
||||||
|
"targetHandle": "textFile_0-input-textSplitter-TextSplitter",
|
||||||
|
"type": "buttonedge",
|
||||||
|
"id": "recursiveCharacterTextSplitter_1-recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter-textFile_0-textFile_0-input-textSplitter-TextSplitter",
|
||||||
|
"data": {
|
||||||
|
"label": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "textFile_0",
|
||||||
|
"sourceHandle": "textFile_0-output-textFile-Document",
|
||||||
|
"target": "pineconeUpsert_0",
|
||||||
|
"targetHandle": "pineconeUpsert_0-input-document-Document",
|
||||||
|
"type": "buttonedge",
|
||||||
|
"id": "textFile_0-textFile_0-output-textFile-Document-pineconeUpsert_0-pineconeUpsert_0-input-document-Document",
|
||||||
|
"data": {
|
||||||
|
"label": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "openAIEmbeddings_1",
|
||||||
|
"sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
|
||||||
|
"target": "pineconeUpsert_0",
|
||||||
|
"targetHandle": "pineconeUpsert_0-input-embeddings-Embeddings",
|
||||||
|
"type": "buttonedge",
|
||||||
|
"id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_0-pineconeUpsert_0-input-embeddings-Embeddings",
|
||||||
|
"data": {
|
||||||
|
"label": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "pineconeUpsert_0",
|
||||||
|
"sourceHandle": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
|
||||||
"target": "conversationalRetrievalQAChain_0",
|
"target": "conversationalRetrievalQAChain_0",
|
||||||
"targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
|
"targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
|
||||||
"type": "buttonedge",
|
"type": "buttonedge",
|
||||||
"id": "pineconeUpsert_1-pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
|
"id": "pineconeUpsert_0-pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
|
||||||
"data": {
|
"data": {
|
||||||
"label": ""
|
"label": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { IChildProcessMessage, IReactFlowNode, IReactFlowObject, IRunChatflowMessageValue, INodeData } from './Interface'
|
import { IChildProcessMessage, IReactFlowNode, IReactFlowObject, IRunChatflowMessageValue, INodeData } from './Interface'
|
||||||
import { buildLangchain, constructGraphs, getEndingNode, getStartingNodes, getUserHome, resolveVariables } from './utils'
|
import {
|
||||||
|
buildLangchain,
|
||||||
|
constructGraphs,
|
||||||
|
getEndingNode,
|
||||||
|
getStartingNodes,
|
||||||
|
getUserHome,
|
||||||
|
replaceInputsWithConfig,
|
||||||
|
resolveVariables
|
||||||
|
} from './utils'
|
||||||
import { DataSource } from 'typeorm'
|
import { DataSource } from 'typeorm'
|
||||||
import { ChatFlow } from './entity/ChatFlow'
|
import { ChatFlow } from './entity/ChatFlow'
|
||||||
import { ChatMessage } from './entity/ChatMessage'
|
import { ChatMessage } from './entity/ChatMessage'
|
||||||
@@ -109,6 +117,8 @@ export class ChildProcess {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (incomingInput.overrideConfig)
|
||||||
|
nodeToExecute.data = replaceInputsWithConfig(nodeToExecute.data, incomingInput.overrideConfig)
|
||||||
const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
|
const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
|
||||||
nodeToExecuteData = reactFlowNodeData
|
nodeToExecuteData = reactFlowNodeData
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ import {
|
|||||||
isVectorStoreFaiss,
|
isVectorStoreFaiss,
|
||||||
databaseEntities,
|
databaseEntities,
|
||||||
getApiKey,
|
getApiKey,
|
||||||
clearSessionMemory
|
clearSessionMemory,
|
||||||
|
replaceInputsWithConfig
|
||||||
} from './utils'
|
} from './utils'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { getDataSource } from './DataSource'
|
import { getDataSource } from './DataSource'
|
||||||
@@ -819,6 +820,8 @@ export class App {
|
|||||||
const nodeToExecute = reactFlowNodes.find((node: IReactFlowNode) => node.id === endingNodeId)
|
const nodeToExecute = reactFlowNodes.find((node: IReactFlowNode) => node.id === endingNodeId)
|
||||||
if (!nodeToExecute) return res.status(404).send(`Node ${endingNodeId} not found`)
|
if (!nodeToExecute) return res.status(404).send(`Node ${endingNodeId} not found`)
|
||||||
|
|
||||||
|
if (incomingInput.overrideConfig)
|
||||||
|
nodeToExecute.data = replaceInputsWithConfig(nodeToExecute.data, incomingInput.overrideConfig)
|
||||||
const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
|
const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
|
||||||
nodeToExecuteData = reactFlowNodeData
|
nodeToExecuteData = reactFlowNodeData
|
||||||
|
|
||||||
|
|||||||
@@ -428,9 +428,12 @@ export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig:
|
|||||||
const types = 'inputs'
|
const types = 'inputs'
|
||||||
|
|
||||||
const getParamValues = (paramsObj: ICommonObject) => {
|
const getParamValues = (paramsObj: ICommonObject) => {
|
||||||
for (const key in paramsObj) {
|
for (const config in overrideConfig) {
|
||||||
const paramValue: string = paramsObj[key]
|
let paramValue = overrideConfig[config] ?? paramsObj[config]
|
||||||
paramsObj[key] = overrideConfig[key] ?? paramValue
|
// Check if boolean
|
||||||
|
if (paramValue === 'true') paramValue = true
|
||||||
|
else if (paramValue === 'false') paramValue = false
|
||||||
|
paramsObj[config] = paramValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onAPIDialogClick = () => {
|
const onAPIDialogClick = () => {
|
||||||
|
// If file type is file, isFormDataRequired = true
|
||||||
let isFormDataRequired = false
|
let isFormDataRequired = false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const flowData = JSON.parse(chatflow.flowData)
|
const flowData = JSON.parse(chatflow.flowData)
|
||||||
const nodes = flowData.nodes
|
const nodes = flowData.nodes
|
||||||
@@ -105,11 +105,27 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If sessionId memory, isSessionMemory = true
|
||||||
|
let isSessionMemory = false
|
||||||
|
try {
|
||||||
|
const flowData = JSON.parse(chatflow.flowData)
|
||||||
|
const nodes = flowData.nodes
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (node.data.inputParams.find((param) => param.name === 'sessionId')) {
|
||||||
|
isSessionMemory = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
|
||||||
setAPIDialogProps({
|
setAPIDialogProps({
|
||||||
title: 'Embed in website or use as API',
|
title: 'Embed in website or use as API',
|
||||||
chatflowid: chatflow.id,
|
chatflowid: chatflow.id,
|
||||||
chatflowApiKeyId: chatflow.apikeyid,
|
chatflowApiKeyId: chatflow.apikeyid,
|
||||||
isFormDataRequired
|
isFormDataRequired,
|
||||||
|
isSessionMemory
|
||||||
})
|
})
|
||||||
setAPIDialogOpen(true)
|
setAPIDialogOpen(true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const ChatbotFull = () => {
|
|||||||
const [loginDialogOpen, setLoginDialogOpen] = useState(false)
|
const [loginDialogOpen, setLoginDialogOpen] = useState(false)
|
||||||
const [loginDialogProps, setLoginDialogProps] = useState({})
|
const [loginDialogProps, setLoginDialogProps] = useState({})
|
||||||
const [isLoading, setLoading] = useState(true)
|
const [isLoading, setLoading] = useState(true)
|
||||||
|
const [chatbotOverrideConfig, setChatbotOverrideConfig] = useState({})
|
||||||
|
|
||||||
const getSpecificChatflowFromPublicApi = useApi(chatflowsApi.getSpecificChatflowFromPublicEndpoint)
|
const getSpecificChatflowFromPublicApi = useApi(chatflowsApi.getSpecificChatflowFromPublicEndpoint)
|
||||||
const getSpecificChatflowApi = useApi(chatflowsApi.getSpecificChatflow)
|
const getSpecificChatflowApi = useApi(chatflowsApi.getSpecificChatflow)
|
||||||
@@ -77,10 +78,19 @@ const ChatbotFull = () => {
|
|||||||
setChatflow(chatflowData)
|
setChatflow(chatflowData)
|
||||||
if (chatflowData.chatbotConfig) {
|
if (chatflowData.chatbotConfig) {
|
||||||
try {
|
try {
|
||||||
setChatbotTheme(JSON.parse(chatflowData.chatbotConfig))
|
const parsedConfig = JSON.parse(chatflowData.chatbotConfig)
|
||||||
|
setChatbotTheme(parsedConfig)
|
||||||
|
if (parsedConfig.overrideConfig) {
|
||||||
|
// Generate new sessionId
|
||||||
|
if (parsedConfig.overrideConfig.generateNewSession) {
|
||||||
|
parsedConfig.overrideConfig.sessionId = Date.now().toString()
|
||||||
|
}
|
||||||
|
setChatbotOverrideConfig(parsedConfig.overrideConfig)
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
setChatbotTheme({})
|
setChatbotTheme({})
|
||||||
|
setChatbotOverrideConfig({})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +107,12 @@ const ChatbotFull = () => {
|
|||||||
{!chatflow || chatflow.apikeyid ? (
|
{!chatflow || chatflow.apikeyid ? (
|
||||||
<p>Invalid Chatbot</p>
|
<p>Invalid Chatbot</p>
|
||||||
) : (
|
) : (
|
||||||
<FullPageChat chatflowid={chatflow.id} apiHost={baseURL} theme={{ chatWindow: chatbotTheme }} />
|
<FullPageChat
|
||||||
|
chatflowid={chatflow.id}
|
||||||
|
apiHost={baseURL}
|
||||||
|
chatflowConfig={chatbotOverrideConfig}
|
||||||
|
theme={{ chatWindow: chatbotTheme }}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<LoginDialog show={loginDialogOpen} dialogProps={loginDialogProps} onConfirm={onLoginClick} />
|
<LoginDialog show={loginDialogOpen} dialogProps={loginDialogProps} onConfirm={onLoginClick} />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -612,7 +612,9 @@ query({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{codeLang === 'Share Chatbot' && !chatflowApiKeyId && <ShareChatbot />}
|
{codeLang === 'Share Chatbot' && !chatflowApiKeyId && (
|
||||||
|
<ShareChatbot isSessionMemory={dialogProps.isSessionMemory} />
|
||||||
|
)}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
))}
|
))}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useState } from 'react'
|
|||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from 'react-redux'
|
||||||
import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from 'store/actions'
|
import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from 'store/actions'
|
||||||
import { SketchPicker } from 'react-color'
|
import { SketchPicker } from 'react-color'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import { Box, Typography, Button, Switch, OutlinedInput, Popover, Stack, IconButton } from '@mui/material'
|
import { Box, Typography, Button, Switch, OutlinedInput, Popover, Stack, IconButton } from '@mui/material'
|
||||||
import { useTheme } from '@mui/material/styles'
|
import { useTheme } from '@mui/material/styles'
|
||||||
@@ -41,7 +42,7 @@ const defaultConfig = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShareChatbot = () => {
|
const ShareChatbot = ({ isSessionMemory }) => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const chatflow = useSelector((state) => state.canvas.chatflow)
|
const chatflow = useSelector((state) => state.canvas.chatflow)
|
||||||
@@ -54,6 +55,7 @@ const ShareChatbot = () => {
|
|||||||
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
|
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
|
||||||
|
|
||||||
const [isPublicChatflow, setChatflowIsPublic] = useState(chatflow.isPublic ?? false)
|
const [isPublicChatflow, setChatflowIsPublic] = useState(chatflow.isPublic ?? false)
|
||||||
|
const [generateNewSession, setGenerateNewSession] = useState(chatbotConfig?.generateNewSession ?? false)
|
||||||
|
|
||||||
const [welcomeMessage, setWelcomeMessage] = useState(chatbotConfig?.welcomeMessage ?? '')
|
const [welcomeMessage, setWelcomeMessage] = useState(chatbotConfig?.welcomeMessage ?? '')
|
||||||
const [backgroundColor, setBackgroundColor] = useState(chatbotConfig?.backgroundColor ?? defaultConfig.backgroundColor)
|
const [backgroundColor, setBackgroundColor] = useState(chatbotConfig?.backgroundColor ?? defaultConfig.backgroundColor)
|
||||||
@@ -103,7 +105,8 @@ const ShareChatbot = () => {
|
|||||||
userMessage: {
|
userMessage: {
|
||||||
showAvatar: false
|
showAvatar: false
|
||||||
},
|
},
|
||||||
textInput: {}
|
textInput: {},
|
||||||
|
overrideConfig: {}
|
||||||
}
|
}
|
||||||
if (welcomeMessage) obj.welcomeMessage = welcomeMessage
|
if (welcomeMessage) obj.welcomeMessage = welcomeMessage
|
||||||
if (backgroundColor) obj.backgroundColor = backgroundColor
|
if (backgroundColor) obj.backgroundColor = backgroundColor
|
||||||
@@ -125,6 +128,8 @@ const ShareChatbot = () => {
|
|||||||
if (textInputPlaceholder) obj.textInput.placeholder = textInputPlaceholder
|
if (textInputPlaceholder) obj.textInput.placeholder = textInputPlaceholder
|
||||||
if (textInputSendButtonColor) obj.textInput.sendButtonColor = textInputSendButtonColor
|
if (textInputSendButtonColor) obj.textInput.sendButtonColor = textInputSendButtonColor
|
||||||
|
|
||||||
|
if (isSessionMemory) obj.overrideConfig.generateNewSession = generateNewSession
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +278,9 @@ const ShareChatbot = () => {
|
|||||||
case 'userMessageShowAvatar':
|
case 'userMessageShowAvatar':
|
||||||
setUserMessageShowAvatar(value)
|
setUserMessageShowAvatar(value)
|
||||||
break
|
break
|
||||||
|
case 'generateNewSession':
|
||||||
|
setGenerateNewSession(value)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,6 +439,16 @@ const ShareChatbot = () => {
|
|||||||
{textField(textInputPlaceholder, 'textInputPlaceholder', 'TextInput Placeholder', 'string', `Type question..`)}
|
{textField(textInputPlaceholder, 'textInputPlaceholder', 'TextInput Placeholder', 'string', `Type question..`)}
|
||||||
{colorField(textInputSendButtonColor, 'textInputSendButtonColor', 'TextIntput Send Button Color')}
|
{colorField(textInputSendButtonColor, 'textInputSendButtonColor', 'TextIntput Send Button Color')}
|
||||||
|
|
||||||
|
{/*Session Memory Input*/}
|
||||||
|
{isSessionMemory && (
|
||||||
|
<>
|
||||||
|
<Typography variant='h4' sx={{ mb: 1, mt: 2 }}>
|
||||||
|
Session Memory
|
||||||
|
</Typography>
|
||||||
|
{booleanField(generateNewSession, 'generateNewSession', 'Start new session when chatbot link is opened or refreshed')}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<StyledButton style={{ marginBottom: 10, marginTop: 10 }} variant='contained' onClick={() => onSave()}>
|
<StyledButton style={{ marginBottom: 10, marginTop: 10 }} variant='contained' onClick={() => onSave()}>
|
||||||
Save Changes
|
Save Changes
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
@@ -470,4 +488,8 @@ const ShareChatbot = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShareChatbot.propTypes = {
|
||||||
|
isSessionMemory: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
export default ShareChatbot
|
export default ShareChatbot
|
||||||
|
|||||||
Reference in New Issue
Block a user