add format prompt values to prompt template

This commit is contained in:
Henry
2023-04-18 23:27:05 +01:00
parent cd8a5b96eb
commit 17207e01db
13 changed files with 675 additions and 599 deletions
@@ -1,8 +1,7 @@
import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
import { LLMChain } from 'langchain/chains'
import { BaseLanguageModel } from 'langchain/base_language'
import { BasePromptTemplate } from 'langchain/prompts'
class LLMChain_Chains implements INode {
label: string
@@ -38,21 +37,8 @@ class LLMChain_Chains implements INode {
label: 'Chain Name',
name: 'chainName',
type: 'string',
placeholder: 'Task Creation Chain',
placeholder: 'Name Your Chain',
optional: true
},
{
label: 'Format Prompt Values',
name: 'promptValues',
type: 'string',
rows: 5,
placeholder: `{
"input_language": "English",
"output_language": "French"
}`,
optional: true,
acceptVariable: true,
list: true
}
]
this.outputs = [
@@ -71,9 +57,9 @@ class LLMChain_Chains implements INode {
async init(nodeData: INodeData, input: string): Promise<any> {
const model = nodeData.inputs?.model as BaseLanguageModel
const prompt = nodeData.inputs?.prompt as BasePromptTemplate
const prompt = nodeData.inputs?.prompt
const output = nodeData.outputs?.output as string
const promptValuesStr = nodeData.inputs?.promptValues as string
const promptValues = prompt.promptValues as ICommonObject
if (output === this.name) {
const chain = new LLMChain({ llm: model, prompt })
@@ -81,7 +67,7 @@ class LLMChain_Chains implements INode {
} else if (output === 'outputPrediction') {
const chain = new LLMChain({ llm: model, prompt })
const inputVariables = chain.prompt.inputVariables as string[] // ["product"]
const res = await runPrediction(inputVariables, chain, input, promptValuesStr)
const res = await runPrediction(inputVariables, chain, input, promptValues)
// eslint-disable-next-line no-console
console.log('\x1b[92m\x1b[1m\n*****OUTPUT PREDICTION*****\n\x1b[0m\x1b[0m')
// eslint-disable-next-line no-console
@@ -93,8 +79,9 @@ class LLMChain_Chains implements INode {
async run(nodeData: INodeData, input: string): Promise<string> {
const inputVariables = nodeData.instance.prompt.inputVariables as string[] // ["product"]
const chain = nodeData.instance as LLMChain
const promptValuesStr = nodeData.inputs?.promptValues as string
const res = await runPrediction(inputVariables, chain, input, promptValuesStr)
const promptValues = nodeData.inputs?.prompt.promptValues as ICommonObject
const res = await runPrediction(inputVariables, chain, input, promptValues)
// eslint-disable-next-line no-console
console.log('\x1b[93m\x1b[1m\n*****FINAL RESULT*****\n\x1b[0m\x1b[0m')
// eslint-disable-next-line no-console
@@ -103,14 +90,11 @@ class LLMChain_Chains implements INode {
}
}
const runPrediction = async (inputVariables: string[], chain: LLMChain, input: string, promptValuesStr: string) => {
const runPrediction = async (inputVariables: string[], chain: LLMChain, input: string, promptValues: ICommonObject) => {
if (inputVariables.length === 1) {
const res = await chain.run(input)
return res
} else if (inputVariables.length > 1) {
if (!promptValuesStr) throw new Error('Please provide Prompt Values')
const promptValues = JSON.parse(promptValuesStr.replace(/\s/g, ''))
let seen: string[] = []
for (const variable of inputVariables) {
@@ -1,4 +1,4 @@
import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
import { ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate } from 'langchain/prompts'
@@ -25,15 +25,28 @@ class ChatPromptTemplate_Prompts implements INode {
label: 'System Message',
name: 'systemMessagePrompt',
type: 'string',
rows: 3,
rows: 4,
placeholder: `You are a helpful assistant that translates {input_language} to {output_language}.`
},
{
label: 'Human Message',
name: 'humanMessagePrompt',
type: 'string',
rows: 3,
rows: 4,
placeholder: `{text}`
},
{
label: 'Format Prompt Values',
name: 'promptValues',
type: 'string',
rows: 4,
placeholder: `{
"input_language": "English",
"output_language": "French"
}`,
optional: true,
acceptVariable: true,
list: true
}
]
}
@@ -41,11 +54,20 @@ class ChatPromptTemplate_Prompts implements INode {
async init(nodeData: INodeData): Promise<any> {
const systemMessagePrompt = nodeData.inputs?.systemMessagePrompt as string
const humanMessagePrompt = nodeData.inputs?.humanMessagePrompt as string
const promptValuesStr = nodeData.inputs?.promptValues as string
const prompt = ChatPromptTemplate.fromPromptMessages([
SystemMessagePromptTemplate.fromTemplate(systemMessagePrompt),
HumanMessagePromptTemplate.fromTemplate(humanMessagePrompt)
])
let promptValues: ICommonObject = {}
if (promptValuesStr) {
promptValues = JSON.parse(promptValuesStr.replace(/\s/g, ''))
}
// @ts-ignore
prompt.promptValues = promptValues
return prompt
}
}
@@ -27,7 +27,7 @@ class FewShotPromptTemplate_Prompts implements INode {
label: 'Examples',
name: 'examples',
type: 'string',
rows: 5,
rows: 4,
placeholder: `[
{ "word": "happy", "antonym": "sad" },
{ "word": "tall", "antonym": "short" },
@@ -42,14 +42,14 @@ class FewShotPromptTemplate_Prompts implements INode {
label: 'Prefix',
name: 'prefix',
type: 'string',
rows: 3,
rows: 4,
placeholder: `Give the antonym of every input`
},
{
label: 'Suffix',
name: 'suffix',
type: 'string',
rows: 3,
rows: 4,
placeholder: `Word: {input}\nAntonym:`
},
{
@@ -1,6 +1,6 @@
import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { ICommonObject, INode, INodeData, INodeParams, PromptTemplate } from '../../../src/Interface'
import { getBaseClasses, getInputVariables } from '../../../src/utils'
import { PromptTemplate, PromptTemplateInput } from 'langchain/prompts'
import { PromptTemplateInput } from 'langchain/prompts'
class PromptTemplate_Prompts implements INode {
label: string
@@ -19,20 +19,40 @@ class PromptTemplate_Prompts implements INode {
this.icon = 'prompt.svg'
this.category = 'Prompts'
this.description = 'Schema to represent a basic prompt for an LLM'
this.baseClasses = [this.type, ...getBaseClasses(PromptTemplate)]
this.baseClasses = [...getBaseClasses(PromptTemplate)]
this.inputs = [
{
label: 'Template',
name: 'template',
type: 'string',
rows: 5,
rows: 4,
placeholder: `What is a good name for a company that makes {product}?`
},
{
label: 'Format Prompt Values',
name: 'promptValues',
type: 'string',
rows: 4,
placeholder: `{
"input_language": "English",
"output_language": "French"
}`,
optional: true,
acceptVariable: true,
list: true
}
]
}
async init(nodeData: INodeData): Promise<any> {
const template = nodeData.inputs?.template as string
const promptValuesStr = nodeData.inputs?.promptValues as string
let promptValues: ICommonObject = {}
if (promptValuesStr) {
promptValues = JSON.parse(promptValuesStr.replace(/\s/g, ''))
}
const inputVariables = getInputVariables(template)
try {
@@ -41,6 +61,7 @@ class PromptTemplate_Prompts implements INode {
inputVariables
}
const prompt = new PromptTemplate(options)
prompt.promptValues = promptValues
return prompt
} catch (e) {
throw new Error(e)
+14
View File
@@ -88,3 +88,17 @@ export interface IMessage {
message: string
type: MessageType
}
/**
* Classes
*/
import { PromptTemplate as LangchainPromptTemplate, PromptTemplateInput } from 'langchain/prompts'
export class PromptTemplate extends LangchainPromptTemplate {
promptValues: ICommonObject
constructor(input: PromptTemplateInput) {
super(input)
}
}
+73 -61
View File
@@ -3,11 +3,11 @@
"nodes": [
{
"width": 300,
"height": 366,
"height": 533,
"id": "promptTemplate_0",
"position": {
"x": 294.38456937448433,
"y": 66.5400435451831
"x": 567,
"y": 85
},
"type": "customNode",
"data": {
@@ -23,13 +23,26 @@
"label": "Template",
"name": "template",
"type": "string",
"rows": 5,
"placeholder": "What is a good name for a company that makes {product}?"
"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": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-input-promptValues-string"
}
],
"inputAnchors": [],
"inputs": {
"template": "Word: {word}\\nAntonym: {antonym}\\n"
"template": "Word: {word}\\nAntonym: {antonym}\\n",
"promptValues": ""
},
"outputAnchors": [
{
@@ -39,22 +52,23 @@
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 294.38456937448433,
"y": 66.5400435451831
},
"dragging": false
"x": 567,
"y": 85
}
},
{
"width": 300,
"height": 905,
"height": 955,
"id": "fewShotPromptTemplate_0",
"position": {
"x": 719.2200337843097,
"y": 67.20405755860693
"x": 942.9569947740308,
"y": 82.93222833361332
},
"type": "customNode",
"data": {
@@ -70,28 +84,32 @@
"label": "Examples",
"name": "examples",
"type": "string",
"rows": 5,
"placeholder": "[\n { \"word\": \"happy\", \"antonym\": \"sad\" },\n { \"word\": \"tall\", \"antonym\": \"short\" },\n]"
"rows": 4,
"placeholder": "[\n { \"word\": \"happy\", \"antonym\": \"sad\" },\n { \"word\": \"tall\", \"antonym\": \"short\" },\n]",
"id": "fewShotPromptTemplate_0-input-examples-string"
},
{
"label": "Prefix",
"name": "prefix",
"type": "string",
"rows": 3,
"placeholder": "Give the antonym of every input"
"rows": 4,
"placeholder": "Give the antonym of every input",
"id": "fewShotPromptTemplate_0-input-prefix-string"
},
{
"label": "Suffix",
"name": "suffix",
"type": "string",
"rows": 3,
"placeholder": "Word: {input}\nAntonym:"
"rows": 4,
"placeholder": "Word: {input}\nAntonym:",
"id": "fewShotPromptTemplate_0-input-suffix-string"
},
{
"label": "Example Seperator",
"name": "exampleSeparator",
"type": "string",
"placeholder": "\n\n"
"placeholder": "\n\n",
"id": "fewShotPromptTemplate_0-input-exampleSeparator-string"
},
{
"label": "Template Format",
@@ -107,7 +125,8 @@
"name": "jinja-2"
}
],
"default": "f-string"
"default": "f-string",
"id": "fewShotPromptTemplate_0-input-templateFormat-options"
}
],
"inputAnchors": [
@@ -134,12 +153,13 @@
"type": "FewShotPromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 719.2200337843097,
"y": 67.20405755860693
"x": 942.9569947740308,
"y": 82.93222833361332
},
"dragging": false
},
@@ -148,8 +168,8 @@
"height": 472,
"id": "openAI_0",
"position": {
"x": 1089.6434062122398,
"y": 27.515288538129425
"x": 1304.9299247555505,
"y": 8.707397857674266
},
"type": "customNode",
"data": {
@@ -164,7 +184,8 @@
{
"label": "OpenAI Api Key",
"name": "openAIApiKey",
"type": "password"
"type": "password",
"id": "openAI_0-input-openAIApiKey-password"
},
{
"label": "Model Name",
@@ -189,20 +210,22 @@
}
],
"default": "text-davinci-003",
"optional": true
"optional": true,
"id": "openAI_0-input-modelName-options"
},
{
"label": "Temperature",
"name": "temperature",
"type": "number",
"default": 0.7,
"optional": true
"optional": true,
"id": "openAI_0-input-temperature-number"
}
],
"inputAnchors": [],
"inputs": {
"modelName": "text-davinci-003",
"temperature": 0.7
"temperature": "0"
},
"outputAnchors": [
{
@@ -212,22 +235,23 @@
"type": "OpenAI | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1089.6434062122398,
"y": 27.515288538129425
"x": 1304.9299247555505,
"y": 8.707397857674266
},
"dragging": false
},
{
"width": 300,
"height": 592,
"height": 405,
"id": "llmChain_0",
"position": {
"x": 1489.0277667172852,
"y": 357.461975349771
"x": 1669.2177402155296,
"y": 338.65158088371567
},
"type": "customNode",
"data": {
@@ -243,20 +267,9 @@
"label": "Chain Name",
"name": "chainName",
"type": "string",
"placeholder": "Task Creation Chain",
"placeholder": "Name Your Chain",
"optional": true,
"id": "llmChain_0-input-chainName-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 5,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "llmChain_0-input-promptValues-string"
}
],
"inputAnchors": [
@@ -276,8 +289,7 @@
"inputs": {
"model": "{{openAI_0.data.instance}}",
"prompt": "{{fewShotPromptTemplate_0.data.instance}}",
"chainName": "",
"promptValues": ""
"chainName": ""
},
"outputAnchors": [
{
@@ -308,24 +320,13 @@
},
"selected": false,
"positionAbsolute": {
"x": 1489.0277667172852,
"y": 357.461975349771
"x": 1669.2177402155296,
"y": 338.65158088371567
},
"dragging": false
}
],
"edges": [
{
"source": "promptTemplate_0",
"sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "fewShotPromptTemplate_0",
"targetHandle": "fewShotPromptTemplate_0-input-examplePrompt-PromptTemplate",
"type": "buttonedge",
"id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-fewShotPromptTemplate_0-fewShotPromptTemplate_0-input-examplePrompt-PromptTemplate",
"data": {
"label": ""
}
},
{
"source": "openAI_0",
"sourceHandle": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
@@ -347,6 +348,17 @@
"data": {
"label": ""
}
},
{
"source": "promptTemplate_0",
"sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "fewShotPromptTemplate_0",
"targetHandle": "fewShotPromptTemplate_0-input-examplePrompt-PromptTemplate",
"type": "buttonedge",
"id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-fewShotPromptTemplate_0-fewShotPromptTemplate_0-input-examplePrompt-PromptTemplate",
"data": {
"label": ""
}
}
]
}
+234 -234
View File
@@ -3,11 +3,72 @@
"nodes": [
{
"width": 300,
"height": 592,
"height": 533,
"id": "promptTemplate_0",
"position": {
"x": 796.6293062501211,
"y": 523.6130142453178
},
"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": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-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_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 796.6293062501211,
"y": 523.6130142453178
},
"dragging": false
},
{
"width": 300,
"height": 405,
"id": "llmChain_0",
"position": {
"x": 586.058087758348,
"y": 109.99914917840562
"x": 1239.1590462985343,
"y": 477.999065568104
},
"type": "customNode",
"data": {
@@ -23,20 +84,9 @@
"label": "Chain Name",
"name": "chainName",
"type": "string",
"placeholder": "Task Creation Chain",
"placeholder": "Name Your Chain",
"optional": true,
"id": "llmChain_0-input-chainName-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 5,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "llmChain_0-input-promptValues-string"
}
],
"inputAnchors": [
@@ -56,8 +106,7 @@
"inputs": {
"model": "{{openAI_0.data.instance}}",
"prompt": "{{promptTemplate_0.data.instance}}",
"chainName": "FirstChain",
"promptValues": "{\n \"objective\": \"{{question}}\"\n}"
"chainName": "FirstChain"
},
"outputAnchors": [
{
@@ -88,198 +137,8 @@
},
"selected": false,
"positionAbsolute": {
"x": 586.058087758348,
"y": 109.99914917840562
},
"dragging": false
},
{
"width": 300,
"height": 366,
"id": "promptTemplate_0",
"position": {
"x": 231.20329590069747,
"y": 313.54994365714185
},
"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": 5,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_0-input-template-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:"
},
"outputAnchors": [
{
"id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 231.20329590069747,
"y": 313.54994365714185
},
"dragging": false
},
{
"width": 300,
"height": 592,
"id": "llmChain_1",
"position": {
"x": 1637.4327907249694,
"y": 127.71255193457947
},
"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": "Task Creation Chain",
"optional": true,
"id": "llmChain_1-input-chainName-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 5,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "llmChain_1-input-promptValues-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": {
"model": "{{openAI_0.data.instance}}",
"prompt": "{{promptTemplate_1.data.instance}}",
"chainName": "FinalChain",
"promptValues": "{\n \"objective\": \"{{question}}\",\n \"result\": \"{{llmChain_0.data.instance}}\"\n}"
},
"outputAnchors": [
{
"name": "output",
"label": "Output",
"type": "options",
"options": [
{
"id": "llmChain_1-output-llmChain-LLMChain|BaseChain",
"name": "llmChain",
"label": "LLM Chain",
"type": "LLMChain | BaseChain"
},
{
"id": "llmChain_1-output-outputPrediction-string",
"name": "outputPrediction",
"label": "Output Prediction",
"type": "string"
}
],
"default": "llmChain"
}
],
"outputs": {
"output": "llmChain"
},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1637.4327907249694,
"y": 127.71255193457947
},
"dragging": false
},
{
"width": 300,
"height": 366,
"id": "promptTemplate_1",
"position": {
"x": 950.292796637893,
"y": 62.31864791878181
},
"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": 5,
"placeholder": "What is a good name for a company that makes {product}?",
"id": "promptTemplate_1-input-template-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."
},
"outputAnchors": [
{
"id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 950.292796637893,
"y": 62.31864791878181
"x": 1239.1590462985343,
"y": 477.999065568104
},
"dragging": false
},
@@ -288,8 +147,8 @@
"height": 472,
"id": "openAI_0",
"position": {
"x": 225.7603660247592,
"y": -193.45016241085625
"x": 801.1835381596817,
"y": 21.196316952440355
},
"type": "customNode",
"data": {
@@ -359,19 +218,160 @@
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 225.7603660247592,
"y": -193.45016241085625
}
"x": 801.1835381596817,
"y": 21.196316952440355
},
"dragging": false
},
{
"width": 300,
"height": 405,
"id": "llmChain_1",
"position": {
"x": 2078.2072357874076,
"y": 476.5404337093371
},
"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": {
"model": "{{openAI_1.data.instance}}",
"prompt": "{{promptTemplate_1.data.instance}}",
"chainName": "LastChain"
},
"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",
"name": "outputPrediction",
"label": "Output Prediction",
"type": "string"
}
],
"default": "llmChain"
}
],
"outputs": {
"output": "llmChain"
},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 2078.2072357874076,
"y": 476.5404337093371
},
"dragging": false
},
{
"width": 300,
"height": 533,
"id": "promptTemplate_1",
"position": {
"x": 1686.7296107958396,
"y": 520.6957505277837
},
"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": "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\": \"{{llmChain_0.data.instance}}\"\n}"
},
"outputAnchors": [
{
"id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 1686.7296107958396,
"y": 520.6957505277837
},
"dragging": false
},
{
"width": 300,
"height": 472,
"id": "openAI_1",
"position": {
"x": 1275.7643968219816,
"y": -197.07668364123862
"x": 1688.3665789878662,
"y": 16.528695004385895
},
"type": "customNode",
"data": {
@@ -387,7 +387,7 @@
"label": "OpenAI Api Key",
"name": "openAIApiKey",
"type": "password",
"id": "openAI_0-input-openAIApiKey-password"
"id": "openAI_1-input-openAIApiKey-password"
},
{
"label": "Model Name",
@@ -413,7 +413,7 @@
],
"default": "text-davinci-003",
"optional": true,
"id": "openAI_0-input-modelName-options"
"id": "openAI_1-input-modelName-options"
},
{
"label": "Temperature",
@@ -421,7 +421,7 @@
"type": "number",
"default": 0.7,
"optional": true,
"id": "openAI_0-input-temperature-number"
"id": "openAI_1-input-temperature-number"
}
],
"inputAnchors": [],
@@ -431,7 +431,7 @@
},
"outputAnchors": [
{
"id": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"name": "openAI",
"label": "OpenAI",
"type": "OpenAI | BaseLLM | BaseLanguageModel"
@@ -441,11 +441,11 @@
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 1275.7643968219816,
"y": -197.07668364123862
}
"x": 1688.3665789878662,
"y": 16.528695004385895
},
"dragging": false
}
],
"edges": [
@@ -483,23 +483,23 @@
}
},
{
"source": "llmChain_0",
"sourceHandle": "llmChain_0-output-outputPrediction-string",
"source": "openAI_1",
"sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"target": "llmChain_1",
"targetHandle": "llmChain_1-input-promptValues-string",
"targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"type": "buttonedge",
"id": "llmChain_0-llmChain_0-output-outputPrediction-string-llmChain_1-llmChain_1-input-promptValues-string",
"id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"data": {
"label": ""
}
},
{
"source": "openAI_1",
"sourceHandle": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"target": "llmChain_1",
"targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"source": "llmChain_0",
"sourceHandle": "llmChain_0-output-outputPrediction-string",
"target": "promptTemplate_1",
"targetHandle": "promptTemplate_1-input-promptValues-string",
"type": "buttonedge",
"id": "openAI_1-openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"id": "llmChain_0-llmChain_0-output-outputPrediction-string-promptTemplate_1-promptTemplate_1-input-promptValues-string",
"data": {
"label": ""
}
@@ -6,8 +6,8 @@
"height": 472,
"id": "openAI_0",
"position": {
"x": 968.1753795547951,
"y": -8.62176310944858
"x": 618,
"y": 97
},
"type": "customNode",
"data": {
@@ -22,7 +22,8 @@
{
"label": "OpenAI Api Key",
"name": "openAIApiKey",
"type": "password"
"type": "password",
"id": "openAI_0-input-openAIApiKey-password"
},
{
"label": "Model Name",
@@ -47,14 +48,16 @@
}
],
"default": "text-davinci-003",
"optional": true
"optional": true,
"id": "openAI_0-input-modelName-options"
},
{
"label": "Temperature",
"name": "temperature",
"type": "number",
"default": 0.7,
"optional": true
"optional": true,
"id": "openAI_0-input-temperature-number"
}
],
"inputAnchors": [],
@@ -70,69 +73,23 @@
"type": "OpenAI | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 968.1753795547951,
"y": -8.62176310944858
},
"dragging": false
"x": 618,
"y": 97
}
},
{
"width": 300,
"height": 366,
"id": "promptTemplate_0",
"position": {
"x": 970.576876549135,
"y": 502.493937944275
},
"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": 5,
"placeholder": "What is a good name for a company that makes {product}?"
}
],
"inputAnchors": [],
"inputs": {
"template": "What is a good name for a company that makes {product}?"
},
"outputAnchors": [
{
"id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"name": "promptTemplate",
"label": "PromptTemplate",
"type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 970.576876549135,
"y": 502.493937944275
},
"dragging": false
},
{
"width": 300,
"height": 592,
"height": 405,
"id": "llmChain_0",
"position": {
"x": 1386.5063477084716,
"y": 211.47670100294192
"x": 998.3768292410252,
"y": 426.849642225371
},
"type": "customNode",
"data": {
@@ -148,20 +105,9 @@
"label": "Chain Name",
"name": "chainName",
"type": "string",
"placeholder": "Task Creation Chain",
"placeholder": "Name Your Chain",
"optional": true,
"id": "llmChain_0-input-chainName-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 5,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "llmChain_0-input-promptValues-string"
}
],
"inputAnchors": [
@@ -181,8 +127,7 @@
"inputs": {
"model": "{{openAI_0.data.instance}}",
"prompt": "{{promptTemplate_0.data.instance}}",
"chainName": "CompanyName Chain",
"promptValues": ""
"chainName": ""
},
"outputAnchors": [
{
@@ -213,8 +158,69 @@
},
"selected": false,
"positionAbsolute": {
"x": 1386.5063477084716,
"y": 211.47670100294192
"x": 998.3768292410252,
"y": 426.849642225371
},
"dragging": false
},
{
"width": 300,
"height": 533,
"id": "promptTemplate_0",
"position": {
"x": 618.658978699234,
"y": 589.2586352262571
},
"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": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "promptTemplate_0-input-promptValues-string"
}
],
"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": 618.658978699234,
"y": 589.2586352262571
},
"dragging": false
}
+163 -157
View File
@@ -1,151 +1,13 @@
{
"description": "Language translation using LLM Chain with a Chat Prompt Template and Chat Model",
"nodes": [
{
"width": 300,
"height": 473,
"id": "chatPromptTemplate_0",
"position": {
"x": 906.3845860429262,
"y": 522.7223115041937
},
"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": 3,
"placeholder": "You are a helpful assistant that translates {input_language} to {output_language}."
},
{
"label": "Human Message",
"name": "humanMessagePrompt",
"type": "string",
"rows": 3,
"placeholder": "{text}"
}
],
"inputAnchors": [],
"inputs": {
"systemMessagePrompt": "You are a helpful assistant that translates {input_language} to {output_language}.",
"humanMessagePrompt": "{input}"
},
"outputAnchors": [
{
"id": "chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"name": "chatPromptTemplate",
"label": "ChatPromptTemplate",
"type": "ChatPromptTemplate | BaseChatPromptTemplate | BasePromptTemplate"
}
],
"selected": false
},
"selected": false,
"dragging": false,
"positionAbsolute": {
"x": 906.3845860429262,
"y": 522.7223115041937
}
},
{
"width": 300,
"height": 472,
"id": "chatOpenAI_0",
"position": {
"x": 909.2168811101023,
"y": 10.159813502526418
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
"label": "OpenAI Api Key",
"name": "openAIApiKey",
"type": "password"
},
{
"label": "Model Name",
"name": "modelName",
"type": "options",
"options": [
{
"label": "gpt-4",
"name": "gpt-4"
},
{
"label": "gpt-4-0314",
"name": "gpt-4-0314"
},
{
"label": "gpt-4-32k-0314",
"name": "gpt-4-32k-0314"
},
{
"label": "gpt-3.5-turbo",
"name": "gpt-3.5-turbo"
},
{
"label": "gpt-3.5-turbo-0301",
"name": "gpt-3.5-turbo-0301"
}
],
"default": "gpt-3.5-turbo",
"optional": true
},
{
"label": "Temperature",
"name": "temperature",
"type": "number",
"default": 0.9,
"optional": true
}
],
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
"temperature": 0.9
},
"outputAnchors": [
{
"id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
"type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 909.2168811101023,
"y": 10.159813502526418
},
"dragging": false
},
{
"width": 300,
"height": 592,
"height": 405,
"id": "llmChain_0",
"position": {
"x": 1318.8661313433918,
"y": 323.51085023894643
"x": 1136.5578350285277,
"y": 619.2492937692573
},
"type": "customNode",
"data": {
@@ -161,20 +23,9 @@
"label": "Chain Name",
"name": "chainName",
"type": "string",
"placeholder": "Task Creation Chain",
"placeholder": "Name Your Chain",
"optional": true,
"id": "llmChain_0-input-chainName-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
"type": "string",
"rows": 5,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "llmChain_0-input-promptValues-string"
}
],
"inputAnchors": [
@@ -194,8 +45,7 @@
"inputs": {
"model": "{{chatOpenAI_0.data.instance}}",
"prompt": "{{chatPromptTemplate_0.data.instance}}",
"chainName": "",
"promptValues": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}"
"chainName": "Language Translation"
},
"outputAnchors": [
{
@@ -226,8 +76,164 @@
},
"selected": false,
"positionAbsolute": {
"x": 1318.8661313433918,
"y": 323.51085023894643
"x": 1136.5578350285277,
"y": 619.2492937692573
},
"dragging": false
},
{
"width": 300,
"height": 472,
"id": "chatOpenAI_0",
"position": {
"x": 776.3729862229602,
"y": 290.4580650723551
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
"type": "ChatOpenAI",
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
"label": "OpenAI Api Key",
"name": "openAIApiKey",
"type": "password",
"id": "chatOpenAI_0-input-openAIApiKey-password"
},
{
"label": "Model Name",
"name": "modelName",
"type": "options",
"options": [
{
"label": "gpt-4",
"name": "gpt-4"
},
{
"label": "gpt-4-0314",
"name": "gpt-4-0314"
},
{
"label": "gpt-4-32k-0314",
"name": "gpt-4-32k-0314"
},
{
"label": "gpt-3.5-turbo",
"name": "gpt-3.5-turbo"
},
{
"label": "gpt-3.5-turbo-0301",
"name": "gpt-3.5-turbo-0301"
}
],
"default": "gpt-3.5-turbo",
"optional": true,
"id": "chatOpenAI_0-input-modelName-options"
},
{
"label": "Temperature",
"name": "temperature",
"type": "number",
"default": 0.9,
"optional": true,
"id": "chatOpenAI_0-input-temperature-number"
}
],
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
"temperature": "0"
},
"outputAnchors": [
{
"id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
"type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 776.3729862229602,
"y": 290.4580650723551
},
"dragging": false
},
{
"width": 300,
"height": 710,
"id": "chatPromptTemplate_0",
"position": {
"x": 428.40848918154023,
"y": 291.77611240963313
},
"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": "string",
"rows": 4,
"placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
"optional": true,
"acceptVariable": true,
"list": true,
"id": "chatPromptTemplate_0-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_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"name": "chatPromptTemplate",
"label": "ChatPromptTemplate",
"type": "ChatPromptTemplate | BaseChatPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
"x": 428.40848918154023,
"y": 291.77611240963313
},
"dragging": false
}
+30 -25
View File
@@ -12,7 +12,7 @@ import {
getEndingNode,
constructGraphs,
resolveVariables,
checkIfFlowNeedToRebuild
checkStartNodeDependOnInput
} from './utils'
import { cloneDeep } from 'lodash'
import { getDataSource } from './DataSource'
@@ -203,6 +203,7 @@ export class App {
let nodeToExecuteData: INodeData
/*** Get chatflows and prepare data ***/
const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({
id: chatflowid
})
@@ -213,36 +214,40 @@ export class App {
const nodes = parsedFlowData.nodes
const edges = parsedFlowData.edges
// Check if node data exists in pool && not out of sync, prevent building whole flow again
/*** Get Ending Node with Directed Graph ***/
const { graph, nodeDependencies } = constructGraphs(nodes, edges)
const directedGraph = graph
const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
if (!endingNodeId) return res.status(500).send(`Ending node must be either a Chain or Agent`)
const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
if (!endingNodeData) return res.status(500).send(`Ending node must be either a Chain or Agent`)
if (endingNodeData.outputs && !Object.values(endingNodeData.outputs).includes(endingNodeData.name)) {
return res
.status(500)
.send(
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
)
}
/*** Get Starting Nodes with Non-Directed Graph ***/
const constructedObj = constructGraphs(nodes, edges, true)
const nonDirectedGraph = constructedObj.graph
const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
/* Check if:
* - Node Data already exists in pool
* - Still in sync (i.e the flow has not been modified since)
* - Flow doesn't start with nodes that depend on incomingInput.question
***/
if (
Object.prototype.hasOwnProperty.call(this.chatflowPool.activeChatflows, chatflowid) &&
this.chatflowPool.activeChatflows[chatflowid].inSync &&
!checkIfFlowNeedToRebuild(nodes, this.chatflowPool.activeChatflows[chatflowid].endingNodeData)
!checkStartNodeDependOnInput(nodes, startingNodeIds)
) {
nodeToExecuteData = this.chatflowPool.activeChatflows[chatflowid].endingNodeData
} else {
/*** Get Ending Node with Directed Graph ***/
const { graph, nodeDependencies } = constructGraphs(nodes, edges)
const directedGraph = graph
const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
if (!endingNodeId) return res.status(500).send(`Ending node must be either a Chain or Agent`)
const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
if (!endingNodeData) return res.status(500).send(`Ending node must be either a Chain or Agent`)
if (endingNodeData.outputs && !Object.values(endingNodeData.outputs).includes(endingNodeData.name)) {
return res
.status(500)
.send(
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
)
}
/*** Get Starting Nodes with Non-Directed Graph ***/
const constructedObj = constructGraphs(nodes, edges, true)
const nonDirectedGraph = constructedObj.graph
const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
/*** BFS to traverse from Starting Nodes to Ending Node ***/
const reactFlowNodes = await buildLangchain(
startingNodeIds,
+9 -12
View File
@@ -13,7 +13,7 @@ import {
INodeData
} from '../Interface'
import { cloneDeep, get } from 'lodash'
import { ICommonObject } from 'flowise-components'
import { ICommonObject, getInputVariables } from 'flowise-components'
const QUESTION_VAR_PREFIX = 'question'
@@ -351,19 +351,16 @@ export const resolveVariables = (reactFlowNodeData: INodeData, reactFlowNodes: I
* Rebuild flow if LLMChain has dependency on other chains
* User Question => Prompt_0 => LLMChain_0 => Prompt-1 => LLMChain_1
* @param {IReactFlowNode[]} nodes
* @param {INodeData} nodeData
* @param {string[]} startingNodeIds
* @returns {boolean}
*/
export const checkIfFlowNeedToRebuild = (nodes: IReactFlowNode[], nodeData: INodeData) => {
if (nodeData.name !== 'llmChain') return false
const node = nodes.find((nd) => nd.id === nodeData.id)
if (!node) throw new Error(`Node ${nodeData.id} not found`)
const inputs = node.data.inputs
for (const key in inputs) {
const isInputAcceptVariable = node.data.inputParams.find((param) => param.name === key)?.acceptVariable || false
if (isInputAcceptVariable && inputs[key].includes('{{') && inputs[key].includes('}}')) return true
export const checkStartNodeDependOnInput = (nodes: IReactFlowNode[], startingNodeIds: string[]) => {
const startingNodes = nodes.filter((nd) => startingNodeIds.includes(nd.id) && nd.id.toLowerCase().includes('prompttemplate'))
for (const node of startingNodes) {
for (const inputName in node.data.inputs) {
const inputVariables = getInputVariables(node.data.inputs[inputName])
if (inputVariables.length > 0) return true
}
}
return false
}
@@ -43,9 +43,13 @@ export const ReactFlowContext = ({ children }) => {
if (node.id === targetNodeId) {
let value
const inputAnchor = node.data.inputAnchors.find((ancr) => ancr.name === targetInput)
const inputParam = node.data.inputParams.find((param) => param.name === targetInput)
if (inputAnchor && inputAnchor.list) {
const values = node.data.inputs[targetInput] || []
value = values.filter((item) => !item.includes(sourceNodeId))
} else if (inputParam && inputParam.acceptVariable) {
value = node.data.inputs[targetInput].replace(`{{${sourceNodeId}.data.instance}}`, '') || ''
} else {
value = ''
}
@@ -36,6 +36,11 @@ export const Input = ({ inputParam, value, onChange, disabled = false, showDialo
setMyValue(e.target.value)
onChange(e.target.value)
}}
inputProps={{
style: {
height: inputParam.rows ? '90px' : 'inherit'
}
}}
/>
</FormControl>
<EditPromptValuesDialog