Merge branch 'main' into feature/WebCrawl

# Conflicts:
#	packages/components/nodes/documentloaders/Puppeteer/Puppeteer.ts
This commit is contained in:
Henry
2023-07-08 23:47:05 +01:00
12 changed files with 156 additions and 23 deletions
@@ -0,0 +1,95 @@
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 = 'openapi.png'
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 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',
description: 'If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead'
},
{
label: 'Headers',
name: 'headers',
type: 'json',
additionalParams: true,
optional: true
}
]
}
async init(nodeData: INodeData): Promise<any> {
return await initChain(nodeData)
}
async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
const chain = await initChain(nodeData)
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
const res = await chain.run(input, [handler])
return res
} else {
const res = await chain.run(input)
return res
}
}
}
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 }
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -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'
@@ -78,9 +78,7 @@ export class HuggingFaceInference extends LLM implements HFInput {
async _call(prompt: string, options: this['ParsedCallOptions']): Promise<string> {
const { HfInference } = await HuggingFaceInference.imports()
const hf = new HfInference(this.apiKey)
if (this.endpoint) hf.endpoint(this.endpoint)
const res = await this.caller.callWithOptions({ signal: options.signal }, hf.textGeneration.bind(hf), {
model: this.model,
const obj: any = {
parameters: {
// make it behave similar to openai, returning only the generated text
return_full_text: false,
@@ -91,7 +89,13 @@ export class HuggingFaceInference extends LLM implements HFInput {
repetition_penalty: this.frequencyPenalty
},
inputs: prompt
})
}
if (this.endpoint) {
hf.endpoint(this.endpoint)
} else {
obj.model = this.model
}
const res = await this.caller.callWithOptions({ signal: options.signal }, hf.textGeneration.bind(hf), obj)
return res.generated_text
}
@@ -86,7 +86,12 @@ class Puppeteer_DocumentLoaders implements INode {
async function puppeteerLoader(url: string): Promise<any> {
try {
let docs = []
const loader = new PuppeteerWebBaseLoader(url)
const loader = new PuppeteerWebBaseLoader(url, {
launchOptions: {
args: ['--no-sandbox'],
headless: 'new'
}
})
if (textSplitter) {
docs = await loader.loadAndSplit(textSplitter)
} else {
@@ -30,12 +30,11 @@ export class HuggingFaceInferenceEmbeddings extends Embeddings implements Huggin
async _embed(texts: string[]): Promise<number[][]> {
// replace newlines, which can negatively affect performance.
const clean = texts.map((text) => text.replace(/\n/g, ' '))
return this.caller.call(() =>
this.client.featureExtraction({
model: this.model,
inputs: clean
})
) as Promise<number[][]>
const obj: any = {
inputs: clean
}
if (!this.endpoint) obj.model = this.model
return this.caller.call(() => this.client.featureExtraction(obj)) as Promise<number[][]>
}
embedQuery(document: string): Promise<number[]> {
@@ -78,9 +78,7 @@ export class HuggingFaceInference extends LLM implements HFInput {
async _call(prompt: string, options: this['ParsedCallOptions']): Promise<string> {
const { HfInference } = await HuggingFaceInference.imports()
const hf = new HfInference(this.apiKey)
if (this.endpoint) hf.endpoint(this.endpoint)
const res = await this.caller.callWithOptions({ signal: options.signal }, hf.textGeneration.bind(hf), {
model: this.model,
const obj: any = {
parameters: {
// make it behave similar to openai, returning only the generated text
return_full_text: false,
@@ -91,7 +89,13 @@ export class HuggingFaceInference extends LLM implements HFInput {
repetition_penalty: this.frequencyPenalty
},
inputs: prompt
})
}
if (this.endpoint) {
hf.endpoint(this.endpoint)
} else {
obj.model = this.model
}
const res = await this.caller.callWithOptions({ signal: options.signal }, hf.textGeneration.bind(hf), obj)
return res.generated_text
}
+1 -1
View File
@@ -36,7 +36,7 @@
"form-data": "^4.0.0",
"graphql": "^16.6.0",
"html-to-text": "^9.0.5",
"langchain": "^0.0.96",
"langchain": "^0.0.104",
"linkifyjs": "^4.1.1",
"mammoth": "^1.5.1",
"moment": "^2.29.3",
@@ -156,6 +156,16 @@
"optional": true,
"additionalParams": true,
"id": "huggingFaceInference_LLMs_0-input-frequencyPenalty-number"
},
{
"label": "Endpoint",
"name": "endpoint",
"type": "string",
"placeholder": "https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2",
"description": "Using your own inference endpoint",
"optional": true,
"additionalParams": true,
"id": "huggingFaceInference_LLMs_0-input-endpoint-string"
}
],
"inputAnchors": [],
+12 -6
View File
@@ -680,10 +680,16 @@ export const isFlowValidForStream = (reactFlowNodes: IReactFlowNode[], endingNod
}
}
return (
isChatOrLLMsExist &&
(endingNodeData.category === 'Chains' || endingNodeData.name === 'openAIFunctionAgent') &&
!isVectorStoreFaiss(endingNodeData) &&
process.env.EXECUTION_MODE !== 'child'
)
let isValidChainOrAgent = false
if (endingNodeData.category === 'Chains') {
// Chains that are not available to stream
const blacklistChains = ['openApiChain']
isValidChainOrAgent = !blacklistChains.includes(endingNodeData.name)
} else if (endingNodeData.category === 'Agents') {
// Agent that are available to stream
const whitelistAgents = ['openAIFunctionAgent']
isValidChainOrAgent = whitelistAgents.includes(endingNodeData.name)
}
return isChatOrLLMsExist && isValidChainOrAgent && !isVectorStoreFaiss(endingNodeData) && process.env.EXECUTION_MODE !== 'child'
}