diff --git a/packages/components/credentials/AWSCredential.credential.ts b/packages/components/credentials/AWSCredential.credential.ts new file mode 100644 index 00000000..3c9dd3a6 --- /dev/null +++ b/packages/components/credentials/AWSCredential.credential.ts @@ -0,0 +1,47 @@ +import { INodeParams, INodeCredential } from '../src/Interface' + +class AWSApi implements INodeCredential { + label: string + name: string + version: number + description: string + optional: boolean + inputs: INodeParams[] + + constructor() { + this.label = 'AWS security credentials' + this.name = 'awsApi' + this.version = 1.0 + this.description = + 'Your AWS security credentials. When unspecified, credentials will be sourced from the runtime environment according to the default AWS SDK behavior.' + this.optional = true + this.inputs = [ + { + label: 'AWS Access Key', + name: 'awsKey', + type: 'string', + placeholder: '', + description: 'The access key for your AWS account.', + optional: true + }, + { + label: 'AWS Secret Access Key', + name: 'awsSecret', + type: 'password', + placeholder: '', + description: 'The secret key for your AWS account.', + optional: true + }, + { + label: 'AWS Session Key', + name: 'awsSession', + type: 'password', + placeholder: '', + description: 'The session key for your AWS account. This is only needed when you are using temporary credentials.', + optional: true + } + ] + } +} + +module.exports = { credClass: AWSApi } diff --git a/packages/components/nodes/chatmodels/AWSBedrock/AWSChatBedrock.ts b/packages/components/nodes/chatmodels/AWSBedrock/AWSChatBedrock.ts new file mode 100644 index 00000000..f5fa8bba --- /dev/null +++ b/packages/components/nodes/chatmodels/AWSBedrock/AWSChatBedrock.ts @@ -0,0 +1,166 @@ +import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface' +import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' +import { ChatBedrock } from 'langchain/chat_models/bedrock' +import { BaseBedrockInput } from 'langchain/dist/util/bedrock' + +/** + * I had to run the following to build the component + * and get the icon copied over to the dist directory + * Flowise/packages/components > yarn build + * + * @author Michael Connor + */ +class AWSChatBedrock_ChatModels implements INode { + label: string + name: string + version: number + type: string + icon: string + category: string + description: string + baseClasses: string[] + credential: INodeParams + inputs: INodeParams[] + + constructor() { + this.label = 'AWS Bedrock' + this.name = 'awsChatBedrock' + this.version = 1.1 + this.type = 'AWSChatBedrock' + this.icon = 'awsBedrock.png' + this.category = 'Chat Models' + this.description = 'Wrapper around AWS Bedrock large language models' + this.baseClasses = [this.type, ...getBaseClasses(ChatBedrock)] + this.credential = { + label: 'AWS Credential', + name: 'credential', + type: 'credential', + credentialNames: ['awsApi'], + optional: true + } + this.inputs = [ + { + label: 'Region', + name: 'region', + type: 'options', + options: [ + { label: 'af-south-1', name: 'af-south-1' }, + { label: 'ap-east-1', name: 'ap-east-1' }, + { label: 'ap-northeast-1', name: 'ap-northeast-1' }, + { label: 'ap-northeast-2', name: 'ap-northeast-2' }, + { label: 'ap-northeast-3', name: 'ap-northeast-3' }, + { label: 'ap-south-1', name: 'ap-south-1' }, + { label: 'ap-south-2', name: 'ap-south-2' }, + { label: 'ap-southeast-1', name: 'ap-southeast-1' }, + { label: 'ap-southeast-2', name: 'ap-southeast-2' }, + { label: 'ap-southeast-3', name: 'ap-southeast-3' }, + { label: 'ap-southeast-4', name: 'ap-southeast-4' }, + { label: 'ap-southeast-5', name: 'ap-southeast-5' }, + { label: 'ap-southeast-6', name: 'ap-southeast-6' }, + { label: 'ca-central-1', name: 'ca-central-1' }, + { label: 'ca-west-1', name: 'ca-west-1' }, + { label: 'cn-north-1', name: 'cn-north-1' }, + { label: 'cn-northwest-1', name: 'cn-northwest-1' }, + { label: 'eu-central-1', name: 'eu-central-1' }, + { label: 'eu-central-2', name: 'eu-central-2' }, + { label: 'eu-north-1', name: 'eu-north-1' }, + { label: 'eu-south-1', name: 'eu-south-1' }, + { label: 'eu-south-2', name: 'eu-south-2' }, + { label: 'eu-west-1', name: 'eu-west-1' }, + { label: 'eu-west-2', name: 'eu-west-2' }, + { label: 'eu-west-3', name: 'eu-west-3' }, + { label: 'il-central-1', name: 'il-central-1' }, + { label: 'me-central-1', name: 'me-central-1' }, + { label: 'me-south-1', name: 'me-south-1' }, + { label: 'sa-east-1', name: 'sa-east-1' }, + { label: 'us-east-1', name: 'us-east-1' }, + { label: 'us-east-2', name: 'us-east-2' }, + { label: 'us-gov-east-1', name: 'us-gov-east-1' }, + { label: 'us-gov-west-1', name: 'us-gov-west-1' }, + { label: 'us-west-1', name: 'us-west-1' }, + { label: 'us-west-2', name: 'us-west-2' } + ], + default: 'us-east-1', + optional: false + }, + { + label: 'Model Name', + name: 'model', + type: 'options', + options: [ + { label: 'amazon.titan-tg1-large', name: 'amazon.titan-tg1-large' }, + { label: 'amazon.titan-e1t-medium', name: 'amazon.titan-e1t-medium' }, + { label: 'stability.stable-diffusion-xl', name: 'stability.stable-diffusion-xl' }, + { label: 'ai21.j2-grande-instruct', name: 'ai21.j2-grande-instruct' }, + { label: 'ai21.j2-jumbo-instruct', name: 'ai21.j2-jumbo-instruct' }, + { label: 'ai21.j2-mid', name: 'ai21.j2-mid' }, + { label: 'ai21.j2-ultra', name: 'ai21.j2-ultra' }, + { label: 'anthropic.claude-instant-v1', name: 'anthropic.claude-instant-v1' }, + { label: 'anthropic.claude-v1', name: 'anthropic.claude-v1' }, + { label: 'anthropic.claude-v2', name: 'anthropic.claude-v2' } + ], + default: 'anthropic.claude-v2', + optional: false + }, + { + label: 'Temperature', + name: 'temperature', + type: 'number', + step: 0.1, + description: 'Temperature parameter may not apply to certain model. Please check available model parameters', + optional: true, + default: 0.7, + additionalParams: false + }, + { + label: 'Max Tokens to Sample', + name: 'max_tokens_to_sample', + type: 'number', + step: 10, + description: 'Max Tokens parameter may not apply to certain model. Please check available model parameters', + optional: false, + default: 200, + additionalParams: false + } + ] + } + + async init(nodeData: INodeData, _: string, options: ICommonObject): Promise { + const iRegion = nodeData.inputs?.region as string + const iModel = nodeData.inputs?.model as string + const iTemperature = nodeData.inputs?.temperature as string + const iMax_tokens_to_sample = nodeData.inputs?.max_tokens_to_sample as string + + const obj: BaseBedrockInput = { + region: iRegion, + model: iModel, + maxTokens: parseInt(iMax_tokens_to_sample, 10), + temperature: parseFloat(iTemperature) + } + + /** + * Long-term credentials specified in LLM configuration are optional. + * Bedrock's credential provider falls back to the AWS SDK to fetch + * credentials from the running environment. + * When specified, we override the default provider with configured values. + * @see https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-node/README.md + */ + const credentialData = await getCredentialData(nodeData.credential ?? '', options) + if (credentialData && Object.keys(credentialData).length !== 0) { + const credentialApiKey = getCredentialParam('awsKey', credentialData, nodeData) + const credentialApiSecret = getCredentialParam('awsSecret', credentialData, nodeData) + const credentialApiSession = getCredentialParam('awsSession', credentialData, nodeData) + + obj.credentials = { + accessKeyId: credentialApiKey, + secretAccessKey: credentialApiSecret, + sessionToken: credentialApiSession + } + } + + const amazonBedrock = new ChatBedrock(obj) + return amazonBedrock + } +} + +module.exports = { nodeClass: AWSChatBedrock_ChatModels } diff --git a/packages/components/nodes/chatmodels/AWSBedrock/awsBedrock.png b/packages/components/nodes/chatmodels/AWSBedrock/awsBedrock.png new file mode 100644 index 00000000..483bc69a Binary files /dev/null and b/packages/components/nodes/chatmodels/AWSBedrock/awsBedrock.png differ diff --git a/packages/components/nodes/documentloaders/PlainText/PlainText.ts b/packages/components/nodes/documentloaders/PlainText/PlainText.ts new file mode 100644 index 00000000..261f2d98 --- /dev/null +++ b/packages/components/nodes/documentloaders/PlainText/PlainText.ts @@ -0,0 +1,88 @@ +import { INode, INodeData, INodeParams } from '../../../src/Interface' +import { TextSplitter } from 'langchain/text_splitter' +import { Document } from 'langchain/document' + +class PlainText_DocumentLoaders implements INode { + label: string + name: string + version: number + description: string + type: string + icon: string + category: string + baseClasses: string[] + inputs: INodeParams[] + + constructor() { + this.label = 'Plain Text' + this.name = 'plainText' + this.version = 1.0 + this.type = 'Document' + this.icon = 'plaintext.svg' + this.category = 'Document Loaders' + this.description = `Load data from plain text` + this.baseClasses = [this.type] + this.inputs = [ + { + label: 'Text', + name: 'text', + type: 'string', + rows: 4, + placeholder: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua...' + }, + { + label: 'Text Splitter', + name: 'textSplitter', + type: 'TextSplitter', + optional: true + }, + { + label: 'Metadata', + name: 'metadata', + type: 'json', + optional: true, + additionalParams: true + } + ] + } + + async init(nodeData: INodeData): Promise { + const textSplitter = nodeData.inputs?.textSplitter as TextSplitter + const text = nodeData.inputs?.text as string + const metadata = nodeData.inputs?.metadata + + let alldocs: Document>[] = [] + + if (textSplitter) { + const docs = await textSplitter.createDocuments([text]) + alldocs.push(...docs) + } else { + alldocs.push( + new Document({ + pageContent: text + }) + ) + } + + if (metadata) { + const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata) + let finaldocs: Document>[] = [] + for (const doc of alldocs) { + const newdoc = { + ...doc, + metadata: { + ...doc.metadata, + ...parsedMetadata + } + } + finaldocs.push(newdoc) + } + return finaldocs + } + + return alldocs + } +} + +module.exports = { nodeClass: PlainText_DocumentLoaders } diff --git a/packages/components/nodes/documentloaders/PlainText/plaintext.svg b/packages/components/nodes/documentloaders/PlainText/plaintext.svg new file mode 100644 index 00000000..b9fec035 --- /dev/null +++ b/packages/components/nodes/documentloaders/PlainText/plaintext.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/packages/components/nodes/llms/AWSBedrock/AWSBedrock.ts b/packages/components/nodes/llms/AWSBedrock/AWSBedrock.ts new file mode 100644 index 00000000..68ee7ed2 --- /dev/null +++ b/packages/components/nodes/llms/AWSBedrock/AWSBedrock.ts @@ -0,0 +1,166 @@ +import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface' +import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' +import { Bedrock } from 'langchain/llms/bedrock' +import { BaseBedrockInput } from 'langchain/dist/util/bedrock' + +/** + * I had to run the following to build the component + * and get the icon copied over to the dist directory + * Flowise/packages/components > yarn build + * + * @author Michael Connor + */ +class AWSBedrock_LLMs implements INode { + label: string + name: string + version: number + type: string + icon: string + category: string + description: string + baseClasses: string[] + credential: INodeParams + inputs: INodeParams[] + + constructor() { + this.label = 'AWS Bedrock' + this.name = 'awsBedrock' + this.version = 1.2 + this.type = 'AWSBedrock' + this.icon = 'awsBedrock.png' + this.category = 'LLMs' + this.description = 'Wrapper around AWS Bedrock large language models' + this.baseClasses = [this.type, ...getBaseClasses(Bedrock)] + this.credential = { + label: 'AWS Credential', + name: 'credential', + type: 'credential', + credentialNames: ['awsApi'], + optional: true + } + this.inputs = [ + { + label: 'Region', + name: 'region', + type: 'options', + options: [ + { label: 'af-south-1', name: 'af-south-1' }, + { label: 'ap-east-1', name: 'ap-east-1' }, + { label: 'ap-northeast-1', name: 'ap-northeast-1' }, + { label: 'ap-northeast-2', name: 'ap-northeast-2' }, + { label: 'ap-northeast-3', name: 'ap-northeast-3' }, + { label: 'ap-south-1', name: 'ap-south-1' }, + { label: 'ap-south-2', name: 'ap-south-2' }, + { label: 'ap-southeast-1', name: 'ap-southeast-1' }, + { label: 'ap-southeast-2', name: 'ap-southeast-2' }, + { label: 'ap-southeast-3', name: 'ap-southeast-3' }, + { label: 'ap-southeast-4', name: 'ap-southeast-4' }, + { label: 'ap-southeast-5', name: 'ap-southeast-5' }, + { label: 'ap-southeast-6', name: 'ap-southeast-6' }, + { label: 'ca-central-1', name: 'ca-central-1' }, + { label: 'ca-west-1', name: 'ca-west-1' }, + { label: 'cn-north-1', name: 'cn-north-1' }, + { label: 'cn-northwest-1', name: 'cn-northwest-1' }, + { label: 'eu-central-1', name: 'eu-central-1' }, + { label: 'eu-central-2', name: 'eu-central-2' }, + { label: 'eu-north-1', name: 'eu-north-1' }, + { label: 'eu-south-1', name: 'eu-south-1' }, + { label: 'eu-south-2', name: 'eu-south-2' }, + { label: 'eu-west-1', name: 'eu-west-1' }, + { label: 'eu-west-2', name: 'eu-west-2' }, + { label: 'eu-west-3', name: 'eu-west-3' }, + { label: 'il-central-1', name: 'il-central-1' }, + { label: 'me-central-1', name: 'me-central-1' }, + { label: 'me-south-1', name: 'me-south-1' }, + { label: 'sa-east-1', name: 'sa-east-1' }, + { label: 'us-east-1', name: 'us-east-1' }, + { label: 'us-east-2', name: 'us-east-2' }, + { label: 'us-gov-east-1', name: 'us-gov-east-1' }, + { label: 'us-gov-west-1', name: 'us-gov-west-1' }, + { label: 'us-west-1', name: 'us-west-1' }, + { label: 'us-west-2', name: 'us-west-2' } + ], + default: 'us-east-1', + optional: false + }, + { + label: 'Model Name', + name: 'model', + type: 'options', + options: [ + { label: 'amazon.titan-tg1-large', name: 'amazon.titan-tg1-large' }, + { label: 'amazon.titan-e1t-medium', name: 'amazon.titan-e1t-medium' }, + { label: 'stability.stable-diffusion-xl', name: 'stability.stable-diffusion-xl' }, + { label: 'ai21.j2-grande-instruct', name: 'ai21.j2-grande-instruct' }, + { label: 'ai21.j2-jumbo-instruct', name: 'ai21.j2-jumbo-instruct' }, + { label: 'ai21.j2-mid', name: 'ai21.j2-mid' }, + { label: 'ai21.j2-ultra', name: 'ai21.j2-ultra' }, + { label: 'anthropic.claude-instant-v1', name: 'anthropic.claude-instant-v1' }, + { label: 'anthropic.claude-v1', name: 'anthropic.claude-v1' }, + { label: 'anthropic.claude-v2', name: 'anthropic.claude-v2' } + ], + default: 'anthropic.claude-v2', + optional: false + }, + { + label: 'Temperature', + name: 'temperature', + type: 'number', + step: 0.1, + description: 'Temperature parameter may not apply to certain model. Please check available model parameters', + optional: true, + default: 0.7, + additionalParams: false + }, + { + label: 'Max Tokens to Sample', + name: 'max_tokens_to_sample', + type: 'number', + step: 10, + description: 'Max Tokens parameter may not apply to certain model. Please check available model parameters', + optional: false, + default: 200, + additionalParams: false + } + ] + } + + async init(nodeData: INodeData, _: string, options: ICommonObject): Promise { + const iRegion = nodeData.inputs?.region as string + const iModel = nodeData.inputs?.model as string + const iTemperature = nodeData.inputs?.temperature as string + const iMax_tokens_to_sample = nodeData.inputs?.max_tokens_to_sample as string + + const obj: Partial = { + model: iModel, + region: iRegion, + temperature: parseFloat(iTemperature), + maxTokens: parseInt(iMax_tokens_to_sample, 10) + } + + /** + * Long-term credentials specified in LLM configuration are optional. + * Bedrock's credential provider falls back to the AWS SDK to fetch + * credentials from the running environment. + * When specified, we override the default provider with configured values. + * @see https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-node/README.md + */ + const credentialData = await getCredentialData(nodeData.credential ?? '', options) + if (credentialData && Object.keys(credentialData).length !== 0) { + const credentialApiKey = getCredentialParam('awsKey', credentialData, nodeData) + const credentialApiSecret = getCredentialParam('awsSecret', credentialData, nodeData) + const credentialApiSession = getCredentialParam('awsSession', credentialData, nodeData) + + obj.credentials = { + accessKeyId: credentialApiKey, + secretAccessKey: credentialApiSecret, + sessionToken: credentialApiSession + } + } + + const amazonBedrock = new Bedrock(obj) + return amazonBedrock + } +} + +module.exports = { nodeClass: AWSBedrock_LLMs } diff --git a/packages/components/nodes/llms/AWSBedrock/awsBedrock.png b/packages/components/nodes/llms/AWSBedrock/awsBedrock.png new file mode 100644 index 00000000..483bc69a Binary files /dev/null and b/packages/components/nodes/llms/AWSBedrock/awsBedrock.png differ diff --git a/packages/ui/src/views/chatflows/Configuration.js b/packages/ui/src/views/chatflows/Configuration.js index 51b8d61c..d569020b 100644 --- a/packages/ui/src/views/chatflows/Configuration.js +++ b/packages/ui/src/views/chatflows/Configuration.js @@ -136,7 +136,7 @@ const Configuration = () => { Rate Limit Setup Guide to set up Rate Limit correctly in your hosting environment.' + 'Visit Rate Limit Setup Guide to set up Rate Limit correctly in your hosting environment.' } /> diff --git a/packages/ui/src/views/chatmessage/ChatMessage.js b/packages/ui/src/views/chatmessage/ChatMessage.js index 7a15d9ff..3e967541 100644 --- a/packages/ui/src/views/chatmessage/ChatMessage.js +++ b/packages/ui/src/views/chatmessage/ChatMessage.js @@ -64,27 +64,10 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => { window.open(data, '_blank') } - const handleVectaraMetadata = (message) => { - if (message.sourceDocuments && message.sourceDocuments[0].metadata.length) - message.sourceDocuments = message.sourceDocuments.map((docs) => { - const newMetadata = docs.metadata.reduce((newMetadata, metadata) => { - newMetadata[metadata.name] = metadata.value - return newMetadata - }, {}) - return { - pageContent: docs.pageContent, - metadata: newMetadata - } - }) - return message - } - const removeDuplicateURL = (message) => { const visitedURLs = [] const newSourceDocuments = [] - message = handleVectaraMetadata(message) - message.sourceDocuments.forEach((source) => { if (isValidURL(source.metadata.source) && !visitedURLs.includes(source.metadata.source)) { visitedURLs.push(source.metadata.source) @@ -174,8 +157,6 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => { if (response.data) { let data = response.data - data = handleVectaraMetadata(data) - if (typeof data === 'object' && data.text && data.sourceDocuments) { if (!isChatFlowAvailableToStream) { setMessages((prevMessages) => [ diff --git a/packages/ui/src/views/marketplaces/index.js b/packages/ui/src/views/marketplaces/index.js index a7836161..49c692db 100644 --- a/packages/ui/src/views/marketplaces/index.js +++ b/packages/ui/src/views/marketplaces/index.js @@ -175,19 +175,8 @@ const Marketplace = () => { )} ))} - {!isChatflowsLoading && (!getAllChatflowsMarketplacesApi.data || getAllChatflowsMarketplacesApi.data.length === 0) && ( - - - WorkflowEmptySVG - -
No Marketplace Yet
-
- )} - {!isToolsLoading && (!getAllToolsMarketplacesApi.data || getAllToolsMarketplacesApi.data.length === 0) && ( + {((!isChatflowsLoading && (!getAllChatflowsMarketplacesApi.data || getAllChatflowsMarketplacesApi.data.length === 0)) || + (!isToolsLoading && (!getAllToolsMarketplacesApi.data || getAllToolsMarketplacesApi.data.length === 0))) && (