Merge branch 'main' of https://github.com/govind-kumarr/Flowise into feature/DynamoDb-Integration

This commit is contained in:
Govind Kumar
2023-07-02 23:04:15 +05:30
30 changed files with 1125 additions and 934 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<!-- markdownlint-disable MD030 --> <!-- markdownlint-disable MD030 -->
# Flowise - Low-Code LLM apps builder # Flowise
<a href="https://github.com/FlowiseAI/Flowise"> <a href="https://github.com/FlowiseAI/Flowise">
<img width="100%" src="https://github.com/FlowiseAI/Flowise/blob/main/images/flowise.gif?raw=true"></a> <img width="100%" src="https://github.com/FlowiseAI/Flowise/blob/main/images/flowise.gif?raw=true"></a>
+1
View File
@@ -3,4 +3,5 @@ PORT=3000
# FLOWISE_PASSWORD=1234 # FLOWISE_PASSWORD=1234
# DEBUG=true # DEBUG=true
# DATABASE_PATH=/your_database_path/.flowise # DATABASE_PATH=/your_database_path/.flowise
# APIKEY_PATH=/your_api_key_path/.flowise
# EXECUTION_MODE=child or main # EXECUTION_MODE=child or main
+1
View File
@@ -9,6 +9,7 @@ services:
- FLOWISE_USERNAME=${FLOWISE_USERNAME} - FLOWISE_USERNAME=${FLOWISE_USERNAME}
- FLOWISE_PASSWORD=${FLOWISE_PASSWORD} - FLOWISE_PASSWORD=${FLOWISE_PASSWORD}
- DATABASE_PATH=${DATABASE_PATH} - DATABASE_PATH=${DATABASE_PATH}
- APIKEY_PATH=${APIKEY_PATH}
- EXECUTION_MODE=${EXECUTION_MODE} - EXECUTION_MODE=${EXECUTION_MODE}
- DEBUG=${DEBUG} - DEBUG=${DEBUG}
ports: ports:
@@ -50,7 +50,7 @@ class LLMChain_Chains implements INode {
{ {
label: 'Output Prediction', label: 'Output Prediction',
name: 'outputPrediction', name: 'outputPrediction',
baseClasses: ['string'] baseClasses: ['string', 'json']
} }
] ]
} }
@@ -43,6 +43,10 @@ class AzureChatOpenAI_ChatModels implements INode {
{ {
label: 'gpt-35-turbo', label: 'gpt-35-turbo',
name: 'gpt-35-turbo' name: 'gpt-35-turbo'
},
{
label: 'gpt-35-turbo-16k',
name: 'gpt-35-turbo-16k'
} }
], ],
default: 'gpt-35-turbo', default: 'gpt-35-turbo',
@@ -70,14 +74,10 @@ class AzureChatOpenAI_ChatModels implements INode {
{ {
label: 'Azure OpenAI Api Version', label: 'Azure OpenAI Api Version',
name: 'azureOpenAIApiVersion', name: 'azureOpenAIApiVersion',
type: 'options', type: 'string',
options: [ placeholder: '2023-06-01-preview',
{ description:
label: '2023-03-15-preview', 'Description of Supported API Versions. Please refer <a target="_blank" href="https://learn.microsoft.com/en-us/azure/cognitive-services/openai/reference#chat-completions">examples</a>'
name: '2023-03-15-preview'
}
],
default: '2023-03-15-preview'
}, },
{ {
label: 'Max Tokens', label: 'Max Tokens',
@@ -0,0 +1,82 @@
import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
import { GitbookLoader } from 'langchain/document_loaders/web/gitbook'
class Gitbook_DocumentLoaders implements INode {
label: string
name: string
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs?: INodeParams[]
constructor() {
this.label = 'GitBook'
this.name = 'gitbook'
this.type = 'Document'
this.icon = 'gitbook.svg'
this.category = 'Document Loaders'
this.description = `Load data from GitBook`
this.baseClasses = [this.type]
this.inputs = [
{
label: 'Web Path',
name: 'webPath',
type: 'string',
placeholder: 'https://docs.gitbook.com/product-tour/navigation',
description: 'If want to load all paths from the GitBook provide only root path e.g.https://docs.gitbook.com/ '
},
{
label: 'Should Load All Paths',
name: 'shouldLoadAllPaths',
type: 'boolean',
description: 'Load from all paths in a given GitBook',
optional: true
},
{
label: 'Text Splitter',
name: 'textSplitter',
type: 'TextSplitter',
optional: true
},
{
label: 'Metadata',
name: 'metadata',
type: 'json',
optional: true,
additionalParams: true
}
]
}
async init(nodeData: INodeData): Promise<any> {
const webPath = nodeData.inputs?.webPath as string
const shouldLoadAllPaths = nodeData.inputs?.shouldLoadAllPaths as boolean
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const metadata = nodeData.inputs?.metadata
const loader = shouldLoadAllPaths ? new GitbookLoader(webPath, { shouldLoadAllPaths }) : new GitbookLoader(webPath)
const docs = textSplitter ? await loader.loadAndSplit() : await loader.load()
if (metadata) {
const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata)
return docs.map((doc) => {
return {
...doc,
metadata: {
...doc.metadata,
...parsedMetadata
}
}
})
}
return docs
}
}
module.exports = {
nodeClass: Gitbook_DocumentLoaders
}
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><switch><g><path d="M28.8 47.4c1 0 1.9.8 1.9 1.9 0 1-.8 1.9-1.9 1.9-1 0-1.9-.8-1.9-1.9 0-1.1.9-1.9 1.9-1.9m29.4-11.6c-1 0-1.9-.8-1.9-1.9 0-1 .8-1.9 1.9-1.9 1 0 1.9.8 1.9 1.9 0 1-.9 1.9-1.9 1.9m0-7.7c-3.2 0-5.8 2.6-5.8 5.8 0 .6.1 1.2.3 1.8L33.6 45.9c-1.1-1.6-2.9-2.5-4.8-2.5-2.2 0-4.2 1.3-5.2 3.2l-17.2-9c-1.8-1-3.2-3.9-3-6.7.1-1.4.6-2.5 1.3-2.9.5-.3 1-.2 1.7.1l.1.1c4.6 2.4 19.5 10.2 20.1 10.5 1 .4 1.5.6 3.2-.2l30.8-16c.5-.2 1-.6 1-1.3 0-.9-.9-1.3-.9-1.3-1.8-.8-4.5-2.1-7.1-3.3C48 14 41.6 11 38.8 9.5c-2.4-1.3-4.4-.2-4.7 0l-.7.3C20.7 16.2 3.9 24.5 2.9 25.1c-1.7 1-2.8 3.1-2.9 5.7-.2 4.1 1.9 8.4 4.9 9.9l18.2 9.4c.4 2.8 2.9 5 5.7 5 3.2 0 5.7-2.5 5.8-5.7l20-10.8c1 .8 2.3 1.2 3.6 1.2 3.2 0 5.8-2.6 5.8-5.8 0-3.3-2.6-5.9-5.8-5.9" fill="#4285fd"/></g></switch></svg>

After

Width:  |  Height:  |  Size: 826 B

@@ -43,7 +43,7 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
label: 'Azure OpenAI Api Version', label: 'Azure OpenAI Api Version',
name: 'azureOpenAIApiVersion', name: 'azureOpenAIApiVersion',
type: 'string', type: 'string',
placeholder: 'YOUR-API-VERSION', placeholder: '2023-03-15-preview',
description: description:
'Description of Supported API Versions. Please refer <a target="_blank" href="https://learn.microsoft.com/en-us/azure/cognitive-services/openai/reference#embeddings">examples</a>' 'Description of Supported API Versions. Please refer <a target="_blank" href="https://learn.microsoft.com/en-us/azure/cognitive-services/openai/reference#embeddings">examples</a>'
}, },
@@ -105,18 +105,10 @@ class AzureOpenAI_LLMs implements INode {
{ {
label: 'Azure OpenAI Api Version', label: 'Azure OpenAI Api Version',
name: 'azureOpenAIApiVersion', name: 'azureOpenAIApiVersion',
type: 'options', type: 'string',
options: [ placeholder: '2023-06-01-preview',
{ description:
label: '2023-03-15-preview', 'Description of Supported API Versions. Please refer <a target="_blank" href="https://learn.microsoft.com/en-us/azure/cognitive-services/openai/reference#completions">examples</a>'
name: '2023-03-15-preview'
},
{
label: '2022-12-01',
name: '2022-12-01'
}
],
default: '2023-03-15-preview'
}, },
{ {
label: 'Max Tokens', label: 'Max Tokens',
@@ -38,12 +38,7 @@ class ChatPromptTemplate_Prompts implements INode {
{ {
label: 'Format Prompt Values', label: 'Format Prompt Values',
name: 'promptValues', name: 'promptValues',
type: 'string', type: 'json',
rows: 4,
placeholder: `{
"input_language": "English",
"output_language": "French"
}`,
optional: true, optional: true,
acceptVariable: true, acceptVariable: true,
list: true list: true
@@ -31,12 +31,7 @@ class PromptTemplate_Prompts implements INode {
{ {
label: 'Format Prompt Values', label: 'Format Prompt Values',
name: 'promptValues', name: 'promptValues',
type: 'string', type: 'json',
rows: 4,
placeholder: `{
"input_language": "English",
"output_language": "French"
}`,
optional: true, optional: true,
acceptVariable: true, acceptVariable: true,
list: true list: true
-41
View File
@@ -245,47 +245,6 @@ export class CustomChainHandler extends BaseCallbackHandler {
} }
} }
export const returnJSONStr = (jsonStr: string): string => {
let jsonStrArray = jsonStr.split(':')
let wholeString = ''
for (let i = 0; i < jsonStrArray.length; i++) {
if (jsonStrArray[i].includes(',') && jsonStrArray[i + 1] !== undefined) {
const splitValueAndTitle = jsonStrArray[i].split(',')
const value = splitValueAndTitle[0]
const newTitle = splitValueAndTitle[1]
wholeString += handleEscapeDoubleQuote(value) + ',' + newTitle + ':'
} else {
wholeString += wholeString === '' ? jsonStrArray[i] + ':' : handleEscapeDoubleQuote(jsonStrArray[i])
}
}
return wholeString
}
const handleEscapeDoubleQuote = (value: string): string => {
let newValue = ''
if (value.includes('"')) {
const valueArray = value.split('"')
for (let i = 0; i < valueArray.length; i++) {
if ((i + 1) % 2 !== 0) {
switch (valueArray[i]) {
case '':
newValue += '"'
break
case '}':
newValue += '"}'
break
default:
newValue += '\\"' + valueArray[i] + '\\"'
}
} else {
newValue += valueArray[i]
}
}
}
return newValue === '' ? value : newValue
}
export const availableDependencies = [ export const availableDependencies = [
'@dqbd/tiktoken', '@dqbd/tiktoken',
'@getzep/zep-js', '@getzep/zep-js',
+76 -78
View File
@@ -3,68 +3,7 @@
"nodes": [ "nodes": [
{ {
"width": 300, "width": 300,
"height": 534, "height": 955,
"id": "promptTemplate_1",
"position": {
"x": 532.2791692529131,
"y": -31.128527027841372
},
"type": "customNode",
"data": {
"id": "promptTemplate_1",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_1-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_1-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"template": "Word: {word}\\nAntonym: {antonym}\\n",
"promptValues": ""
},
"outputAnchors": [
{
"id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 532.2791692529131,
"y": -31.128527027841372
},
"dragging": false
},
{
"width": 300,
"height": 956,
"id": "fewShotPromptTemplate_1", "id": "fewShotPromptTemplate_1",
"position": { "position": {
"x": 886.3229032369354, "x": 886.3229032369354,
@@ -139,7 +78,7 @@
], ],
"inputs": { "inputs": {
"examples": "[\n { \"word\": \"happy\", \"antonym\": \"sad\" },\n { \"word\": \"tall\", \"antonym\": \"short\" }\n]", "examples": "[\n { \"word\": \"happy\", \"antonym\": \"sad\" },\n { \"word\": \"tall\", \"antonym\": \"short\" }\n]",
"examplePrompt": "{{promptTemplate_1.data.instance}}", "examplePrompt": "{{promptTemplate_0.data.instance}}",
"prefix": "Give the antonym of every input", "prefix": "Give the antonym of every input",
"suffix": "Word: {input}\\nAntonym:", "suffix": "Word: {input}\\nAntonym:",
"exampleSeparator": "\\n\\n", "exampleSeparator": "\\n\\n",
@@ -165,7 +104,7 @@
}, },
{ {
"width": 300, "width": 300,
"height": 526, "height": 524,
"id": "openAI_1", "id": "openAI_1",
"position": { "position": {
"x": 1224.5139327142097, "x": 1224.5139327142097,
@@ -318,7 +257,7 @@
}, },
{ {
"width": 300, "width": 300,
"height": 407, "height": 405,
"id": "llmChain_1", "id": "llmChain_1",
"position": { "position": {
"x": 1635.363191180743, "x": 1635.363191180743,
@@ -375,10 +314,10 @@
"type": "LLMChain | BaseChain | BaseLangChain" "type": "LLMChain | BaseChain | BaseLangChain"
}, },
{ {
"id": "llmChain_1-output-outputPrediction-string", "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction", "name": "outputPrediction",
"label": "Output Prediction", "label": "Output Prediction",
"type": "string" "type": "string | json"
} }
], ],
"default": "llmChain" "default": "llmChain"
@@ -395,20 +334,68 @@
}, },
"selected": false, "selected": false,
"dragging": false "dragging": false
},
{
"width": 300,
"height": 475,
"id": "promptTemplate_0",
"position": {
"x": 540.0140796251119,
"y": -33.31673494170347
},
"type": "customNode",
"data": {
"id": "promptTemplate_0",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_0-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"template": "Word: {word}\\nAntonym: {antonym}\\n",
"promptValues": ""
},
"outputAnchors": [
{
"id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 540.0140796251119,
"y": -33.31673494170347
},
"dragging": false
} }
], ],
"edges": [ "edges": [
{
"source": "promptTemplate_1",
"sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "fewShotPromptTemplate_1",
"targetHandle": "fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
"type": "buttonedge",
"id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-fewShotPromptTemplate_1-fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
"data": {
"label": ""
}
},
{ {
"source": "openAI_1", "source": "openAI_1",
"sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain", "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
@@ -430,6 +417,17 @@
"data": { "data": {
"label": "" "label": ""
} }
},
{
"source": "promptTemplate_0",
"sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "fewShotPromptTemplate_1",
"targetHandle": "fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
"type": "buttonedge",
"id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-fewShotPromptTemplate_1-fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
"data": {
"label": ""
}
} }
] ]
} }
@@ -1,67 +1,6 @@
{ {
"description": "Simple LLM Chain using HuggingFace Inference API on falcon-7b-instruct model", "description": "Simple LLM Chain using HuggingFace Inference API on falcon-7b-instruct model",
"nodes": [ "nodes": [
{
"width": 300,
"height": 532,
"id": "promptTemplate_1",
"position": {
"x": 514.5434056794296,
"y": 507.47798128037107
},
"type": "customNode",
"data": {
"id": "promptTemplate_1",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_1-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_1-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"template": "Question: {question}\n\nAnswer: Let's think step by step.",
"promptValues": ""
},
"outputAnchors": [
{
"id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 514.5434056794296,
"y": 507.47798128037107
},
"dragging": false
},
{ {
"width": 300, "width": 300,
"height": 405, "height": 405,
@@ -105,7 +44,7 @@
], ],
"inputs": { "inputs": {
"model": "{{huggingFaceInference_LLMs_0.data.instance}}", "model": "{{huggingFaceInference_LLMs_0.data.instance}}",
"prompt": "{{promptTemplate_1.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}",
"chainName": "" "chainName": ""
}, },
"outputAnchors": [ "outputAnchors": [
@@ -121,10 +60,10 @@
"type": "LLMChain | BaseChain | BaseLangChain" "type": "LLMChain | BaseChain | BaseLangChain"
}, },
{ {
"id": "llmChain_1-output-outputPrediction-string", "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction", "name": "outputPrediction",
"label": "Output Prediction", "label": "Output Prediction",
"type": "string" "type": "string | json"
} }
], ],
"default": "llmChain" "default": "llmChain"
@@ -144,7 +83,7 @@
}, },
{ {
"width": 300, "width": 300,
"height": 427, "height": 429,
"id": "huggingFaceInference_LLMs_0", "id": "huggingFaceInference_LLMs_0",
"position": { "position": {
"x": 503.5630827259226, "x": 503.5630827259226,
@@ -245,20 +184,68 @@
"y": 50.79125094823999 "y": 50.79125094823999
}, },
"dragging": false "dragging": false
},
{
"width": 300,
"height": 475,
"id": "promptTemplate_0",
"position": {
"x": 506.50436294210306,
"y": 504.50766458127396
},
"type": "customNode",
"data": {
"id": "promptTemplate_0",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_0-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"template": "Question: {question}\n\nAnswer: Let's think step by step.",
"promptValues": ""
},
"outputAnchors": [
{
"id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 506.50436294210306,
"y": 504.50766458127396
},
"dragging": false
} }
], ],
"edges": [ "edges": [
{
"source": "promptTemplate_1",
"sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_1",
"targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge",
"id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
},
{ {
"source": "huggingFaceInference_LLMs_0", "source": "huggingFaceInference_LLMs_0",
"sourceHandle": "huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel|BaseLangChain", "sourceHandle": "huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel|BaseLangChain",
@@ -269,6 +256,17 @@
"data": { "data": {
"label": "" "label": ""
} }
},
{
"source": "promptTemplate_0",
"sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_1",
"targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge",
"id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
} }
] ]
} }
+249 -253
View File
@@ -3,7 +3,7 @@
"nodes": [ "nodes": [
{ {
"width": 300, "width": 300,
"height": 526, "height": 524,
"id": "openAI_2", "id": "openAI_2",
"position": { "position": {
"x": 793.6674026500068, "x": 793.6674026500068,
@@ -156,213 +156,11 @@
}, },
{ {
"width": 300, "width": 300,
"height": 534, "height": 524,
"id": "promptTemplate_2",
"position": {
"x": 796.3399644963663,
"y": 512.349657546027
},
"type": "customNode",
"data": {
"id": "promptTemplate_2",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_2-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_2-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"template": "You are an AI who performs one task based on the following objective: {objective}.\nRespond with how you would complete this task:",
"promptValues": "{\n \"objective\": \"{{question}}\"\n}"
},
"outputAnchors": [
{
"id": "promptTemplate_2-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 796.3399644963663,
"y": 512.349657546027
},
"dragging": false
},
{
"width": 300,
"height": 407,
"id": "llmChain_2",
"position": {
"x": 1225.2861408370582,
"y": 485.62403908243243
},
"type": "customNode",
"data": {
"id": "llmChain_2",
"label": "LLM Chain",
"name": "llmChain",
"type": "LLMChain",
"baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
"description": "Chain to run queries against LLMs",
"inputParams": [
{
"label": "Chain Name",
"name": "chainName",
"type": "string",
"placeholder": "Name Your Chain",
"optional": true,
"id": "llmChain_2-input-chainName-string"
}
],
"inputAnchors": [
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
"id": "llmChain_2-input-model-BaseLanguageModel"
},
{
"label": "Prompt",
"name": "prompt",
"type": "BasePromptTemplate",
"id": "llmChain_2-input-prompt-BasePromptTemplate"
}
],
"inputs": {
"model": "{{openAI_2.data.instance}}",
"prompt": "{{promptTemplate_2.data.instance}}",
"chainName": "First Chain"
},
"outputAnchors": [
{
"name": "output",
"label": "Output",
"type": "options",
"options": [
{
"id": "llmChain_2-output-llmChain-LLMChain|BaseChain|BaseLangChain",
"name": "llmChain",
"label": "LLM Chain",
"type": "LLMChain | BaseChain | BaseLangChain"
},
{
"id": "llmChain_2-output-outputPrediction-string",
"name": "outputPrediction",
"label": "Output Prediction",
"type": "string"
}
],
"default": "llmChain"
}
],
"outputs": {
"output": "outputPrediction"
},
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 1225.2861408370582,
"y": 485.62403908243243
}
},
{
"width": 300,
"height": 534,
"id": "promptTemplate_3",
"position": {
"x": 1589.206555911206,
"y": 460.23470154201766
},
"type": "customNode",
"data": {
"id": "promptTemplate_3",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_3-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_3-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"template": "You are a task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}.\nThe last completed task has the result: {result}.\nBased on the result, create new tasks to be completed by the AI system that do not overlap with result.\nReturn the tasks as an array.",
"promptValues": "{\n \"objective\": \"{{question}}\",\n \"result\": \"\"\n}"
},
"outputAnchors": [
{
"id": "promptTemplate_3-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1589.206555911206,
"y": 460.23470154201766
},
"dragging": false
},
{
"width": 300,
"height": 526,
"id": "openAI_3", "id": "openAI_3",
"position": { "position": {
"x": 1225.2861408370586, "x": 1216.061423775753,
"y": -62.7856517905272 "y": -20.35195330852082
}, },
"type": "customNode", "type": "customNode",
"data": { "data": {
@@ -503,27 +301,145 @@
"selected": false "selected": false
}, },
"positionAbsolute": { "positionAbsolute": {
"x": 1225.2861408370586, "x": 1216.061423775753,
"y": -62.7856517905272 "y": -20.35195330852082
}, },
"selected": false, "selected": false,
"dragging": false "dragging": false
}, },
{ {
"width": 300, "width": 300,
"height": 407, "height": 475,
"id": "llmChain_3", "id": "promptTemplate_0",
"position": { "position": {
"x": 1972.2671768945252, "x": 792.9464838535649,
"y": 142.73435419451476 "y": 527.1718536712464
}, },
"type": "customNode", "type": "customNode",
"data": { "data": {
"id": "llmChain_3", "id": "promptTemplate_0",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_0-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"template": "You are an AI who performs one task based on the following objective: {objective}.\nRespond with how you would complete this task:",
"promptValues": "{\"objective\":\"{{question}}\"}"
},
"outputAnchors": [
{
"id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 792.9464838535649,
"y": 527.1718536712464
},
"dragging": false
},
{
"width": 300,
"height": 475,
"id": "promptTemplate_1",
"position": {
"x": 1577.7482561604884,
"y": 516.186942924815
},
"type": "customNode",
"data": {
"id": "promptTemplate_1",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_1-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_1-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"template": "You are a task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}.\nThe last completed task has the result: {result}.\nBased on the result, create new tasks to be completed by the AI system that do not overlap with result.\nReturn the tasks as an array.",
"promptValues": "{\"objective\":\"{{question}}\",\"result\":\"{{llmChain_0.data.instance}}\"}"
},
"outputAnchors": [
{
"id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"positionAbsolute": {
"x": 1577.7482561604884,
"y": 516.186942924815
},
"selected": false,
"dragging": false
},
{
"width": 300,
"height": 405,
"id": "llmChain_0",
"position": {
"x": 1221.1346231272787,
"y": 538.9546839784628
},
"type": "customNode",
"data": {
"id": "llmChain_0",
"label": "LLM Chain", "label": "LLM Chain",
"name": "llmChain", "name": "llmChain",
"type": "LLMChain", "type": "LLMChain",
"baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"], "baseClasses": ["LLMChain", "BaseChain"],
"category": "Chains", "category": "Chains",
"description": "Chain to run queries against LLMs", "description": "Chain to run queries against LLMs",
"inputParams": [ "inputParams": [
@@ -533,7 +449,7 @@
"type": "string", "type": "string",
"placeholder": "Name Your Chain", "placeholder": "Name Your Chain",
"optional": true, "optional": true,
"id": "llmChain_3-input-chainName-string" "id": "llmChain_0-input-chainName-string"
} }
], ],
"inputAnchors": [ "inputAnchors": [
@@ -541,18 +457,98 @@
"label": "Language Model", "label": "Language Model",
"name": "model", "name": "model",
"type": "BaseLanguageModel", "type": "BaseLanguageModel",
"id": "llmChain_3-input-model-BaseLanguageModel" "id": "llmChain_0-input-model-BaseLanguageModel"
}, },
{ {
"label": "Prompt", "label": "Prompt",
"name": "prompt", "name": "prompt",
"type": "BasePromptTemplate", "type": "BasePromptTemplate",
"id": "llmChain_3-input-prompt-BasePromptTemplate" "id": "llmChain_0-input-prompt-BasePromptTemplate"
}
],
"inputs": {
"model": "{{openAI_2.data.instance}}",
"prompt": "{{promptTemplate_0.data.instance}}",
"chainName": "FirstChain"
},
"outputAnchors": [
{
"name": "output",
"label": "Output",
"type": "options",
"options": [
{
"id": "llmChain_0-output-llmChain-LLMChain|BaseChain",
"name": "llmChain",
"label": "LLM Chain",
"type": "LLMChain | BaseChain"
},
{
"id": "llmChain_0-output-outputPrediction-string|json",
"name": "outputPrediction",
"label": "Output Prediction",
"type": "string | json"
}
],
"default": "llmChain"
}
],
"outputs": {
"output": "outputPrediction"
},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1221.1346231272787,
"y": 538.9546839784628
},
"dragging": false
},
{
"width": 300,
"height": 405,
"id": "llmChain_1",
"position": {
"x": 1971.8054567964418,
"y": 207.624530381245
},
"type": "customNode",
"data": {
"id": "llmChain_1",
"label": "LLM Chain",
"name": "llmChain",
"type": "LLMChain",
"baseClasses": ["LLMChain", "BaseChain"],
"category": "Chains",
"description": "Chain to run queries against LLMs",
"inputParams": [
{
"label": "Chain Name",
"name": "chainName",
"type": "string",
"placeholder": "Name Your Chain",
"optional": true,
"id": "llmChain_1-input-chainName-string"
}
],
"inputAnchors": [
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
"id": "llmChain_1-input-model-BaseLanguageModel"
},
{
"label": "Prompt",
"name": "prompt",
"type": "BasePromptTemplate",
"id": "llmChain_1-input-prompt-BasePromptTemplate"
} }
], ],
"inputs": { "inputs": {
"model": "{{openAI_3.data.instance}}", "model": "{{openAI_3.data.instance}}",
"prompt": "{{promptTemplate_3.data.instance}}", "prompt": "{{promptTemplate_1.data.instance}}",
"chainName": "LastChain" "chainName": "LastChain"
}, },
"outputAnchors": [ "outputAnchors": [
@@ -562,16 +558,16 @@
"type": "options", "type": "options",
"options": [ "options": [
{ {
"id": "llmChain_3-output-llmChain-LLMChain|BaseChain|BaseLangChain", "id": "llmChain_1-output-llmChain-LLMChain|BaseChain",
"name": "llmChain", "name": "llmChain",
"label": "LLM Chain", "label": "LLM Chain",
"type": "LLMChain | BaseChain | BaseLangChain" "type": "LLMChain | BaseChain"
}, },
{ {
"id": "llmChain_3-output-outputPrediction-string", "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction", "name": "outputPrediction",
"label": "Output Prediction", "label": "Output Prediction",
"type": "string" "type": "string | json"
} }
], ],
"default": "llmChain" "default": "llmChain"
@@ -583,43 +579,43 @@
"selected": false "selected": false
}, },
"selected": false, "selected": false,
"dragging": false,
"positionAbsolute": { "positionAbsolute": {
"x": 1972.2671768945252, "x": 1971.8054567964418,
"y": 142.73435419451476 "y": 207.624530381245
} },
"dragging": false
} }
], ],
"edges": [ "edges": [
{
"source": "llmChain_2",
"sourceHandle": "llmChain_2-output-outputPrediction-string",
"target": "promptTemplate_3",
"targetHandle": "promptTemplate_3-input-promptValues-string",
"type": "buttonedge",
"id": "llmChain_2-llmChain_2-output-outputPrediction-string-promptTemplate_3-promptTemplate_3-input-promptValues-string",
"data": {
"label": ""
}
},
{ {
"source": "openAI_2", "source": "openAI_2",
"sourceHandle": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain", "sourceHandle": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
"target": "llmChain_2", "target": "llmChain_0",
"targetHandle": "llmChain_2-input-model-BaseLanguageModel", "targetHandle": "llmChain_0-input-model-BaseLanguageModel",
"type": "buttonedge", "type": "buttonedge",
"id": "openAI_2-openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_2-llmChain_2-input-model-BaseLanguageModel", "id": "openAI_2-openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_0-llmChain_0-input-model-BaseLanguageModel",
"data": { "data": {
"label": "" "label": ""
} }
}, },
{ {
"source": "promptTemplate_2", "source": "promptTemplate_0",
"sourceHandle": "promptTemplate_2-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate", "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_2", "target": "llmChain_0",
"targetHandle": "llmChain_2-input-prompt-BasePromptTemplate", "targetHandle": "llmChain_0-input-prompt-BasePromptTemplate",
"type": "buttonedge", "type": "buttonedge",
"id": "promptTemplate_2-promptTemplate_2-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_2-llmChain_2-input-prompt-BasePromptTemplate", "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_0-llmChain_0-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
},
{
"source": "llmChain_0",
"sourceHandle": "llmChain_0-output-outputPrediction-string|json",
"target": "promptTemplate_1",
"targetHandle": "promptTemplate_1-input-promptValues-json",
"type": "buttonedge",
"id": "llmChain_0-llmChain_0-output-outputPrediction-string|json-promptTemplate_1-promptTemplate_1-input-promptValues-json",
"data": { "data": {
"label": "" "label": ""
} }
@@ -627,21 +623,21 @@
{ {
"source": "openAI_3", "source": "openAI_3",
"sourceHandle": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain", "sourceHandle": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
"target": "llmChain_3", "target": "llmChain_1",
"targetHandle": "llmChain_3-input-model-BaseLanguageModel", "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"type": "buttonedge", "type": "buttonedge",
"id": "openAI_3-openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_3-llmChain_3-input-model-BaseLanguageModel", "id": "openAI_3-openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"data": { "data": {
"label": "" "label": ""
} }
}, },
{ {
"source": "promptTemplate_3", "source": "promptTemplate_1",
"sourceHandle": "promptTemplate_3-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate", "sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_3", "target": "llmChain_1",
"targetHandle": "llmChain_3-input-prompt-BasePromptTemplate", "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge", "type": "buttonedge",
"id": "promptTemplate_3-promptTemplate_3-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_3-llmChain_3-input-prompt-BasePromptTemplate", "id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": { "data": {
"label": "" "label": ""
} }
@@ -3,7 +3,7 @@
"nodes": [ "nodes": [
{ {
"width": 300, "width": 300,
"height": 526, "height": 524,
"id": "openAI_1", "id": "openAI_1",
"position": { "position": {
"x": 510.75932526856377, "x": 510.75932526856377,
@@ -156,68 +156,7 @@
}, },
{ {
"width": 300, "width": 300,
"height": 534, "height": 405,
"id": "promptTemplate_1",
"position": {
"x": 514.5434056794296,
"y": 507.47798128037107
},
"type": "customNode",
"data": {
"id": "promptTemplate_1",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_1-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_1-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"template": "",
"promptValues": ""
},
"outputAnchors": [
{
"id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 514.5434056794296,
"y": 507.47798128037107
},
"dragging": false
},
{
"width": 300,
"height": 407,
"id": "llmChain_1", "id": "llmChain_1",
"position": { "position": {
"x": 970.9254258940236, "x": 970.9254258940236,
@@ -258,7 +197,7 @@
], ],
"inputs": { "inputs": {
"model": "{{openAI_1.data.instance}}", "model": "{{openAI_1.data.instance}}",
"prompt": "{{promptTemplate_1.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}",
"chainName": "" "chainName": ""
}, },
"outputAnchors": [ "outputAnchors": [
@@ -274,10 +213,10 @@
"type": "LLMChain | BaseChain | BaseLangChain" "type": "LLMChain | BaseChain | BaseLangChain"
}, },
{ {
"id": "llmChain_1-output-outputPrediction-string", "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction", "name": "outputPrediction",
"label": "Output Prediction", "label": "Output Prediction",
"type": "string" "type": "string | json"
} }
], ],
"default": "llmChain" "default": "llmChain"
@@ -294,6 +233,65 @@
}, },
"selected": false, "selected": false,
"dragging": false "dragging": false
},
{
"width": 300,
"height": 475,
"id": "promptTemplate_0",
"position": {
"x": 517.7412884791509,
"y": 506.7411400888471
},
"type": "customNode",
"data": {
"id": "promptTemplate_0",
"label": "Prompt Template",
"name": "promptTemplate",
"type": "PromptTemplate",
"baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
"label": "Template",
"name": "template",
"type": "string",
"rows": 4,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_0-input-template-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"template": "What is a good name for a company that makes {product}?",
"promptValues": ""
},
"outputAnchors": [
{
"id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 517.7412884791509,
"y": 506.7411400888471
},
"dragging": false
} }
], ],
"edges": [ "edges": [
@@ -309,12 +307,12 @@
} }
}, },
{ {
"source": "promptTemplate_1", "source": "promptTemplate_0",
"sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate", "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_1", "target": "llmChain_1",
"targetHandle": "llmChain_1-input-prompt-BasePromptTemplate", "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge", "type": "buttonedge",
"id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate", "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": { "data": {
"label": "" "label": ""
} }
+76 -78
View File
@@ -3,77 +3,7 @@
"nodes": [ "nodes": [
{ {
"width": 300, "width": 300,
"height": 711, "height": 524,
"id": "chatPromptTemplate_1",
"position": {
"x": 441.8516979620723,
"y": 636.1108860994266
},
"type": "customNode",
"data": {
"id": "chatPromptTemplate_1",
"label": "Chat Prompt Template",
"name": "chatPromptTemplate",
"type": "ChatPromptTemplate",
"baseClasses": ["ChatPromptTemplate", "BaseChatPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a chat prompt",
"inputParams": [
{
"label": "System Message",
"name": "systemMessagePrompt",
"type": "string",
"rows": 4,
"placeholder": "You are a helpful assistant that translates {input_language} to {output_language}.",
"id": "chatPromptTemplate_1-input-systemMessagePrompt-string"
},
{
"label": "Human Message",
"name": "humanMessagePrompt",
"type": "string",
"rows": 4,
"placeholder": "{text}",
"id": "chatPromptTemplate_1-input-humanMessagePrompt-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "chatPromptTemplate_1-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"systemMessagePrompt": "You are a helpful assistant that translates {input_language} to {output_language}.",
"humanMessagePrompt": "{input}",
"promptValues": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}"
},
"outputAnchors": [
{
"id": "chatPromptTemplate_1-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"name": "chatPromptTemplate",
"label": "ChatPromptTemplate",
"type": "ChatPromptTemplate | BaseChatPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 441.8516979620723,
"y": 636.1108860994266
},
"dragging": false
},
{
"width": 300,
"height": 526,
"id": "chatOpenAI_1", "id": "chatOpenAI_1",
"position": { "position": {
"x": 439.5219561593599, "x": 439.5219561593599,
@@ -224,7 +154,7 @@
}, },
{ {
"width": 300, "width": 300,
"height": 407, "height": 405,
"id": "llmChain_1", "id": "llmChain_1",
"position": { "position": {
"x": 865.7775572410412, "x": 865.7775572410412,
@@ -265,7 +195,7 @@
], ],
"inputs": { "inputs": {
"model": "{{chatOpenAI_1.data.instance}}", "model": "{{chatOpenAI_1.data.instance}}",
"prompt": "{{chatPromptTemplate_1.data.instance}}", "prompt": "{{chatPromptTemplate_0.data.instance}}",
"chainName": "Language Translation" "chainName": "Language Translation"
}, },
"outputAnchors": [ "outputAnchors": [
@@ -281,10 +211,10 @@
"type": "LLMChain | BaseChain | BaseLangChain" "type": "LLMChain | BaseChain | BaseLangChain"
}, },
{ {
"id": "llmChain_1-output-outputPrediction-string", "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction", "name": "outputPrediction",
"label": "Output Prediction", "label": "Output Prediction",
"type": "string" "type": "string | json"
} }
], ],
"default": "llmChain" "default": "llmChain"
@@ -301,6 +231,74 @@
"y": 543.9211372857111 "y": 543.9211372857111
}, },
"dragging": false "dragging": false
},
{
"width": 300,
"height": 652,
"id": "chatPromptTemplate_0",
"position": {
"x": 437.51367850489396,
"y": 649.7619214034173
},
"type": "customNode",
"data": {
"id": "chatPromptTemplate_0",
"label": "Chat Prompt Template",
"name": "chatPromptTemplate",
"type": "ChatPromptTemplate",
"baseClasses": ["ChatPromptTemplate", "BaseChatPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
"description": "Schema to represent a chat prompt",
"inputParams": [
{
"label": "System Message",
"name": "systemMessagePrompt",
"type": "string",
"rows": 4,
"placeholder": "You are a helpful assistant that translates {input_language} to {output_language}.",
"id": "chatPromptTemplate_0-input-systemMessagePrompt-string"
},
{
"label": "Human Message",
"name": "humanMessagePrompt",
"type": "string",
"rows": 4,
"placeholder": "{text}",
"id": "chatPromptTemplate_0-input-humanMessagePrompt-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "chatPromptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"systemMessagePrompt": "You are a helpful assistant that translates {input_language} to {output_language}.",
"humanMessagePrompt": "{text}",
"promptValues": "{\"input_language\":\"English\",\"output_language\":\"French\",\"text\":\"{{question}}\"}"
},
"outputAnchors": [
{
"id": "chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"name": "chatPromptTemplate",
"label": "ChatPromptTemplate",
"type": "ChatPromptTemplate | BaseChatPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 437.51367850489396,
"y": 649.7619214034173
},
"dragging": false
} }
], ],
"edges": [ "edges": [
@@ -316,12 +314,12 @@
} }
}, },
{ {
"source": "chatPromptTemplate_1", "source": "chatPromptTemplate_0",
"sourceHandle": "chatPromptTemplate_1-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate", "sourceHandle": "chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"target": "llmChain_1", "target": "llmChain_1",
"targetHandle": "llmChain_1-input-prompt-BasePromptTemplate", "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge", "type": "buttonedge",
"id": "chatPromptTemplate_1-chatPromptTemplate_1-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate", "id": "chatPromptTemplate_0-chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": { "data": {
"label": "" "label": ""
} }
+2
View File
@@ -20,6 +20,7 @@ export default class Start extends Command {
PORT: Flags.string(), PORT: Flags.string(),
DEBUG: Flags.string(), DEBUG: Flags.string(),
DATABASE_PATH: Flags.string(), DATABASE_PATH: Flags.string(),
APIKEY_PATH: Flags.string(),
EXECUTION_MODE: Flags.string() EXECUTION_MODE: Flags.string()
} }
@@ -56,6 +57,7 @@ export default class Start extends Command {
if (flags.FLOWISE_PASSWORD) process.env.FLOWISE_PASSWORD = flags.FLOWISE_PASSWORD if (flags.FLOWISE_PASSWORD) process.env.FLOWISE_PASSWORD = flags.FLOWISE_PASSWORD
if (flags.PORT) process.env.PORT = flags.PORT if (flags.PORT) process.env.PORT = flags.PORT
if (flags.DATABASE_PATH) process.env.DATABASE_PATH = flags.DATABASE_PATH if (flags.DATABASE_PATH) process.env.DATABASE_PATH = flags.DATABASE_PATH
if (flags.APIKEY_PATH) process.env.APIKEY_PATH = flags.APIKEY_PATH
if (flags.EXECUTION_MODE) process.env.EXECUTION_MODE = flags.EXECUTION_MODE if (flags.EXECUTION_MODE) process.env.EXECUTION_MODE = flags.EXECUTION_MODE
if (flags.DEBUG) process.env.DEBUG = flags.DEBUG if (flags.DEBUG) process.env.DEBUG = flags.DEBUG
+10 -2
View File
@@ -93,7 +93,14 @@ export class App {
const basicAuthMiddleware = basicAuth({ const basicAuthMiddleware = basicAuth({
users: { [username]: password } users: { [username]: password }
}) })
const whitelistURLs = ['/api/v1/public-chatflows', '/api/v1/prediction/', '/api/v1/node-icon/', '/api/v1/chatflows-streaming'] const whitelistURLs = [
'/api/v1/verify/apikey/',
'/api/v1/chatflows/apikey/',
'/api/v1/public-chatflows',
'/api/v1/prediction/',
'/api/v1/node-icon/',
'/api/v1/chatflows-streaming'
]
this.app.use((req, res, next) => { this.app.use((req, res, next) => {
if (req.url.includes('/api/v1/')) { if (req.url.includes('/api/v1/')) {
whitelistURLs.some((url) => req.url.includes(url)) ? next() : basicAuthMiddleware(req, res, next) whitelistURLs.some((url) => req.url.includes(url)) ? next() : basicAuthMiddleware(req, res, next)
@@ -187,6 +194,7 @@ export class App {
.createQueryBuilder('cf') .createQueryBuilder('cf')
.where('cf.apikeyid = :apikeyid', { apikeyid: apiKey.id }) .where('cf.apikeyid = :apikeyid', { apikeyid: apiKey.id })
.orWhere('cf.apikeyid IS NULL') .orWhere('cf.apikeyid IS NULL')
.orWhere('cf.apikeyid = ""')
.orderBy('cf.name', 'ASC') .orderBy('cf.name', 'ASC')
.getMany() .getMany()
if (chatflows.length >= 1) return res.status(200).send(chatflows) if (chatflows.length >= 1) return res.status(200).send(chatflows)
@@ -502,7 +510,7 @@ export class App {
}) })
// Verify api key // Verify api key
this.app.get('/api/v1/apikey/:apiKey', async (req: Request, res: Response) => { this.app.get('/api/v1/verify/apikey/:apiKey', async (req: Request, res: Response) => {
try { try {
const apiKey = await getApiKey(req.params.apiKey) const apiKey = await getApiKey(req.params.apiKey)
if (!apiKey) return res.status(401).send('Unauthorized') if (!apiKey) return res.status(401).send('Unauthorized')
+1 -1
View File
@@ -18,6 +18,7 @@
"clsx": "^1.1.1", "clsx": "^1.1.1",
"flowise-embed": "*", "flowise-embed": "*",
"flowise-embed-react": "*", "flowise-embed-react": "*",
"flowise-react-json-view": "*",
"formik": "^2.2.6", "formik": "^2.2.6",
"framer-motion": "^4.1.13", "framer-motion": "^4.1.13",
"history": "^5.0.0", "history": "^5.0.0",
@@ -33,7 +34,6 @@
"react-datepicker": "^4.8.0", "react-datepicker": "^4.8.0",
"react-device-detect": "^1.17.0", "react-device-detect": "^1.17.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-json-view": "^1.21.3",
"react-markdown": "^8.0.6", "react-markdown": "^8.0.6",
"react-perfect-scrollbar": "^1.5.8", "react-perfect-scrollbar": "^1.5.8",
"react-redux": "^8.0.5", "react-redux": "^8.0.5",
@@ -1,256 +0,0 @@
import { createPortal } from 'react-dom'
import { useState, useEffect } from 'react'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import {
Button,
Dialog,
DialogActions,
DialogContent,
Box,
List,
ListItemButton,
ListItem,
ListItemAvatar,
ListItemText,
Typography,
Stack
} from '@mui/material'
import { useTheme } from '@mui/material/styles'
import PerfectScrollbar from 'react-perfect-scrollbar'
import { StyledButton } from 'ui-component/button/StyledButton'
import { DarkCodeEditor } from 'ui-component/editor/DarkCodeEditor'
import { LightCodeEditor } from 'ui-component/editor/LightCodeEditor'
import './EditPromptValuesDialog.css'
import { baseURL } from 'store/constant'
const EditPromptValuesDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
const portalElement = document.getElementById('portal')
const theme = useTheme()
const customization = useSelector((state) => state.customization)
const languageType = 'json'
const [inputValue, setInputValue] = useState('')
const [inputParam, setInputParam] = useState(null)
const [textCursorPosition, setTextCursorPosition] = useState({})
useEffect(() => {
if (dialogProps.value) setInputValue(dialogProps.value)
if (dialogProps.inputParam) setInputParam(dialogProps.inputParam)
return () => {
setInputValue('')
setInputParam(null)
setTextCursorPosition({})
}
}, [dialogProps])
const onMouseUp = (e) => {
if (e.target && e.target.selectionEnd && e.target.value) {
const cursorPosition = e.target.selectionEnd
const textBeforeCursorPosition = e.target.value.substring(0, cursorPosition)
const textAfterCursorPosition = e.target.value.substring(cursorPosition, e.target.value.length)
const body = {
textBeforeCursorPosition,
textAfterCursorPosition
}
setTextCursorPosition(body)
} else {
setTextCursorPosition({})
}
}
const onSelectOutputResponseClick = (node, isUserQuestion = false) => {
let variablePath = isUserQuestion ? `question` : `${node.id}.data.instance`
if (textCursorPosition) {
let newInput = ''
if (textCursorPosition.textBeforeCursorPosition === undefined && textCursorPosition.textAfterCursorPosition === undefined)
newInput = `${inputValue}${`{{${variablePath}}}`}`
else newInput = `${textCursorPosition.textBeforeCursorPosition}{{${variablePath}}}${textCursorPosition.textAfterCursorPosition}`
setInputValue(newInput)
}
}
const component = show ? (
<Dialog open={show} fullWidth maxWidth='md' aria-labelledby='alert-dialog-title' aria-describedby='alert-dialog-description'>
<DialogContent>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{inputParam && inputParam.type === 'string' && (
<div style={{ flex: 70 }}>
<Typography sx={{ mb: 2, ml: 1 }} variant='h4'>
{inputParam.label}
</Typography>
<PerfectScrollbar
style={{
border: '1px solid',
borderColor: theme.palette.grey['500'],
borderRadius: '12px',
height: '100%',
maxHeight: 'calc(100vh - 220px)',
overflowX: 'hidden',
backgroundColor: 'white'
}}
>
{customization.isDarkMode ? (
<DarkCodeEditor
disabled={dialogProps.disabled}
value={inputValue}
onValueChange={(code) => setInputValue(code)}
placeholder={inputParam.placeholder}
type={languageType}
onMouseUp={(e) => onMouseUp(e)}
onBlur={(e) => onMouseUp(e)}
style={{
fontSize: '0.875rem',
minHeight: 'calc(100vh - 220px)',
width: '100%'
}}
/>
) : (
<LightCodeEditor
disabled={dialogProps.disabled}
value={inputValue}
onValueChange={(code) => setInputValue(code)}
placeholder={inputParam.placeholder}
type={languageType}
onMouseUp={(e) => onMouseUp(e)}
onBlur={(e) => onMouseUp(e)}
style={{
fontSize: '0.875rem',
minHeight: 'calc(100vh - 220px)',
width: '100%'
}}
/>
)}
</PerfectScrollbar>
</div>
)}
{!dialogProps.disabled && inputParam && inputParam.acceptVariable && (
<div style={{ flex: 30 }}>
<Stack flexDirection='row' sx={{ mb: 1, ml: 2 }}>
<Typography variant='h4'>Select Variable</Typography>
</Stack>
<PerfectScrollbar style={{ height: '100%', maxHeight: 'calc(100vh - 220px)', overflowX: 'hidden' }}>
<Box sx={{ pl: 2, pr: 2 }}>
<List>
<ListItemButton
sx={{
p: 0,
borderRadius: `${customization.borderRadius}px`,
boxShadow: '0 2px 14px 0 rgb(32 40 45 / 8%)',
mb: 1
}}
disabled={dialogProps.disabled}
onClick={() => onSelectOutputResponseClick(null, true)}
>
<ListItem alignItems='center'>
<ListItemAvatar>
<div
style={{
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
}}
>
<img
style={{
width: '100%',
height: '100%',
padding: 10,
objectFit: 'contain'
}}
alt='AI'
src='https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/parroticon.png'
/>
</div>
</ListItemAvatar>
<ListItemText
sx={{ ml: 1 }}
primary='question'
secondary={`User's question from chatbox`}
/>
</ListItem>
</ListItemButton>
{dialogProps.availableNodesForVariable &&
dialogProps.availableNodesForVariable.length > 0 &&
dialogProps.availableNodesForVariable.map((node, index) => {
const selectedOutputAnchor = node.data.outputAnchors[0].options.find(
(ancr) => ancr.name === node.data.outputs['output']
)
return (
<ListItemButton
key={index}
sx={{
p: 0,
borderRadius: `${customization.borderRadius}px`,
boxShadow: '0 2px 14px 0 rgb(32 40 45 / 8%)',
mb: 1
}}
disabled={dialogProps.disabled}
onClick={() => onSelectOutputResponseClick(node)}
>
<ListItem alignItems='center'>
<ListItemAvatar>
<div
style={{
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
}}
>
<img
style={{
width: '100%',
height: '100%',
padding: 10,
objectFit: 'contain'
}}
alt={node.data.name}
src={`${baseURL}/api/v1/node-icon/${node.data.name}`}
/>
</div>
</ListItemAvatar>
<ListItemText
sx={{ ml: 1 }}
primary={
node.data.inputs.chainName ? node.data.inputs.chainName : node.data.id
}
secondary={`${selectedOutputAnchor?.label ?? 'output'} from ${
node.data.label
}`}
/>
</ListItem>
</ListItemButton>
)
})}
</List>
</Box>
</PerfectScrollbar>
</div>
)}
</div>
</DialogContent>
<DialogActions>
<Button onClick={onCancel}>{dialogProps.cancelButtonName}</Button>
<StyledButton disabled={dialogProps.disabled} variant='contained' onClick={() => onConfirm(inputValue, inputParam.name)}>
{dialogProps.confirmButtonName}
</StyledButton>
</DialogActions>
</Dialog>
) : null
return createPortal(component, portalElement)
}
EditPromptValuesDialog.propTypes = {
show: PropTypes.bool,
dialogProps: PropTypes.object,
onCancel: PropTypes.func,
onConfirm: PropTypes.func
}
export default EditPromptValuesDialog
@@ -0,0 +1,105 @@
import { createPortal } from 'react-dom'
import { useState, useEffect } from 'react'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import { Button, Dialog, DialogActions, DialogContent, Typography } from '@mui/material'
import { useTheme } from '@mui/material/styles'
import PerfectScrollbar from 'react-perfect-scrollbar'
import { StyledButton } from 'ui-component/button/StyledButton'
import { DarkCodeEditor } from 'ui-component/editor/DarkCodeEditor'
import { LightCodeEditor } from 'ui-component/editor/LightCodeEditor'
import './ExpandTextDialog.css'
const ExpandTextDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
const portalElement = document.getElementById('portal')
const theme = useTheme()
const customization = useSelector((state) => state.customization)
const languageType = 'json'
const [inputValue, setInputValue] = useState('')
const [inputParam, setInputParam] = useState(null)
useEffect(() => {
if (dialogProps.value) setInputValue(dialogProps.value)
if (dialogProps.inputParam) setInputParam(dialogProps.inputParam)
return () => {
setInputValue('')
setInputParam(null)
}
}, [dialogProps])
const component = show ? (
<Dialog open={show} fullWidth maxWidth='md' aria-labelledby='alert-dialog-title' aria-describedby='alert-dialog-description'>
<DialogContent>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{inputParam && inputParam.type === 'string' && (
<div style={{ flex: 70 }}>
<Typography sx={{ mb: 2, ml: 1 }} variant='h4'>
{inputParam.label}
</Typography>
<PerfectScrollbar
style={{
border: '1px solid',
borderColor: theme.palette.grey['500'],
borderRadius: '12px',
height: '100%',
maxHeight: 'calc(100vh - 220px)',
overflowX: 'hidden',
backgroundColor: 'white'
}}
>
{customization.isDarkMode ? (
<DarkCodeEditor
disabled={dialogProps.disabled}
value={inputValue}
onValueChange={(code) => setInputValue(code)}
placeholder={inputParam.placeholder}
type={languageType}
style={{
fontSize: '0.875rem',
minHeight: 'calc(100vh - 220px)',
width: '100%'
}}
/>
) : (
<LightCodeEditor
disabled={dialogProps.disabled}
value={inputValue}
onValueChange={(code) => setInputValue(code)}
placeholder={inputParam.placeholder}
type={languageType}
style={{
fontSize: '0.875rem',
minHeight: 'calc(100vh - 220px)',
width: '100%'
}}
/>
)}
</PerfectScrollbar>
</div>
)}
</div>
</DialogContent>
<DialogActions>
<Button onClick={onCancel}>{dialogProps.cancelButtonName}</Button>
<StyledButton disabled={dialogProps.disabled} variant='contained' onClick={() => onConfirm(inputValue, inputParam.name)}>
{dialogProps.confirmButtonName}
</StyledButton>
</DialogActions>
</Dialog>
) : null
return createPortal(component, portalElement)
}
ExpandTextDialog.propTypes = {
show: PropTypes.bool,
dialogProps: PropTypes.object,
onCancel: PropTypes.func,
onConfirm: PropTypes.func
}
export default ExpandTextDialog
@@ -0,0 +1,56 @@
import { createPortal } from 'react-dom'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import { Dialog, DialogContent, DialogTitle } from '@mui/material'
import PerfectScrollbar from 'react-perfect-scrollbar'
import { JsonEditorInput } from 'ui-component/json/JsonEditor'
const FormatPromptValuesDialog = ({ show, dialogProps, onChange, onCancel }) => {
const portalElement = document.getElementById('portal')
const customization = useSelector((state) => state.customization)
const component = show ? (
<Dialog
onClose={onCancel}
open={show}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'>
Format Prompt Values
</DialogTitle>
<DialogContent>
<PerfectScrollbar
style={{
height: '100%',
maxHeight: 'calc(100vh - 220px)',
overflowX: 'hidden'
}}
>
<JsonEditorInput
onChange={(newValue) => onChange(newValue)}
value={dialogProps.value}
isDarkMode={customization.isDarkMode}
inputParam={dialogProps.inputParam}
nodes={dialogProps.nodes}
edges={dialogProps.edges}
nodeId={dialogProps.nodeId}
/>
</PerfectScrollbar>
</DialogContent>
</Dialog>
) : null
return createPortal(component, portalElement)
}
FormatPromptValuesDialog.propTypes = {
show: PropTypes.bool,
dialogProps: PropTypes.object,
onChange: PropTypes.func,
onCancel: PropTypes.func
}
export default FormatPromptValuesDialog
@@ -3,7 +3,7 @@ import { useState, useEffect } from 'react'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Dialog, DialogContent, DialogTitle } from '@mui/material' import { Dialog, DialogContent, DialogTitle } from '@mui/material'
import ReactJson from 'react-json-view' import ReactJson from 'flowise-react-json-view'
const SourceDocDialog = ({ show, dialogProps, onCancel }) => { const SourceDocDialog = ({ show, dialogProps, onCancel }) => {
const portalElement = document.getElementById('portal') const portalElement = document.getElementById('portal')
+3 -3
View File
@@ -1,7 +1,7 @@
import { useState } from 'react' import { useState } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormControl, OutlinedInput } from '@mui/material' import { FormControl, OutlinedInput } from '@mui/material'
import EditPromptValuesDialog from 'ui-component/dialog/EditPromptValuesDialog' import ExpandTextDialog from 'ui-component/dialog/ExpandTextDialog'
export const Input = ({ inputParam, value, onChange, disabled = false, showDialog, dialogProps, onDialogCancel, onDialogConfirm }) => { export const Input = ({ inputParam, value, onChange, disabled = false, showDialog, dialogProps, onDialogCancel, onDialogConfirm }) => {
const [myValue, setMyValue] = useState(value ?? '') const [myValue, setMyValue] = useState(value ?? '')
@@ -45,7 +45,7 @@ export const Input = ({ inputParam, value, onChange, disabled = false, showDialo
/> />
</FormControl> </FormControl>
{showDialog && ( {showDialog && (
<EditPromptValuesDialog <ExpandTextDialog
show={showDialog} show={showDialog}
dialogProps={dialogProps} dialogProps={dialogProps}
onCancel={onDialogCancel} onCancel={onDialogCancel}
@@ -53,7 +53,7 @@ export const Input = ({ inputParam, value, onChange, disabled = false, showDialo
setMyValue(newValue) setMyValue(newValue)
onDialogConfirm(newValue, inputParamName) onDialogConfirm(newValue, inputParamName)
}} }}
></EditPromptValuesDialog> ></ExpandTextDialog>
)} )}
</> </>
) )
@@ -1,10 +1,32 @@
import { useState } from 'react' import { useEffect, useState } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { FormControl } from '@mui/material' import { FormControl, Popover } from '@mui/material'
import ReactJson from 'react-json-view' import ReactJson from 'flowise-react-json-view'
import SelectVariable from './SelectVariable'
import { cloneDeep } from 'lodash'
import { getAvailableNodesForVariable } from 'utils/genericHelper'
export const JsonEditorInput = ({ value, onChange, disabled = false, isDarkMode = false }) => { export const JsonEditorInput = ({ value, onChange, inputParam, nodes, edges, nodeId, disabled = false, isDarkMode = false }) => {
const [myValue, setMyValue] = useState(value ? JSON.parse(value) : {}) const [myValue, setMyValue] = useState(value ? JSON.parse(value) : {})
const [availableNodesForVariable, setAvailableNodesForVariable] = useState([])
const [mouseUpKey, setMouseUpKey] = useState('')
const [anchorEl, setAnchorEl] = useState(null)
const openPopOver = Boolean(anchorEl)
const handleClosePopOver = () => {
setAnchorEl(null)
}
const setNewVal = (val) => {
const newVal = cloneDeep(myValue)
newVal[mouseUpKey] = val
onChange(JSON.stringify(newVal))
setMyValue((params) => ({
...params,
[mouseUpKey]: val
}))
}
const onClipboardCopy = (e) => { const onClipboardCopy = (e) => {
const src = e.src const src = e.src
@@ -15,6 +37,13 @@ export const JsonEditorInput = ({ value, onChange, disabled = false, isDarkMode
} }
} }
useEffect(() => {
if (!disabled && nodes && edges && nodeId && inputParam) {
const nodesForVariable = inputParam?.acceptVariable ? getAvailableNodesForVariable(nodes, edges, nodeId, inputParam.id) : []
setAvailableNodesForVariable(nodesForVariable)
}
}, [disabled, inputParam, nodes, edges, nodeId])
return ( return (
<> <>
<FormControl sx={{ mt: 1, width: '100%' }} size='small'> <FormControl sx={{ mt: 1, width: '100%' }} size='small'>
@@ -30,6 +59,7 @@ export const JsonEditorInput = ({ value, onChange, disabled = false, isDarkMode
/> />
)} )}
{!disabled && ( {!disabled && (
<div key={JSON.stringify(myValue)}>
<ReactJson <ReactJson
theme={isDarkMode ? 'ocean' : 'rjv-default'} theme={isDarkMode ? 'ocean' : 'rjv-default'}
style={{ padding: 10, borderRadius: 10 }} style={{ padding: 10, borderRadius: 10 }}
@@ -38,6 +68,12 @@ export const JsonEditorInput = ({ value, onChange, disabled = false, isDarkMode
quotesOnKeys={false} quotesOnKeys={false}
displayDataTypes={false} displayDataTypes={false}
enableClipboard={(e) => onClipboardCopy(e)} enableClipboard={(e) => onClipboardCopy(e)}
onMouseUp={(event) => {
if (inputParam?.acceptVariable) {
setMouseUpKey(event.name)
setAnchorEl(event.currentTarget)
}
}}
onEdit={(edit) => { onEdit={(edit) => {
setMyValue(edit.updated_src) setMyValue(edit.updated_src)
onChange(JSON.stringify(edit.updated_src)) onChange(JSON.stringify(edit.updated_src))
@@ -50,8 +86,33 @@ export const JsonEditorInput = ({ value, onChange, disabled = false, isDarkMode
onChange(JSON.stringify(deleteobj.updated_src)) onChange(JSON.stringify(deleteobj.updated_src))
}} }}
/> />
</div>
)} )}
</FormControl> </FormControl>
{inputParam?.acceptVariable && (
<Popover
open={openPopOver}
anchorEl={anchorEl}
onClose={handleClosePopOver}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left'
}}
>
<SelectVariable
disabled={disabled}
availableNodesForVariable={availableNodesForVariable}
onSelectAndReturnVal={(val) => {
setNewVal(val)
handleClosePopOver()
}}
/>
</Popover>
)}
</> </>
) )
} }
@@ -60,5 +121,9 @@ JsonEditorInput.propTypes = {
value: PropTypes.string, value: PropTypes.string,
onChange: PropTypes.func, onChange: PropTypes.func,
disabled: PropTypes.bool, disabled: PropTypes.bool,
isDarkMode: PropTypes.bool isDarkMode: PropTypes.bool,
inputParam: PropTypes.object,
nodes: PropTypes.array,
edges: PropTypes.array,
nodeId: PropTypes.string
} }
@@ -0,0 +1,126 @@
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import { Box, List, ListItemButton, ListItem, ListItemAvatar, ListItemText, Typography, Stack } from '@mui/material'
import PerfectScrollbar from 'react-perfect-scrollbar'
import { baseURL } from 'store/constant'
const SelectVariable = ({ availableNodesForVariable, disabled = false, onSelectAndReturnVal }) => {
const customization = useSelector((state) => state.customization)
const onSelectOutputResponseClick = (node, isUserQuestion = false) => {
let variablePath = isUserQuestion ? `question` : `${node.id}.data.instance`
const newInput = `{{${variablePath}}}`
onSelectAndReturnVal(newInput)
}
return (
<>
{!disabled && (
<div style={{ flex: 30 }}>
<Stack flexDirection='row' sx={{ mb: 1, ml: 2, mt: 2 }}>
<Typography variant='h5'>Select Variable</Typography>
</Stack>
<PerfectScrollbar style={{ height: '100%', maxHeight: 'calc(100vh - 220px)', overflowX: 'hidden' }}>
<Box sx={{ pl: 2, pr: 2 }}>
<List>
<ListItemButton
sx={{
p: 0,
borderRadius: `${customization.borderRadius}px`,
boxShadow: '0 2px 14px 0 rgb(32 40 45 / 8%)',
mb: 1
}}
disabled={disabled}
onClick={() => onSelectOutputResponseClick(null, true)}
>
<ListItem alignItems='center'>
<ListItemAvatar>
<div
style={{
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
}}
>
<img
style={{
width: '100%',
height: '100%',
padding: 10,
objectFit: 'contain'
}}
alt='AI'
src='https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/parroticon.png'
/>
</div>
</ListItemAvatar>
<ListItemText sx={{ ml: 1 }} primary='question' secondary={`User's question from chatbox`} />
</ListItem>
</ListItemButton>
{availableNodesForVariable &&
availableNodesForVariable.length > 0 &&
availableNodesForVariable.map((node, index) => {
const selectedOutputAnchor = node.data.outputAnchors[0].options.find(
(ancr) => ancr.name === node.data.outputs['output']
)
return (
<ListItemButton
key={index}
sx={{
p: 0,
borderRadius: `${customization.borderRadius}px`,
boxShadow: '0 2px 14px 0 rgb(32 40 45 / 8%)',
mb: 1
}}
disabled={disabled}
onClick={() => onSelectOutputResponseClick(node)}
>
<ListItem alignItems='center'>
<ListItemAvatar>
<div
style={{
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
}}
>
<img
style={{
width: '100%',
height: '100%',
padding: 10,
objectFit: 'contain'
}}
alt={node.data.name}
src={`${baseURL}/api/v1/node-icon/${node.data.name}`}
/>
</div>
</ListItemAvatar>
<ListItemText
sx={{ ml: 1 }}
primary={node.data.inputs.chainName ? node.data.inputs.chainName : node.data.id}
secondary={`${selectedOutputAnchor?.label ?? 'output'} from ${node.data.label}`}
/>
</ListItem>
</ListItemButton>
)
})}
</List>
</Box>
</PerfectScrollbar>
</div>
)}
</>
)
}
SelectVariable.propTypes = {
availableNodesForVariable: PropTypes.array,
disabled: PropTypes.bool,
onSelectAndReturnVal: PropTypes.func
}
export default SelectVariable
+29 -1
View File
@@ -285,7 +285,7 @@ export const generateExportFlowData = (flowData) => {
} }
export const getAvailableNodesForVariable = (nodes, edges, target, targetHandle) => { export const getAvailableNodesForVariable = (nodes, edges, target, targetHandle) => {
// example edge id = "llmChain_0-llmChain_0-output-outputPrediction-string-llmChain_1-llmChain_1-input-promptValues-string" // example edge id = "llmChain_0-llmChain_0-output-outputPrediction-string|json-llmChain_1-llmChain_1-input-promptValues-string"
// {source} -{sourceHandle} -{target} -{targetHandle} // {source} -{sourceHandle} -{target} -{targetHandle}
const parentNodes = [] const parentNodes = []
const inputEdges = edges.filter((edg) => edg.target === target && edg.targetHandle === targetHandle) const inputEdges = edges.filter((edg) => edg.target === target && edg.targetHandle === targetHandle)
@@ -353,3 +353,31 @@ export const generateRandomGradient = () => {
return gradient return gradient
} }
export const getInputVariables = (paramValue) => {
let returnVal = paramValue
const variableStack = []
const inputVariables = []
let startIdx = 0
const endIdx = returnVal.length
while (startIdx < endIdx) {
const substr = returnVal.substring(startIdx, startIdx + 1)
// Store the opening double curly bracket
if (substr === '{') {
variableStack.push({ substr, startIdx: startIdx + 1 })
}
// Found the complete variable
if (substr === '}' && variableStack.length > 0 && variableStack[variableStack.length - 1].substr === '{') {
const variableStartIdx = variableStack[variableStack.length - 1].startIdx
const variableEndIdx = startIdx
const variableFullPath = returnVal.substring(variableStartIdx, variableEndIdx)
inputVariables.push(variableFullPath)
variableStack.pop()
}
startIdx += 1
}
return inputVariables
}
@@ -5,7 +5,7 @@ import { useSelector } from 'react-redux'
// material-ui // material-ui
import { useTheme, styled } from '@mui/material/styles' import { useTheme, styled } from '@mui/material/styles'
import { Box, Typography, Tooltip, IconButton } from '@mui/material' import { Box, Typography, Tooltip, IconButton, Button } from '@mui/material'
import { tooltipClasses } from '@mui/material/Tooltip' import { tooltipClasses } from '@mui/material/Tooltip'
import { IconArrowsMaximize, IconEdit } from '@tabler/icons' import { IconArrowsMaximize, IconEdit } from '@tabler/icons'
@@ -16,10 +16,13 @@ import { Input } from 'ui-component/input/Input'
import { File } from 'ui-component/file/File' import { File } from 'ui-component/file/File'
import { SwitchInput } from 'ui-component/switch/Switch' import { SwitchInput } from 'ui-component/switch/Switch'
import { flowContext } from 'store/context/ReactFlowContext' import { flowContext } from 'store/context/ReactFlowContext'
import { isValidConnection, getAvailableNodesForVariable } from 'utils/genericHelper' import { isValidConnection } from 'utils/genericHelper'
import { JsonEditorInput } from 'ui-component/json/JsonEditor' import { JsonEditorInput } from 'ui-component/json/JsonEditor'
import { TooltipWithParser } from 'ui-component/tooltip/TooltipWithParser' import { TooltipWithParser } from 'ui-component/tooltip/TooltipWithParser'
import ToolDialog from 'views/tools/ToolDialog' import ToolDialog from 'views/tools/ToolDialog'
import FormatPromptValuesDialog from 'ui-component/dialog/FormatPromptValuesDialog'
import { getInputVariables } from 'utils/genericHelper'
const EDITABLE_TOOLS = ['selectedTool'] const EDITABLE_TOOLS = ['selectedTool']
@@ -43,6 +46,8 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
const [showAsyncOptionDialog, setAsyncOptionEditDialog] = useState('') const [showAsyncOptionDialog, setAsyncOptionEditDialog] = useState('')
const [asyncOptionEditDialogProps, setAsyncOptionEditDialogProps] = useState({}) const [asyncOptionEditDialogProps, setAsyncOptionEditDialogProps] = useState({})
const [reloadTimestamp, setReloadTimestamp] = useState(Date.now().toString()) const [reloadTimestamp, setReloadTimestamp] = useState(Date.now().toString())
const [showFormatPromptValuesDialog, setShowFormatPromptValuesDialog] = useState(false)
const [formatPromptValuesDialogProps, setFormatPromptValuesDialogProps] = useState({})
const onExpandDialogClicked = (value, inputParam) => { const onExpandDialogClicked = (value, inputParam) => {
const dialogProp = { const dialogProp = {
@@ -52,17 +57,34 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
confirmButtonName: 'Save', confirmButtonName: 'Save',
cancelButtonName: 'Cancel' cancelButtonName: 'Cancel'
} }
if (!disabled) {
const nodes = reactFlowInstance.getNodes()
const edges = reactFlowInstance.getEdges()
const nodesForVariable = inputParam.acceptVariable ? getAvailableNodesForVariable(nodes, edges, data.id, inputParam.id) : []
dialogProp.availableNodesForVariable = nodesForVariable
}
setExpandDialogProps(dialogProp) setExpandDialogProps(dialogProp)
setShowExpandDialog(true) setShowExpandDialog(true)
} }
const onFormatPromptValuesClicked = (value, inputParam) => {
// Preset values if the field is format prompt values
let inputValue = value
if (inputParam.name === 'promptValues' && !value) {
const obj = {}
const templateValue =
(data.inputs['template'] ?? '') + (data.inputs['systemMessagePrompt'] ?? '') + (data.inputs['humanMessagePrompt'] ?? '')
const inputVariables = getInputVariables(templateValue)
for (const inputVariable of inputVariables) {
obj[inputVariable] = ''
}
if (Object.keys(obj).length) inputValue = JSON.stringify(obj)
}
const dialogProp = {
value: inputValue,
inputParam,
nodes: reactFlowInstance.getNodes(),
edges: reactFlowInstance.getEdges(),
nodeId: data.id
}
setFormatPromptValuesDialogProps(dialogProp)
setShowFormatPromptValuesDialog(true)
}
const onExpandDialogSave = (newValue, inputParamName) => { const onExpandDialogSave = (newValue, inputParamName) => {
setShowExpandDialog(false) setShowExpandDialog(false)
data.inputs[inputParamName] = newValue data.inputs[inputParamName] = newValue
@@ -217,6 +239,8 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
/> />
)} )}
{inputParam.type === 'json' && ( {inputParam.type === 'json' && (
<>
{!inputParam?.acceptVariable && (
<JsonEditorInput <JsonEditorInput
disabled={disabled} disabled={disabled}
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)} onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
@@ -224,6 +248,25 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
isDarkMode={customization.isDarkMode} isDarkMode={customization.isDarkMode}
/> />
)} )}
{inputParam?.acceptVariable && (
<>
<Button
sx={{ borderRadius: 25, width: '100%', mb: 2, mt: 2 }}
variant='outlined'
onClick={() => onFormatPromptValuesClicked(data.inputs[inputParam.name] ?? '', inputParam)}
>
Format Prompt Values
</Button>
<FormatPromptValuesDialog
show={showFormatPromptValuesDialog}
dialogProps={formatPromptValuesDialogProps}
onCancel={() => setShowFormatPromptValuesDialog(false)}
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
></FormatPromptValuesDialog>
</>
)}
</>
)}
{inputParam.type === 'options' && ( {inputParam.type === 'options' && (
<Dropdown <Dropdown
disabled={disabled} disabled={disabled}