From c78ca494f57d1c6c8193d306b7b9b92942b66bfd Mon Sep 17 00:00:00 2001 From: vjsai Date: Thu, 6 Jul 2023 18:28:33 +0530 Subject: [PATCH 1/6] Added OpenAPI chain --- .../nodes/chains/ApiChain/OpenAPIChain.ts | 84 +++++++++++++++++++ .../SqlDatabaseChain/SqlDatabaseChain.ts | 2 +- packages/components/package.json | 2 +- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 packages/components/nodes/chains/ApiChain/OpenAPIChain.ts diff --git a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts new file mode 100644 index 00000000000..f0656f6dddc --- /dev/null +++ b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts @@ -0,0 +1,84 @@ +import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface' +import { APIChain, createOpenAPIChain } from 'langchain/chains' +import { CustomChainHandler, getBaseClasses } from '../../../src/utils' +import { ChatOpenAI } from 'langchain/chat_models/openai' + +class OpenApiChain_Chains implements INode { + label: string + name: string + type: string + icon: string + category: string + baseClasses: string[] + description: string + inputs: INodeParams[] + + constructor() { + this.label = 'OpenAPI Chain' + this.name = 'openApiChain' + this.type = 'openApiChain' + this.icon = 'apichain.svg' + this.category = 'Chains' + this.description = 'Chain to run queries against OpenAPI' + this.baseClasses = [this.type, ...getBaseClasses(APIChain)] + this.inputs = [ + { + label: 'ChatOpenAI Model', + name: 'model', + type: 'ChatOpenAI' + }, + { + label: 'YAML File', + name: 'yamlFile', + type: 'file', + fileType: '.yaml' + }, + { + label: 'Headers', + name: 'headers', + type: 'json', + additionalParams: true, + optional: true + } + ] + } + + async init(nodeData: INodeData): Promise { + const model = nodeData.inputs?.model as ChatOpenAI + const headers = nodeData.inputs?.headers as Record + const yamlFileBase64 = nodeData.inputs?.yamlFile as string + const splitDataURI = yamlFileBase64.split(',') + splitDataURI.pop() + const bf = Buffer.from(splitDataURI.pop() || '', 'base64') + const utf8String = bf.toString('utf-8') + const chain = await createOpenAPIChain(utf8String, { + llm: model, + headers + }) + return chain + } + + async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { + const model = nodeData.inputs?.model as ChatOpenAI + const headers = nodeData.inputs?.headers as Record + const yamlFileBase64 = nodeData.inputs?.yamlFile as string + const splitDataURI = yamlFileBase64.split(',') + splitDataURI.pop() + const bf = Buffer.from(splitDataURI.pop() || '', 'base64') + const utf8String = bf.toString('utf-8') + const chain = await createOpenAPIChain(utf8String, { + llm: model, + headers + }) + if (options.socketIO && options.socketIOClientId) { + const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2) + const res = await chain.run(input, [handler]) + return res + } else { + const res = await chain.run(input) + return res + } + } +} + +module.exports = { nodeClass: OpenApiChain_Chains } diff --git a/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts b/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts index 27a245e1aee..441ec4cd2ee 100644 --- a/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts +++ b/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts @@ -1,5 +1,5 @@ import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface' -import { SqlDatabaseChain, SqlDatabaseChainInput } from 'langchain/chains' +import { SqlDatabaseChain, SqlDatabaseChainInput } from 'langchain/chains/sql_db' import { CustomChainHandler, getBaseClasses } from '../../../src/utils' import { DataSource } from 'typeorm' import { SqlDatabase } from 'langchain/sql_db' diff --git a/packages/components/package.json b/packages/components/package.json index a5f03e10efd..3e5f540b9ea 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -35,7 +35,7 @@ "form-data": "^4.0.0", "graphql": "^16.6.0", "html-to-text": "^9.0.5", - "langchain": "^0.0.96", + "langchain": "^0.0.103", "linkifyjs": "^4.1.1", "mammoth": "^1.5.1", "moment": "^2.29.3", From 717468a018b724bd83a4de2f0953023c11698b88 Mon Sep 17 00:00:00 2001 From: vjsai Date: Fri, 7 Jul 2023 18:38:22 +0530 Subject: [PATCH 2/6] Updated appropriate icon for OpenAPIChain --- .../nodes/chains/ApiChain/OpenAPIChain.ts | 2 +- .../nodes/chains/ApiChain/openapi.png | Bin 0 -> 25114 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 packages/components/nodes/chains/ApiChain/openapi.png diff --git a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts index f0656f6dddc..b5970bb8779 100644 --- a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts +++ b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts @@ -17,7 +17,7 @@ class OpenApiChain_Chains implements INode { this.label = 'OpenAPI Chain' this.name = 'openApiChain' this.type = 'openApiChain' - this.icon = 'apichain.svg' + this.icon = 'openapi.png' this.category = 'Chains' this.description = 'Chain to run queries against OpenAPI' this.baseClasses = [this.type, ...getBaseClasses(APIChain)] diff --git a/packages/components/nodes/chains/ApiChain/openapi.png b/packages/components/nodes/chains/ApiChain/openapi.png new file mode 100644 index 0000000000000000000000000000000000000000..457c2e4050c8eef06588f25c0acc67a6059ebe01 GIT binary patch literal 25114 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 Date: Sat, 8 Jul 2023 18:01:51 +0530 Subject: [PATCH 3/6] fixed header parsing issue --- packages/components/nodes/chains/ApiChain/OpenAPIChain.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts index b5970bb8779..2e54d23759a 100644 --- a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts +++ b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts @@ -60,7 +60,7 @@ class OpenApiChain_Chains implements INode { async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { const model = nodeData.inputs?.model as ChatOpenAI - const headers = nodeData.inputs?.headers as Record + const headers = nodeData.inputs?.headers as string const yamlFileBase64 = nodeData.inputs?.yamlFile as string const splitDataURI = yamlFileBase64.split(',') splitDataURI.pop() @@ -68,7 +68,7 @@ class OpenApiChain_Chains implements INode { const utf8String = bf.toString('utf-8') const chain = await createOpenAPIChain(utf8String, { llm: model, - headers + headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {} }) if (options.socketIO && options.socketIOClientId) { const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2) From 9cda188c73124901467b58108f335e3562e09b07 Mon Sep 17 00:00:00 2001 From: vjsai Date: Sat, 8 Jul 2023 18:45:18 +0530 Subject: [PATCH 4/6] fixed the issue in init as well --- packages/components/nodes/chains/ApiChain/OpenAPIChain.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts index 2e54d23759a..a7e8441a814 100644 --- a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts +++ b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts @@ -45,7 +45,7 @@ class OpenApiChain_Chains implements INode { async init(nodeData: INodeData): Promise { const model = nodeData.inputs?.model as ChatOpenAI - const headers = nodeData.inputs?.headers as Record + const headers = nodeData.inputs?.headers as string const yamlFileBase64 = nodeData.inputs?.yamlFile as string const splitDataURI = yamlFileBase64.split(',') splitDataURI.pop() @@ -53,7 +53,7 @@ class OpenApiChain_Chains implements INode { const utf8String = bf.toString('utf-8') const chain = await createOpenAPIChain(utf8String, { llm: model, - headers + headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {} }) return chain } From 45792665df1e8971bbfa89f2fb1558c350af9bbb Mon Sep 17 00:00:00 2001 From: Henry Heng Date: Sat, 8 Jul 2023 22:34:46 +0100 Subject: [PATCH 5/6] Update OpenAPIChain.ts --- .../nodes/chains/ApiChain/OpenAPIChain.ts | 61 +++++++++++-------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts index a7e8441a814..ae1ae3c0319 100644 --- a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts +++ b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts @@ -27,11 +27,19 @@ class OpenApiChain_Chains implements INode { name: 'model', type: 'ChatOpenAI' }, + { + label: 'YAML Link', + name: 'yamlLink', + type: 'string', + placeholder: 'https://api.speak.com/openapi.yaml', + description: 'If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead' + }, { label: 'YAML File', name: 'yamlFile', type: 'file', - fileType: '.yaml' + fileType: '.yaml', + description: 'If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead' }, { label: 'Headers', @@ -44,34 +52,13 @@ class OpenApiChain_Chains implements INode { } async init(nodeData: INodeData): Promise { - const model = nodeData.inputs?.model as ChatOpenAI - const headers = nodeData.inputs?.headers as string - const yamlFileBase64 = nodeData.inputs?.yamlFile as string - const splitDataURI = yamlFileBase64.split(',') - splitDataURI.pop() - const bf = Buffer.from(splitDataURI.pop() || '', 'base64') - const utf8String = bf.toString('utf-8') - const chain = await createOpenAPIChain(utf8String, { - llm: model, - headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {} - }) - return chain + return await initChain(nodeData) } async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { - const model = nodeData.inputs?.model as ChatOpenAI - const headers = nodeData.inputs?.headers as string - const yamlFileBase64 = nodeData.inputs?.yamlFile as string - const splitDataURI = yamlFileBase64.split(',') - splitDataURI.pop() - const bf = Buffer.from(splitDataURI.pop() || '', 'base64') - const utf8String = bf.toString('utf-8') - const chain = await createOpenAPIChain(utf8String, { - llm: model, - headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {} - }) + const chain = await initChain(nodeData) if (options.socketIO && options.socketIOClientId) { - const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2) + const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId) const res = await chain.run(input, [handler]) return res } else { @@ -81,4 +68,28 @@ class OpenApiChain_Chains implements INode { } } +const initChain = async (nodeData: INodeData) => { + const model = nodeData.inputs?.model as ChatOpenAI + const headers = nodeData.inputs?.headers as string + const yamlLink = nodeData.inputs?.yamlLink as string + const yamlFileBase64 = nodeData.inputs?.yamlFile as string + + let yamlString = '' + + if (yamlLink) { + yamlString = yamlLink + } else { + const splitDataURI = yamlFileBase64.split(',') + splitDataURI.pop() + const bf = Buffer.from(splitDataURI.pop() || '', 'base64') + yamlString = bf.toString('utf-8') + } + + return await createOpenAPIChain(yamlString, { + llm: model, + headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {}, + verbose: process.env.DEBUG === 'true' ? true : false + }) +} + module.exports = { nodeClass: OpenApiChain_Chains } From 83a62011cbe2f2e552c5dd3725764d55957ef20f Mon Sep 17 00:00:00 2001 From: Henry Heng Date: Sat, 8 Jul 2023 22:35:25 +0100 Subject: [PATCH 6/6] Update package.json --- packages/components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/package.json b/packages/components/package.json index cca3e47af7e..775d6e946e2 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -35,7 +35,7 @@ "form-data": "^4.0.0", "graphql": "^16.6.0", "html-to-text": "^9.0.5", - "langchain": "^0.0.103", + "langchain": "^0.0.104", "linkifyjs": "^4.1.1", "mammoth": "^1.5.1", "moment": "^2.29.3",