From 17207e01dbb8cf05d784ab1ba3c132b505007ae3 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 18 Apr 2023 23:27:05 +0100 Subject: [PATCH] add format prompt values to prompt template --- .../nodes/chains/LLMChain/LLMChain.ts | 34 +- .../ChatPromptTemplate/ChatPromptTemplate.ts | 28 +- .../FewShotPromptTemplate.ts | 6 +- .../prompts/PromptTemplate/PromptTemplate.ts | 29 +- packages/components/src/Interface.ts | 14 + packages/server/marketplaces/Antonym.json | 134 ++--- .../server/marketplaces/Prompt Chaining.json | 468 +++++++++--------- .../server/marketplaces/Simple LLM Chain.json | 156 +++--- packages/server/marketplaces/Translator.json | 320 ++++++------ packages/server/src/index.ts | 55 +- packages/server/src/utils/index.ts | 21 +- .../ui/src/store/context/ReactFlowContext.js | 4 + packages/ui/src/ui-component/input/Input.js | 5 + 13 files changed, 675 insertions(+), 599 deletions(-) diff --git a/packages/components/nodes/chains/LLMChain/LLMChain.ts b/packages/components/nodes/chains/LLMChain/LLMChain.ts index df8f85cf..ae441eae 100644 --- a/packages/components/nodes/chains/LLMChain/LLMChain.ts +++ b/packages/components/nodes/chains/LLMChain/LLMChain.ts @@ -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 { 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 { 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) { diff --git a/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts b/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts index 5bec3ac0..c3c4d77f 100644 --- a/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts +++ b/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts @@ -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 { 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 } } diff --git a/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts b/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts index f137eedf..a42a1d08 100644 --- a/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts +++ b/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts @@ -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:` }, { diff --git a/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts b/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts index 50e79255..f976d64c 100644 --- a/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts +++ b/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts @@ -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 { 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) diff --git a/packages/components/src/Interface.ts b/packages/components/src/Interface.ts index d1831fa1..fd26020c 100644 --- a/packages/components/src/Interface.ts +++ b/packages/components/src/Interface.ts @@ -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) + } +} diff --git a/packages/server/marketplaces/Antonym.json b/packages/server/marketplaces/Antonym.json index 9f83076f..a56f5b58 100644 --- a/packages/server/marketplaces/Antonym.json +++ b/packages/server/marketplaces/Antonym.json @@ -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": "" + } } ] } diff --git a/packages/server/marketplaces/Prompt Chaining.json b/packages/server/marketplaces/Prompt Chaining.json index ede2b642..356c0b81 100644 --- a/packages/server/marketplaces/Prompt Chaining.json +++ b/packages/server/marketplaces/Prompt Chaining.json @@ -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": "" } diff --git a/packages/server/marketplaces/Simple LLM Chain.json b/packages/server/marketplaces/Simple LLM Chain.json index 994e2750..91867d24 100644 --- a/packages/server/marketplaces/Simple LLM Chain.json +++ b/packages/server/marketplaces/Simple LLM Chain.json @@ -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 } diff --git a/packages/server/marketplaces/Translator.json b/packages/server/marketplaces/Translator.json index 66e4e482..12269d73 100644 --- a/packages/server/marketplaces/Translator.json +++ b/packages/server/marketplaces/Translator.json @@ -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 } diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 7888da7b..7115a030 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -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, diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index 564ff51f..8ec72328 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -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 } diff --git a/packages/ui/src/store/context/ReactFlowContext.js b/packages/ui/src/store/context/ReactFlowContext.js index bbf4c0d4..4c35d702 100644 --- a/packages/ui/src/store/context/ReactFlowContext.js +++ b/packages/ui/src/store/context/ReactFlowContext.js @@ -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 = '' } diff --git a/packages/ui/src/ui-component/input/Input.js b/packages/ui/src/ui-component/input/Input.js index f04c086a..0886b22f 100644 --- a/packages/ui/src/ui-component/input/Input.js +++ b/packages/ui/src/ui-component/input/Input.js @@ -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' + } + }} />