mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-30 11:00:27 +03:00
Chore/refractor (#4454)
* markdown files and env examples cleanup * components update * update jsonlines description * server refractor * update telemetry * add execute custom node * add ui refractor * add username and password authenticate * correctly retrieve past images in agentflowv2 * disable e2e temporarily * add existing username and password authenticate * update migration to default workspace * update todo * blob storage migrating * throw error on agent tool call error * add missing execution import * add referral * chore: add error message when importData is undefined * migrate api keys to db * fix: data too long for column executionData * migrate api keys from json to db at init * add info on account setup * update docstore missing fields --------- Co-authored-by: chungyau97 <chungyau97@gmail.com>
This commit is contained in:
@@ -427,7 +427,8 @@ class Agent_Agentflow implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).findBy(searchOptions)
|
||||
for (const store of stores) {
|
||||
if (store.status === 'UPSERTED') {
|
||||
const obj = {
|
||||
|
||||
@@ -152,7 +152,7 @@ class CustomFunction_Agentflow implements INode {
|
||||
newState = updateFlowState(state, _customFunctionUpdateState)
|
||||
}
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
|
||||
@@ -127,7 +127,8 @@ class ExecuteFlow_Agentflow implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const chatflows = await appDataSource.getRepository(databaseEntities['ChatFlow']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const chatflows = await appDataSource.getRepository(databaseEntities['ChatFlow']).findBy(searchOptions)
|
||||
|
||||
for (let i = 0; i < chatflows.length; i += 1) {
|
||||
let cfType = 'Chatflow'
|
||||
|
||||
@@ -119,7 +119,8 @@ class Retriever_Agentflow implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).findBy(searchOptions)
|
||||
for (const store of stores) {
|
||||
if (store.status === 'UPSERTED') {
|
||||
const obj = {
|
||||
|
||||
@@ -18,7 +18,7 @@ export const addImagesToMessages = async (
|
||||
for (const upload of imageUploads) {
|
||||
let bf = upload.data
|
||||
if (upload.type == 'stored-file') {
|
||||
const contents = await getFileFromStorage(upload.name, options.chatflowid, options.chatId)
|
||||
const contents = await getFileFromStorage(upload.name, options.orgId, options.chatflowid, options.chatId)
|
||||
// as the image is stored in the server, read the file and convert it to base64
|
||||
bf = 'data:' + upload.mime + ';base64,' + contents.toString('base64')
|
||||
|
||||
@@ -90,7 +90,7 @@ export const processMessagesWithImages = async (
|
||||
hasImageReferences = true
|
||||
try {
|
||||
// Get file contents from storage
|
||||
const contents = await getFileFromStorage(item.name, options.chatflowid, options.chatId)
|
||||
const contents = await getFileFromStorage(item.name, options.orgId, options.chatflowid, options.chatId)
|
||||
|
||||
// Create base64 data URL
|
||||
const base64Data = 'data:' + item.mime + ';base64,' + contents.toString('base64')
|
||||
@@ -319,7 +319,7 @@ export const getPastChatHistoryImageMessages = async (
|
||||
const imageContents: MessageContentImageUrl[] = []
|
||||
for (const upload of uploads) {
|
||||
if (upload.type === 'stored-file' && upload.mime.startsWith('image/')) {
|
||||
const fileData = await getFileFromStorage(upload.name, options.chatflowid, options.chatId)
|
||||
const fileData = await getFileFromStorage(upload.name, options.orgId, options.chatflowid, options.chatId)
|
||||
// as the image is stored in the server, read the file and convert it to base64
|
||||
const bf = 'data:' + upload.mime + ';base64,' + fileData.toString('base64')
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class Airtable_Agents implements INode {
|
||||
|
||||
let base64String = Buffer.from(JSON.stringify(airtableData)).toString('base64')
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
const pyodide = await LoadPyodide()
|
||||
@@ -163,7 +163,7 @@ json.dumps(my_dict)`
|
||||
const chain = new LLMChain({
|
||||
llm: model,
|
||||
prompt: PromptTemplate.fromTemplate(systemPrompt),
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
const inputs = {
|
||||
dict: dataframeColDict,
|
||||
@@ -192,7 +192,7 @@ json.dumps(my_dict)`
|
||||
const chain = new LLMChain({
|
||||
llm: model,
|
||||
prompt: PromptTemplate.fromTemplate(finalSystemPrompt),
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
const inputs = {
|
||||
question: input,
|
||||
|
||||
@@ -97,7 +97,7 @@ class CSV_Agents implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||
const chatId = options.chatId
|
||||
@@ -114,11 +114,12 @@ class CSV_Agents implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
base64String += fileData.toString('base64')
|
||||
}
|
||||
} else {
|
||||
@@ -170,7 +171,7 @@ json.dumps(my_dict)`
|
||||
const chain = new LLMChain({
|
||||
llm: model,
|
||||
prompt: PromptTemplate.fromTemplate(systemPrompt),
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
const inputs = {
|
||||
dict: dataframeColDict,
|
||||
@@ -201,7 +202,7 @@ json.dumps(my_dict)`
|
||||
prompt: PromptTemplate.fromTemplate(
|
||||
systemMessagePrompt ? `${systemMessagePrompt}\n${finalSystemPrompt}` : finalSystemPrompt
|
||||
),
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
const inputs = {
|
||||
question: input,
|
||||
|
||||
@@ -132,7 +132,7 @@ class ConversationalAgent_Agents implements INode {
|
||||
}
|
||||
const executor = await prepareAgent(nodeData, options, { sessionId: this.sessionId, chatId: options.chatId, input })
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
let res: ChainValues = {}
|
||||
|
||||
+2
-2
@@ -130,7 +130,7 @@ class ConversationalRetrievalToolAgent_Agents implements INode {
|
||||
|
||||
const executor = await prepareAgent(nodeData, options, { sessionId: this.sessionId, chatId: options.chatId, input })
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
let res: ChainValues = {}
|
||||
@@ -288,7 +288,7 @@ const prepareAgent = async (
|
||||
sessionId: flowObj?.sessionId,
|
||||
chatId: flowObj?.chatId,
|
||||
input: flowObj?.input,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
maxIterations: maxIterations ? parseFloat(maxIterations) : undefined
|
||||
})
|
||||
|
||||
|
||||
+6
-2
@@ -2,6 +2,7 @@ import { flatten } from 'lodash'
|
||||
import { MessageContentTextDetail, ChatMessage, AnthropicAgent, Anthropic } from 'llamaindex'
|
||||
import { getBaseClasses } from '../../../../src/utils'
|
||||
import { FlowiseMemory, ICommonObject, IMessage, INode, INodeData, INodeParams, IUsedTool } from '../../../../src/Interface'
|
||||
import { EvaluationRunTracerLlama } from '../../../../evaluation/EvaluationRunTracerLlama'
|
||||
|
||||
class AnthropicAgent_LlamaIndex_Agents implements INode {
|
||||
label: string
|
||||
@@ -96,13 +97,16 @@ class AnthropicAgent_LlamaIndex_Agents implements INode {
|
||||
tools,
|
||||
llm: model,
|
||||
chatHistory: chatHistory,
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
|
||||
// these are needed for evaluation runs
|
||||
await EvaluationRunTracerLlama.injectEvaluationMetadata(nodeData, options, agent)
|
||||
|
||||
let text = ''
|
||||
const usedTools: IUsedTool[] = []
|
||||
|
||||
const response = await agent.chat({ message: input, chatHistory, verbose: process.env.DEBUG === 'true' })
|
||||
const response = await agent.chat({ message: input, chatHistory, verbose: process.env.DEBUG === 'true' ? true : false })
|
||||
|
||||
if (response.sources.length) {
|
||||
for (const sourceTool of response.sources) {
|
||||
|
||||
+7
-4
@@ -1,6 +1,7 @@
|
||||
import { flatten } from 'lodash'
|
||||
import { ChatMessage, OpenAI, OpenAIAgent } from 'llamaindex'
|
||||
import { getBaseClasses } from '../../../../src/utils'
|
||||
import { EvaluationRunTracerLlama } from '../../../../evaluation/EvaluationRunTracerLlama'
|
||||
import {
|
||||
FlowiseMemory,
|
||||
ICommonObject,
|
||||
@@ -107,9 +108,12 @@ class OpenAIFunctionAgent_LlamaIndex_Agents implements INode {
|
||||
tools,
|
||||
llm: model,
|
||||
chatHistory: chatHistory,
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
|
||||
// these are needed for evaluation runs
|
||||
await EvaluationRunTracerLlama.injectEvaluationMetadata(nodeData, options, agent)
|
||||
|
||||
let text = ''
|
||||
let isStreamingStarted = false
|
||||
const usedTools: IUsedTool[] = []
|
||||
@@ -119,10 +123,9 @@ class OpenAIFunctionAgent_LlamaIndex_Agents implements INode {
|
||||
message: input,
|
||||
chatHistory,
|
||||
stream: true,
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
for await (const chunk of stream) {
|
||||
//console.log('chunk', chunk)
|
||||
text += chunk.response.delta
|
||||
if (!isStreamingStarted) {
|
||||
isStreamingStarted = true
|
||||
@@ -147,7 +150,7 @@ class OpenAIFunctionAgent_LlamaIndex_Agents implements INode {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const response = await agent.chat({ message: input, chatHistory, verbose: process.env.DEBUG === 'true' })
|
||||
const response = await agent.chat({ message: input, chatHistory, verbose: process.env.DEBUG === 'true' ? true : false })
|
||||
if (response.sources.length) {
|
||||
for (const sourceTool of response.sources) {
|
||||
usedTools.push({
|
||||
|
||||
@@ -107,7 +107,11 @@ class OpenAIAssistant_Agents implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const assistants = await appDataSource.getRepository(databaseEntities['Assistant']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const assistants = await appDataSource.getRepository(databaseEntities['Assistant']).findBy({
|
||||
...searchOptions,
|
||||
type: 'OPENAI'
|
||||
})
|
||||
|
||||
for (let i = 0; i < assistants.length; i += 1) {
|
||||
const assistantDetails = JSON.parse(assistants[i].details)
|
||||
@@ -130,13 +134,14 @@ class OpenAIAssistant_Agents implements INode {
|
||||
const selectedAssistantId = nodeData.inputs?.selectedAssistant as string
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const orgId = options.orgId
|
||||
|
||||
const assistant = await appDataSource.getRepository(databaseEntities['Assistant']).findOneBy({
|
||||
id: selectedAssistantId
|
||||
})
|
||||
|
||||
if (!assistant) {
|
||||
options.logger.error(`Assistant ${selectedAssistantId} not found`)
|
||||
options.logger.error(`[${orgId}]: Assistant ${selectedAssistantId} not found`)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -149,7 +154,7 @@ class OpenAIAssistant_Agents implements INode {
|
||||
chatId
|
||||
})
|
||||
if (!chatmsg) {
|
||||
options.logger.error(`Chat Message with Chat Id: ${chatId} not found`)
|
||||
options.logger.error(`[${orgId}]: Chat Message with Chat Id: ${chatId} not found`)
|
||||
return
|
||||
}
|
||||
sessionId = chatmsg.sessionId
|
||||
@@ -160,21 +165,21 @@ class OpenAIAssistant_Agents implements INode {
|
||||
const credentialData = await getCredentialData(assistant.credential ?? '', options)
|
||||
const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData)
|
||||
if (!openAIApiKey) {
|
||||
options.logger.error(`OpenAI ApiKey not found`)
|
||||
options.logger.error(`[${orgId}]: OpenAI ApiKey not found`)
|
||||
return
|
||||
}
|
||||
|
||||
const openai = new OpenAI({ apiKey: openAIApiKey })
|
||||
options.logger.info(`Clearing OpenAI Thread ${sessionId}`)
|
||||
options.logger.info(`[${orgId}]: Clearing OpenAI Thread ${sessionId}`)
|
||||
try {
|
||||
if (sessionId && sessionId.startsWith('thread_')) {
|
||||
await openai.beta.threads.del(sessionId)
|
||||
options.logger.info(`Successfully cleared OpenAI Thread ${sessionId}`)
|
||||
options.logger.info(`[${orgId}]: Successfully cleared OpenAI Thread ${sessionId}`)
|
||||
} else {
|
||||
options.logger.error(`Error clearing OpenAI Thread ${sessionId}`)
|
||||
options.logger.error(`[${orgId}]: Error clearing OpenAI Thread ${sessionId}`)
|
||||
}
|
||||
} catch (e) {
|
||||
options.logger.error(`Error clearing OpenAI Thread ${sessionId}`)
|
||||
options.logger.error(`[${orgId}]: Error clearing OpenAI Thread ${sessionId}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +195,17 @@ class OpenAIAssistant_Agents implements INode {
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||
const chatId = options.chatId
|
||||
const checkStorage = options.checkStorage
|
||||
? (options.checkStorage as (orgId: string, subscriptionId: string, usageCacheManager: any) => Promise<void>)
|
||||
: undefined
|
||||
const updateStorageUsage = options.updateStorageUsage
|
||||
? (options.updateStorageUsage as (
|
||||
orgId: string,
|
||||
workspaceId: string,
|
||||
totalSize: number,
|
||||
usageCacheManager: any
|
||||
) => Promise<void>)
|
||||
: undefined
|
||||
|
||||
if (moderations && moderations.length > 0) {
|
||||
try {
|
||||
@@ -380,17 +396,30 @@ class OpenAIAssistant_Agents implements INode {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const fileName = cited_file.filename.split(/[\/\\]/).pop() ?? cited_file.filename
|
||||
if (!disableFileDownload) {
|
||||
filePath = await downloadFile(
|
||||
if (checkStorage)
|
||||
await checkStorage(options.orgId, options.subscriptionId, options.usageCacheManager)
|
||||
|
||||
const { path, totalSize } = await downloadFile(
|
||||
openAIApiKey,
|
||||
cited_file,
|
||||
fileName,
|
||||
options.orgId,
|
||||
options.chatflowid,
|
||||
options.chatId
|
||||
)
|
||||
filePath = path
|
||||
fileAnnotations.push({
|
||||
filePath,
|
||||
fileName
|
||||
})
|
||||
|
||||
if (updateStorageUsage)
|
||||
await updateStorageUsage(
|
||||
options.orgId,
|
||||
options.workspaceId,
|
||||
totalSize,
|
||||
options.usageCacheManager
|
||||
)
|
||||
}
|
||||
} else {
|
||||
const file_path = (annotation as OpenAI.Beta.Threads.Messages.FilePathAnnotation).file_path
|
||||
@@ -399,17 +428,30 @@ class OpenAIAssistant_Agents implements INode {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const fileName = cited_file.filename.split(/[\/\\]/).pop() ?? cited_file.filename
|
||||
if (!disableFileDownload) {
|
||||
filePath = await downloadFile(
|
||||
if (checkStorage)
|
||||
await checkStorage(options.orgId, options.subscriptionId, options.usageCacheManager)
|
||||
|
||||
const { path, totalSize } = await downloadFile(
|
||||
openAIApiKey,
|
||||
cited_file,
|
||||
fileName,
|
||||
options.orgId,
|
||||
options.chatflowid,
|
||||
options.chatId
|
||||
)
|
||||
filePath = path
|
||||
fileAnnotations.push({
|
||||
filePath,
|
||||
fileName
|
||||
})
|
||||
|
||||
if (updateStorageUsage)
|
||||
await updateStorageUsage(
|
||||
options.orgId,
|
||||
options.workspaceId,
|
||||
totalSize,
|
||||
options.usageCacheManager
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,15 +509,21 @@ class OpenAIAssistant_Agents implements INode {
|
||||
const fileId = chunk.image_file.file_id
|
||||
const fileObj = await openai.files.retrieve(fileId)
|
||||
|
||||
const filePath = await downloadImg(
|
||||
if (checkStorage) await checkStorage(options.orgId, options.subscriptionId, options.usageCacheManager)
|
||||
|
||||
const { filePath, totalSize } = await downloadImg(
|
||||
openai,
|
||||
fileId,
|
||||
`${fileObj.filename}.png`,
|
||||
options.orgId,
|
||||
options.chatflowid,
|
||||
options.chatId
|
||||
)
|
||||
artifacts.push({ type: 'png', data: filePath })
|
||||
|
||||
if (updateStorageUsage)
|
||||
await updateStorageUsage(options.orgId, options.workspaceId, totalSize, options.usageCacheManager)
|
||||
|
||||
if (!isStreamingStarted) {
|
||||
isStreamingStarted = true
|
||||
if (sseStreamer) {
|
||||
@@ -776,7 +824,21 @@ class OpenAIAssistant_Agents implements INode {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const fileName = cited_file.filename.split(/[\/\\]/).pop() ?? cited_file.filename
|
||||
if (!disableFileDownload) {
|
||||
filePath = await downloadFile(openAIApiKey, cited_file, fileName, options.chatflowid, options.chatId)
|
||||
if (checkStorage) await checkStorage(options.orgId, options.subscriptionId, options.usageCacheManager)
|
||||
|
||||
const { path, totalSize } = await downloadFile(
|
||||
openAIApiKey,
|
||||
cited_file,
|
||||
fileName,
|
||||
options.orgId,
|
||||
options.chatflowid,
|
||||
options.chatId
|
||||
)
|
||||
filePath = path
|
||||
|
||||
if (updateStorageUsage)
|
||||
await updateStorageUsage(options.orgId, options.workspaceId, totalSize, options.usageCacheManager)
|
||||
|
||||
fileAnnotations.push({
|
||||
filePath,
|
||||
fileName
|
||||
@@ -789,13 +851,27 @@ class OpenAIAssistant_Agents implements INode {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const fileName = cited_file.filename.split(/[\/\\]/).pop() ?? cited_file.filename
|
||||
if (!disableFileDownload) {
|
||||
filePath = await downloadFile(
|
||||
if (checkStorage)
|
||||
await checkStorage(options.orgId, options.subscriptionId, options.usageCacheManager)
|
||||
|
||||
const { path, totalSize } = await downloadFile(
|
||||
openAIApiKey,
|
||||
cited_file,
|
||||
fileName,
|
||||
options.orgId,
|
||||
options.chatflowid,
|
||||
options.chatId
|
||||
)
|
||||
filePath = path
|
||||
|
||||
if (updateStorageUsage)
|
||||
await updateStorageUsage(
|
||||
options.orgId,
|
||||
options.workspaceId,
|
||||
totalSize,
|
||||
options.usageCacheManager
|
||||
)
|
||||
|
||||
fileAnnotations.push({
|
||||
filePath,
|
||||
fileName
|
||||
@@ -822,7 +898,20 @@ class OpenAIAssistant_Agents implements INode {
|
||||
const fileId = content.image_file.file_id
|
||||
const fileObj = await openai.files.retrieve(fileId)
|
||||
|
||||
const filePath = await downloadImg(openai, fileId, `${fileObj.filename}.png`, options.chatflowid, options.chatId)
|
||||
if (checkStorage) await checkStorage(options.orgId, options.subscriptionId, options.usageCacheManager)
|
||||
|
||||
const { filePath, totalSize } = await downloadImg(
|
||||
openai,
|
||||
fileId,
|
||||
`${fileObj.filename}.png`,
|
||||
options.orgId,
|
||||
options.chatflowid,
|
||||
options.chatId
|
||||
)
|
||||
|
||||
if (updateStorageUsage)
|
||||
await updateStorageUsage(options.orgId, options.workspaceId, totalSize, options.usageCacheManager)
|
||||
|
||||
artifacts.push({ type: 'png', data: filePath })
|
||||
}
|
||||
}
|
||||
@@ -847,7 +936,13 @@ class OpenAIAssistant_Agents implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
const downloadImg = async (openai: OpenAI, fileId: string, fileName: string, ...paths: string[]) => {
|
||||
const downloadImg = async (
|
||||
openai: OpenAI,
|
||||
fileId: string,
|
||||
fileName: string,
|
||||
orgId: string,
|
||||
...paths: string[]
|
||||
): Promise<{ filePath: string; totalSize: number }> => {
|
||||
const response = await openai.files.content(fileId)
|
||||
|
||||
// Extract the binary data from the Response object
|
||||
@@ -857,12 +952,18 @@ const downloadImg = async (openai: OpenAI, fileId: string, fileName: string, ...
|
||||
const image_data_buffer = Buffer.from(image_data)
|
||||
const mime = 'image/png'
|
||||
|
||||
const res = await addSingleFileToStorage(mime, image_data_buffer, fileName, ...paths)
|
||||
const { path, totalSize } = await addSingleFileToStorage(mime, image_data_buffer, fileName, orgId, ...paths)
|
||||
|
||||
return res
|
||||
return { filePath: path, totalSize }
|
||||
}
|
||||
|
||||
const downloadFile = async (openAIApiKey: string, fileObj: any, fileName: string, ...paths: string[]) => {
|
||||
const downloadFile = async (
|
||||
openAIApiKey: string,
|
||||
fileObj: any,
|
||||
fileName: string,
|
||||
orgId: string,
|
||||
...paths: string[]
|
||||
): Promise<{ path: string; totalSize: number }> => {
|
||||
try {
|
||||
const response = await fetch(`https://api.openai.com/v1/files/${fileObj.id}/content`, {
|
||||
method: 'GET',
|
||||
@@ -880,10 +981,12 @@ const downloadFile = async (openAIApiKey: string, fileObj: any, fileName: string
|
||||
const data_buffer = Buffer.from(data)
|
||||
const mime = 'application/octet-stream'
|
||||
|
||||
return await addSingleFileToStorage(mime, data_buffer, fileName, ...paths)
|
||||
const { path, totalSize } = await addSingleFileToStorage(mime, data_buffer, fileName, orgId, ...paths)
|
||||
|
||||
return { path, totalSize }
|
||||
} catch (error) {
|
||||
console.error('Error downloading or writing the file:', error)
|
||||
return ''
|
||||
return { path: '', totalSize: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class ReActAgentLLM_Agents implements INode {
|
||||
const executor = new AgentExecutor({
|
||||
agent,
|
||||
tools,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
maxIterations: maxIterations ? parseFloat(maxIterations) : undefined
|
||||
})
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ class ToolAgent_Agents implements INode {
|
||||
|
||||
const executor = await prepareAgent(nodeData, options, { sessionId: this.sessionId, chatId: options.chatId, input })
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
// Add custom streaming handler if detailed streaming is enabled
|
||||
@@ -370,7 +370,7 @@ const prepareAgent = async (
|
||||
sessionId: flowObj?.sessionId,
|
||||
chatId: flowObj?.chatId,
|
||||
input: flowObj?.input,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
maxIterations: maxIterations ? parseFloat(maxIterations) : undefined
|
||||
})
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ class XMLAgent_Agents implements INode {
|
||||
}
|
||||
const executor = await prepareAgent(nodeData, options, { sessionId: this.sessionId, chatId: options.chatId, input })
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
let res: ChainValues = {}
|
||||
@@ -278,7 +278,7 @@ const prepareAgent = async (
|
||||
chatId: flowObj?.chatId,
|
||||
input: flowObj?.input,
|
||||
isXML: true,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
maxIterations: maxIterations ? parseFloat(maxIterations) : undefined
|
||||
})
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ class GETApiChain_Chains implements INode {
|
||||
const ansPrompt = nodeData.inputs?.ansPrompt as string
|
||||
|
||||
const chain = await getAPIChain(apiDocs, model, headers, urlPrompt, ansPrompt)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||
@@ -129,7 +129,7 @@ const getAPIChain = async (documents: string, llm: BaseLanguageModel, headers: s
|
||||
const chain = APIChain.fromLLMAndAPIDocs(llm, documents, {
|
||||
apiUrlPrompt,
|
||||
apiResponsePrompt,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {}
|
||||
})
|
||||
return chain
|
||||
|
||||
@@ -71,7 +71,7 @@ class OpenApiChain_Chains implements INode {
|
||||
|
||||
async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string | object> {
|
||||
const chain = await initChain(nodeData, options)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
const moderations = nodeData.inputs?.inputModeration as Moderation[]
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
@@ -114,8 +114,9 @@ const initChain = async (nodeData: INodeData, options: ICommonObject) => {
|
||||
} else {
|
||||
if (yamlFileBase64.startsWith('FILE-STORAGE::')) {
|
||||
const file = yamlFileBase64.replace('FILE-STORAGE::', '')
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
yamlString = fileData.toString()
|
||||
} else {
|
||||
const splitDataURI = yamlFileBase64.split(',')
|
||||
@@ -128,7 +129,7 @@ const initChain = async (nodeData: INodeData, options: ICommonObject) => {
|
||||
return await createOpenAPIChain(yamlString, {
|
||||
llm: model,
|
||||
headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {},
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class POSTApiChain_Chains implements INode {
|
||||
const ansPrompt = nodeData.inputs?.ansPrompt as string
|
||||
|
||||
const chain = await getAPIChain(apiDocs, model, headers, urlPrompt, ansPrompt)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
@@ -119,7 +119,7 @@ const getAPIChain = async (documents: string, llm: BaseLanguageModel, headers: s
|
||||
const chain = APIChain.fromLLMAndAPIDocs(llm, documents, {
|
||||
apiUrlPrompt,
|
||||
apiResponsePrompt,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {}
|
||||
})
|
||||
return chain
|
||||
|
||||
@@ -132,7 +132,7 @@ class ConversationChain_Chains implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const additionalCallback = await additionalCallbacks(nodeData, options)
|
||||
|
||||
let res = ''
|
||||
|
||||
+8
-3
@@ -185,6 +185,7 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||
const chatId = options.chatId
|
||||
const orgId = options.orgId
|
||||
|
||||
let customResponsePrompt = responsePrompt
|
||||
// If the deprecated systemMessagePrompt is still exists
|
||||
@@ -200,7 +201,8 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
||||
memoryKey: 'chat_history',
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
})
|
||||
}
|
||||
|
||||
@@ -220,7 +222,7 @@ class ConversationalRetrievalQAChain_Chains implements INode {
|
||||
|
||||
const history = ((await memory.getChatMessages(this.sessionId, false, prependMessages)) as IMessage[]) ?? []
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const additionalCallback = await additionalCallbacks(nodeData, options)
|
||||
|
||||
let callbacks = [loggerHandler, ...additionalCallback]
|
||||
@@ -407,18 +409,21 @@ interface BufferMemoryExtendedInput {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class BufferMemory extends FlowiseMemory implements MemoryMethods {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
|
||||
constructor(fields: BufferMemoryInput & BufferMemoryExtendedInput) {
|
||||
super(fields)
|
||||
this.appDataSource = fields.appDataSource
|
||||
this.databaseEntities = fields.databaseEntities
|
||||
this.chatflowid = fields.chatflowid
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async getChatMessages(
|
||||
@@ -443,7 +448,7 @@ class BufferMemory extends FlowiseMemory implements MemoryMethods {
|
||||
}
|
||||
|
||||
if (returnBaseMessages) {
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.orgId)
|
||||
}
|
||||
|
||||
let returnIMessages: IMessage[] = []
|
||||
|
||||
@@ -215,7 +215,7 @@ class GraphCypherQA_Chain implements INode {
|
||||
query: input
|
||||
}
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbackHandlers = await additionalCallbacks(nodeData, options)
|
||||
let callbacks = [loggerHandler, ...callbackHandlers]
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ const runPrediction = async (
|
||||
nodeData: INodeData,
|
||||
disableStreaming?: boolean
|
||||
) => {
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
const moderations = nodeData.inputs?.inputModeration as Moderation[]
|
||||
|
||||
@@ -66,7 +66,7 @@ class MultiPromptChain_Chains implements INode {
|
||||
promptNames,
|
||||
promptDescriptions,
|
||||
promptTemplates,
|
||||
llmChainOpts: { verbose: process.env.DEBUG === 'true' }
|
||||
llmChainOpts: { verbose: process.env.DEBUG === 'true' ? true : false }
|
||||
})
|
||||
|
||||
return chain
|
||||
@@ -95,7 +95,7 @@ class MultiPromptChain_Chains implements INode {
|
||||
}
|
||||
const obj = { input }
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
if (shouldStreamResponse) {
|
||||
|
||||
@@ -74,7 +74,7 @@ class MultiRetrievalQAChain_Chains implements INode {
|
||||
retrieverNames,
|
||||
retrieverDescriptions,
|
||||
retrievers,
|
||||
retrievalQAChainOpts: { verbose: process.env.DEBUG === 'true', returnSourceDocuments }
|
||||
retrievalQAChainOpts: { verbose: process.env.DEBUG === 'true' ? true : false, returnSourceDocuments }
|
||||
})
|
||||
return chain
|
||||
}
|
||||
@@ -101,7 +101,7 @@ class MultiRetrievalQAChain_Chains implements INode {
|
||||
}
|
||||
}
|
||||
const obj = { input }
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
if (shouldStreamResponse) {
|
||||
|
||||
@@ -53,7 +53,7 @@ class RetrievalQAChain_Chains implements INode {
|
||||
const model = nodeData.inputs?.model as BaseLanguageModel
|
||||
const vectorStoreRetriever = nodeData.inputs?.vectorStoreRetriever as BaseRetriever
|
||||
|
||||
const chain = RetrievalQAChain.fromLLM(model, vectorStoreRetriever, { verbose: process.env.DEBUG === 'true' })
|
||||
const chain = RetrievalQAChain.fromLLM(model, vectorStoreRetriever, { verbose: process.env.DEBUG === 'true' ? true : false })
|
||||
return chain
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class RetrievalQAChain_Chains implements INode {
|
||||
const obj = {
|
||||
query: input
|
||||
}
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
if (shouldStreamResponse) {
|
||||
|
||||
@@ -194,7 +194,7 @@ class SqlDatabaseChain_Chains implements INode {
|
||||
topK,
|
||||
customPrompt
|
||||
)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
if (shouldStreamResponse) {
|
||||
@@ -241,7 +241,7 @@ const getSQLDBChain = async (
|
||||
const obj: SqlDatabaseChainInput = {
|
||||
llm,
|
||||
database: db,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
topK: topK
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class VectorDBQAChain_Chains implements INode {
|
||||
|
||||
const chain = VectorDBQAChain.fromLLM(model, vectorStore, {
|
||||
k: (vectorStore as any)?.k ?? 4,
|
||||
verbose: process.env.DEBUG === 'true'
|
||||
verbose: process.env.DEBUG === 'true' ? true : false
|
||||
})
|
||||
return chain
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class VectorDBQAChain_Chains implements INode {
|
||||
query: input
|
||||
}
|
||||
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger)
|
||||
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
||||
const callbacks = await additionalCallbacks(nodeData, options)
|
||||
|
||||
if (shouldStreamResponse) {
|
||||
|
||||
@@ -4,13 +4,13 @@ Azure OpenAI Chat Model integration for Flowise
|
||||
|
||||
## 🌱 Env Variables
|
||||
|
||||
| Variable | Description | Type | Default |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||
| AZURE_OPENAI_API_KEY | Default `credential.azureOpenAIApiKey` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_INSTANCE_NAME | Default `credential.azureOpenAIApiInstanceName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_DEPLOYMENT_NAME | Default `credential.azureOpenAIApiDeploymentName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_VERSION | Default `credential.azureOpenAIApiVersion` for Azure OpenAI Model | String | |
|
||||
| Variable | Description | Type | Default |
|
||||
| -------------------------------- | ------------------------------------------------------------------------ | ------ | ------- |
|
||||
| AZURE_OPENAI_API_KEY | Default `credential.azureOpenAIApiKey` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_INSTANCE_NAME | Default `credential.azureOpenAIApiInstanceName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_DEPLOYMENT_NAME | Default `credential.azureOpenAIApiDeploymentName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_VERSION | Default `credential.azureOpenAIApiVersion` for Azure OpenAI Model | String | |
|
||||
|
||||
## License
|
||||
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
|
||||
@@ -216,6 +216,10 @@ class GoogleGenerativeAI_ChatModels implements INode {
|
||||
streaming: streaming ?? true
|
||||
}
|
||||
|
||||
// this extra metadata is needed, as langchain does not show the model name in the callbacks.
|
||||
obj.metadata = {
|
||||
fw_model_name: customModelName || modelName
|
||||
}
|
||||
if (maxOutputTokens) obj.maxOutputTokens = parseInt(maxOutputTokens, 10)
|
||||
if (topP) obj.topP = parseFloat(topP)
|
||||
if (topK) obj.topK = parseFloat(topK)
|
||||
|
||||
@@ -161,12 +161,13 @@ class ChatIBMWatsonx_ChatModels implements INode {
|
||||
watsonxAIBearerToken
|
||||
}
|
||||
|
||||
const obj: ChatWatsonxInput & WatsonxAuth = {
|
||||
const obj = {
|
||||
...auth,
|
||||
streaming: streaming ?? true,
|
||||
model: modelName,
|
||||
temperature: temperature ? parseFloat(temperature) : undefined
|
||||
}
|
||||
} as ChatWatsonxInput & WatsonxAuth
|
||||
|
||||
if (cache) obj.cache = cache
|
||||
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
|
||||
if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
|
||||
|
||||
@@ -123,6 +123,7 @@ class Cheerio_DocumentLoaders implements INode {
|
||||
const selectedLinks = nodeData.inputs?.selectedLinks as string[]
|
||||
let limit = parseInt(nodeData.inputs?.limit as string)
|
||||
const output = nodeData.outputs?.output as string
|
||||
const orgId = options.orgId
|
||||
|
||||
const _omitMetadataKeys = nodeData.inputs?.omitMetadataKeys as string
|
||||
|
||||
@@ -149,7 +150,8 @@ class Cheerio_DocumentLoaders implements INode {
|
||||
try {
|
||||
let docs: IDocument[] = []
|
||||
if (url.endsWith('.pdf')) {
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`CheerioWebBaseLoader does not support PDF files: ${url}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`[${orgId}]: CheerioWebBaseLoader does not support PDF files: ${url}`)
|
||||
return docs
|
||||
}
|
||||
const loader = new CheerioWebBaseLoader(url, params)
|
||||
@@ -161,7 +163,8 @@ class Cheerio_DocumentLoaders implements INode {
|
||||
}
|
||||
return docs
|
||||
} catch (err) {
|
||||
if (process.env.DEBUG === 'true') options.logger.error(`error in CheerioWebBaseLoader: ${err.message}, on page: ${url}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.error(`[${orgId}]: Error in CheerioWebBaseLoader: ${err.message}, on page: ${url}`)
|
||||
return []
|
||||
}
|
||||
}
|
||||
@@ -169,7 +172,7 @@ class Cheerio_DocumentLoaders implements INode {
|
||||
let docs: IDocument[] = []
|
||||
|
||||
if (relativeLinksMethod) {
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`Start ${relativeLinksMethod}`)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`[${orgId}]: Start CheerioWebBaseLoader ${relativeLinksMethod}`)
|
||||
// if limit is 0 we don't want it to default to 10 so we check explicitly for null or undefined
|
||||
// so when limit is 0 we can fetch all the links
|
||||
if (limit === null || limit === undefined) limit = 10
|
||||
@@ -180,15 +183,18 @@ class Cheerio_DocumentLoaders implements INode {
|
||||
: relativeLinksMethod === 'webCrawl'
|
||||
? await webCrawl(url, limit)
|
||||
: await xmlScrape(url, limit)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`[${orgId}]: CheerioWebBaseLoader pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
|
||||
if (!pages || pages.length === 0) throw new Error('No relative links found')
|
||||
for (const page of pages) {
|
||||
docs.push(...(await cheerioLoader(page)))
|
||||
}
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`Finish ${relativeLinksMethod}`)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`[${orgId}]: Finish CheerioWebBaseLoader ${relativeLinksMethod}`)
|
||||
} else if (selectedLinks && selectedLinks.length > 0) {
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`pages: ${JSON.stringify(selectedLinks)}, length: ${selectedLinks.length}`)
|
||||
options.logger.info(
|
||||
`[${orgId}]: CheerioWebBaseLoader pages: ${JSON.stringify(selectedLinks)}, length: ${selectedLinks.length}`
|
||||
)
|
||||
for (const page of selectedLinks.slice(0, limit)) {
|
||||
docs.push(...(await cheerioLoader(page)))
|
||||
}
|
||||
|
||||
@@ -107,9 +107,9 @@ class Csv_DocumentLoaders implements INode {
|
||||
return { files, fromStorage }
|
||||
}
|
||||
|
||||
async getFileData(file: string, { chatflowid }: { chatflowid: string }, fromStorage?: boolean) {
|
||||
async getFileData(file: string, { orgId, chatflowid }: { orgId: string; chatflowid: string }, fromStorage?: boolean) {
|
||||
if (fromStorage) {
|
||||
return getFileFromStorage(file, chatflowid)
|
||||
return getFileFromStorage(file, orgId, chatflowid)
|
||||
} else {
|
||||
const splitDataURI = file.split(',')
|
||||
splitDataURI.pop()
|
||||
@@ -126,6 +126,7 @@ class Csv_DocumentLoaders implements INode {
|
||||
|
||||
let docs: IDocument[] = []
|
||||
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
const { files, fromStorage } = this.getFiles(nodeData)
|
||||
@@ -133,7 +134,7 @@ class Csv_DocumentLoaders implements INode {
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
|
||||
const fileData = await this.getFileData(file, { chatflowid }, fromStorage)
|
||||
const fileData = await this.getFileData(file, { orgId, chatflowid }, fromStorage)
|
||||
const blob = new Blob([fileData])
|
||||
const loader = new CSVLoader(blob, columnName.trim().length === 0 ? undefined : columnName.trim())
|
||||
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ class CustomDocumentLoader_DocumentLoaders implements INode {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
|
||||
@@ -60,7 +60,8 @@ class DocStore_DocumentLoaders implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).findBy(searchOptions)
|
||||
for (const store of stores) {
|
||||
if (store.status === 'SYNC') {
|
||||
const obj = {
|
||||
|
||||
@@ -96,11 +96,12 @@ class Docx_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
const loader = new DocxLoader(blob)
|
||||
|
||||
|
||||
@@ -118,10 +118,11 @@ class Epub_DocumentLoaders implements INode {
|
||||
files = fileName.startsWith('[') && fileName.endsWith(']') ? JSON.parse(fileName) : [fileName]
|
||||
|
||||
const chatflowid = options.chatflowid
|
||||
const orgId = options.orgId
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const tempFilePath = path.join(tempDir, `${Date.now()}_${file}`)
|
||||
fs.writeFileSync(tempFilePath, fileData)
|
||||
await this.extractDocs(usage, tempFilePath, textSplitter, docs)
|
||||
|
||||
@@ -144,6 +144,7 @@ class File_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
// specific to createAttachment to get files from chatId
|
||||
@@ -151,14 +152,14 @@ class File_DocumentLoaders implements INode {
|
||||
if (retrieveAttachmentChatId) {
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid, options.chatId)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid, options.chatId)
|
||||
const blob = new Blob([fileData])
|
||||
fileBlobs.push({ blob, ext: file.split('.').pop() || '' })
|
||||
}
|
||||
} else {
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
fileBlobs.push({ blob, ext: file.split('.').pop() || '' })
|
||||
}
|
||||
|
||||
@@ -146,11 +146,12 @@ class Json_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
const loader = new JSONLoader(blob, pointers.length != 0 ? pointers : undefined, metadata)
|
||||
|
||||
|
||||
@@ -135,11 +135,12 @@ class Jsonlines_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
const loader = new JSONLinesLoader(blob, pointer, metadata)
|
||||
|
||||
|
||||
@@ -122,11 +122,12 @@ class Pdf_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const bf = Buffer.from(fileData)
|
||||
await this.extractDocs(usage, bf, legacyBuild, textSplitter, docs)
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ class Playwright_DocumentLoaders implements INode {
|
||||
let waitForSelector = nodeData.inputs?.waitForSelector as string
|
||||
const _omitMetadataKeys = nodeData.inputs?.omitMetadataKeys as string
|
||||
const output = nodeData.outputs?.output as string
|
||||
const orgId = options.orgId
|
||||
|
||||
let omitMetadataKeys: string[] = []
|
||||
if (_omitMetadataKeys) {
|
||||
@@ -202,13 +203,14 @@ class Playwright_DocumentLoaders implements INode {
|
||||
}
|
||||
return docs
|
||||
} catch (err) {
|
||||
if (process.env.DEBUG === 'true') options.logger.error(`error in PlaywrightWebBaseLoader: ${err.message}, on page: ${url}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.error(`[${orgId}]: Error in PlaywrightWebBaseLoader: ${err.message}, on page: ${url}`)
|
||||
}
|
||||
}
|
||||
|
||||
let docs: IDocument[] = []
|
||||
if (relativeLinksMethod) {
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`Start ${relativeLinksMethod}`)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`[${orgId}]: Start PlaywrightWebBaseLoader ${relativeLinksMethod}`)
|
||||
// if limit is 0 we don't want it to default to 10 so we check explicitly for null or undefined
|
||||
// so when limit is 0 we can fetch all the links
|
||||
if (limit === null || limit === undefined) limit = 10
|
||||
@@ -219,15 +221,18 @@ class Playwright_DocumentLoaders implements INode {
|
||||
: relativeLinksMethod === 'webCrawl'
|
||||
? await webCrawl(url, limit)
|
||||
: await xmlScrape(url, limit)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`[${orgId}]: PlaywrightWebBaseLoader pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
|
||||
if (!pages || pages.length === 0) throw new Error('No relative links found')
|
||||
for (const page of pages) {
|
||||
docs.push(...(await playwrightLoader(page)))
|
||||
}
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`Finish ${relativeLinksMethod}`)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`[${orgId}]: Finish PlaywrightWebBaseLoader ${relativeLinksMethod}`)
|
||||
} else if (selectedLinks && selectedLinks.length > 0) {
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`pages: ${JSON.stringify(selectedLinks)}, length: ${selectedLinks.length}`)
|
||||
options.logger.info(
|
||||
`[${orgId}]: PlaywrightWebBaseLoader pages: ${JSON.stringify(selectedLinks)}, length: ${selectedLinks.length}`
|
||||
)
|
||||
for (const page of selectedLinks.slice(0, limit)) {
|
||||
docs.push(...(await playwrightLoader(page)))
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ class Puppeteer_DocumentLoaders implements INode {
|
||||
let waitForSelector = nodeData.inputs?.waitForSelector as string
|
||||
const _omitMetadataKeys = nodeData.inputs?.omitMetadataKeys as string
|
||||
const output = nodeData.outputs?.output as string
|
||||
const orgId = options.orgId
|
||||
|
||||
let omitMetadataKeys: string[] = []
|
||||
if (_omitMetadataKeys) {
|
||||
@@ -198,13 +199,14 @@ class Puppeteer_DocumentLoaders implements INode {
|
||||
}
|
||||
return docs
|
||||
} catch (err) {
|
||||
if (process.env.DEBUG === 'true') options.logger.error(`error in PuppeteerWebBaseLoader: ${err.message}, on page: ${url}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.error(`[${orgId}]: Error in PuppeteerWebBaseLoader: ${err.message}, on page: ${url}`)
|
||||
}
|
||||
}
|
||||
|
||||
let docs: IDocument[] = []
|
||||
if (relativeLinksMethod) {
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`Start ${relativeLinksMethod}`)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`[${orgId}]: Start PuppeteerWebBaseLoader ${relativeLinksMethod}`)
|
||||
// if limit is 0 we don't want it to default to 10 so we check explicitly for null or undefined
|
||||
// so when limit is 0 we can fetch all the links
|
||||
if (limit === null || limit === undefined) limit = 10
|
||||
@@ -215,15 +217,18 @@ class Puppeteer_DocumentLoaders implements INode {
|
||||
: relativeLinksMethod === 'webCrawl'
|
||||
? await webCrawl(url, limit)
|
||||
: await xmlScrape(url, limit)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`[${orgId}]: PuppeteerWebBaseLoader pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
|
||||
if (!pages || pages.length === 0) throw new Error('No relative links found')
|
||||
for (const page of pages) {
|
||||
docs.push(...(await puppeteerLoader(page)))
|
||||
}
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`Finish ${relativeLinksMethod}`)
|
||||
if (process.env.DEBUG === 'true') options.logger.info(`[${orgId}]: Finish PuppeteerWebBaseLoader ${relativeLinksMethod}`)
|
||||
} else if (selectedLinks && selectedLinks.length > 0) {
|
||||
if (process.env.DEBUG === 'true')
|
||||
options.logger.info(`pages: ${JSON.stringify(selectedLinks)}, length: ${selectedLinks.length}`)
|
||||
options.logger.info(
|
||||
`[${orgId}]: PuppeteerWebBaseLoader pages: ${JSON.stringify(selectedLinks)}, length: ${selectedLinks.length}`
|
||||
)
|
||||
for (const page of selectedLinks.slice(0, limit)) {
|
||||
docs.push(...(await puppeteerLoader(page)))
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ DS File Loarder integration for Flowise
|
||||
|
||||
## 🌱 Env Variables
|
||||
|
||||
| Variable | Description | Type | Default |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||
| UNSTRUCTURED_API_URL | Default `unstructuredApiUrl` for S3 File Loader | String | http://localhost:8000/general/v0/general |
|
||||
| Variable | Description | Type | Default |
|
||||
| -------------------- | ----------------------------------------------- | ------ | ---------------------------------------- |
|
||||
| UNSTRUCTURED_API_URL | Default `unstructuredApiUrl` for S3 File Loader | String | http://localhost:8000/general/v0/general |
|
||||
|
||||
## License
|
||||
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
|
||||
@@ -98,11 +98,12 @@ class Text_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
const loader = new TextLoader(blob)
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ Unstructured File Loader integration for Flowise
|
||||
|
||||
## 🌱 Env Variables
|
||||
|
||||
| Variable | Description | Type | Default |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||
| UNSTRUCTURED_API_URL | Default `apiUrl` for Unstructured File/Floder Loader | String | http://localhost:8000/general/v0/general |
|
||||
| Variable | Description | Type | Default |
|
||||
| -------------------- | ---------------------------------------------------- | ------ | ---------------------------------------- |
|
||||
| UNSTRUCTURED_API_URL | Default `apiUrl` for Unstructured File/Floder Loader | String | http://localhost:8000/general/v0/general |
|
||||
|
||||
## License
|
||||
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
|
||||
@@ -532,11 +532,12 @@ class UnstructuredFile_DocumentLoaders implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const loaderDocs = await loader.loadAndSplitBuffer(fileData, file)
|
||||
docs.push(...loaderDocs)
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ Azure OpenAI Embedding Model integration for Flowise
|
||||
|
||||
## 🌱 Env Variables
|
||||
|
||||
| Variable | Description | Type | Default |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||
| AZURE_OPENAI_API_KEY | Default `credential.azureOpenAIApiKey` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_INSTANCE_NAME | Default `credential.azureOpenAIApiInstanceName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME | Default `credential.azureOpenAIApiDeploymentName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_VERSION | Default `credential.azureOpenAIApiVersion` for Azure OpenAI Model | String | |
|
||||
| Variable | Description | Type | Default |
|
||||
| ------------------------------------------- | ------------------------------------------------------------------------ | ------ | ------- |
|
||||
| AZURE_OPENAI_API_KEY | Default `credential.azureOpenAIApiKey` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_INSTANCE_NAME | Default `credential.azureOpenAIApiInstanceName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME | Default `credential.azureOpenAIApiDeploymentName` for Azure OpenAI Model | String | |
|
||||
| AZURE_OPENAI_API_VERSION | Default `credential.azureOpenAIApiVersion` for Azure OpenAI Model | String | |
|
||||
|
||||
## License
|
||||
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from '../../../src/Interface'
|
||||
import { Metadata, BaseRetriever, LLM, ContextChatEngine, ChatMessage, NodeWithScore } from 'llamaindex'
|
||||
import { reformatSourceDocuments } from '../EngineUtils'
|
||||
import { EvaluationRunTracerLlama } from '../../../evaluation/EvaluationRunTracerLlama'
|
||||
|
||||
class ContextChatEngine_LlamaIndex implements INode {
|
||||
label: string
|
||||
@@ -93,6 +94,9 @@ class ContextChatEngine_LlamaIndex implements INode {
|
||||
|
||||
const chatEngine = new ContextChatEngine({ chatModel: model, retriever: vectorStoreRetriever })
|
||||
|
||||
// these are needed for evaluation runs
|
||||
await EvaluationRunTracerLlama.injectEvaluationMetadata(nodeData, options, chatEngine)
|
||||
|
||||
const msgs = (await memory.getChatMessages(this.sessionId, false, prependMessages)) as IMessage[]
|
||||
for (const message of msgs) {
|
||||
if (message.type === 'apiMessage') {
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
IServerSideEventStreamer
|
||||
} from '../../../src/Interface'
|
||||
import { LLM, ChatMessage, SimpleChatEngine } from 'llamaindex'
|
||||
import { EvaluationRunTracerLlama } from '../../../evaluation/EvaluationRunTracerLlama'
|
||||
|
||||
class SimpleChatEngine_LlamaIndex implements INode {
|
||||
label: string
|
||||
@@ -78,6 +79,9 @@ class SimpleChatEngine_LlamaIndex implements INode {
|
||||
|
||||
const chatEngine = new SimpleChatEngine({ llm: model })
|
||||
|
||||
// these are needed for evaluation runs
|
||||
await EvaluationRunTracerLlama.injectEvaluationMetadata(nodeData, options, chatEngine)
|
||||
|
||||
const msgs = (await memory.getChatMessages(this.sessionId, false, prependMessages)) as IMessage[]
|
||||
for (const message of msgs) {
|
||||
if (message.type === 'apiMessage') {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
NodeWithScore
|
||||
} from 'llamaindex'
|
||||
import { reformatSourceDocuments } from '../EngineUtils'
|
||||
import { EvaluationRunTracerLlama } from '../../../evaluation/EvaluationRunTracerLlama'
|
||||
|
||||
class QueryEngine_LlamaIndex implements INode {
|
||||
label: string
|
||||
@@ -72,6 +73,8 @@ class QueryEngine_LlamaIndex implements INode {
|
||||
let sourceNodes: NodeWithScore<Metadata>[] = []
|
||||
let isStreamingStarted = false
|
||||
|
||||
await EvaluationRunTracerLlama.injectEvaluationMetadata(nodeData, options, queryEngine)
|
||||
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||
const chatId = options.chatId
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
NodeWithScore
|
||||
} from 'llamaindex'
|
||||
import { reformatSourceDocuments } from '../EngineUtils'
|
||||
import { EvaluationRunTracerLlama } from '../../../evaluation/EvaluationRunTracerLlama'
|
||||
|
||||
class SubQuestionQueryEngine_LlamaIndex implements INode {
|
||||
label: string
|
||||
@@ -89,6 +90,8 @@ class SubQuestionQueryEngine_LlamaIndex implements INode {
|
||||
let sourceNodes: NodeWithScore<Metadata>[] = []
|
||||
let isStreamingStarted = false
|
||||
|
||||
await EvaluationRunTracerLlama.injectEvaluationMetadata(nodeData, options, queryEngine)
|
||||
|
||||
const shouldStreamResponse = options.shouldStreamResponse
|
||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||
const chatId = options.chatId
|
||||
|
||||
@@ -4,13 +4,13 @@ Azure OpenAI LLM integration for Flowise
|
||||
|
||||
## 🌱 Env Variables
|
||||
|
||||
| Variable | Description | Type | Default |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||
| AZURE_OPENAI_API_KEY | Default `credential.azureOpenAIApiKey` for Azure OpenAI LLM | String | |
|
||||
| AZURE_OPENAI_API_INSTANCE_NAME | Default `credential.azureOpenAIApiInstanceName` for Azure OpenAI LLM | String | |
|
||||
| AZURE_OPENAI_API_DEPLOYMENT_NAME | Default `credential.azureOpenAIApiDeploymentName` for Azure OpenAI LLM | String | |
|
||||
| AZURE_OPENAI_API_VERSION | Default `credential.azureOpenAIApiVersion` for Azure OpenAI LLM | String | |
|
||||
| Variable | Description | Type | Default |
|
||||
| -------------------------------- | ---------------------------------------------------------------------- | ------ | ------- |
|
||||
| AZURE_OPENAI_API_KEY | Default `credential.azureOpenAIApiKey` for Azure OpenAI LLM | String | |
|
||||
| AZURE_OPENAI_API_INSTANCE_NAME | Default `credential.azureOpenAIApiInstanceName` for Azure OpenAI LLM | String | |
|
||||
| AZURE_OPENAI_API_DEPLOYMENT_NAME | Default `credential.azureOpenAIApiDeploymentName` for Azure OpenAI LLM | String | |
|
||||
| AZURE_OPENAI_API_VERSION | Default `credential.azureOpenAIApiVersion` for Azure OpenAI LLM | String | |
|
||||
|
||||
## License
|
||||
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
Source code in this repository is made available under the [Apache License Version 2.0](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
|
||||
|
||||
@@ -108,6 +108,7 @@ class AgentMemory_Memory implements INode {
|
||||
const databaseType = nodeData.inputs?.databaseType as string
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const orgId = options.orgId as string
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
|
||||
let additionalConfiguration = {}
|
||||
@@ -135,7 +136,8 @@ class AgentMemory_Memory implements INode {
|
||||
threadId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
const recordManager = new SqliteSaver(args)
|
||||
return recordManager
|
||||
@@ -159,7 +161,8 @@ class AgentMemory_Memory implements INode {
|
||||
threadId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
const recordManager = new PostgresSaver(args)
|
||||
return recordManager
|
||||
@@ -184,7 +187,8 @@ class AgentMemory_Memory implements INode {
|
||||
threadId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
const recordManager = new MySQLSaver(args)
|
||||
return recordManager
|
||||
|
||||
@@ -65,6 +65,7 @@ class MySQLAgentMemory_Memory implements INode {
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const orgId = options.orgId as string
|
||||
|
||||
let additionalConfiguration = {}
|
||||
if (additionalConfig) {
|
||||
@@ -102,7 +103,8 @@ class MySQLAgentMemory_Memory implements INode {
|
||||
threadId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
const recordManager = new MySQLSaver(args)
|
||||
return recordManager
|
||||
|
||||
@@ -242,7 +242,7 @@ export class MySQLSaver extends BaseCheckpointSaver implements MemoryMethods {
|
||||
}
|
||||
|
||||
if (returnBaseMessages) {
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.config.orgId)
|
||||
}
|
||||
|
||||
let returnIMessages: IMessage[] = []
|
||||
|
||||
+3
-1
@@ -65,6 +65,7 @@ class PostgresAgentMemory_Memory implements INode {
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const orgId = options.orgId as string
|
||||
|
||||
let additionalConfiguration = {}
|
||||
if (additionalConfig) {
|
||||
@@ -101,7 +102,8 @@ class PostgresAgentMemory_Memory implements INode {
|
||||
threadId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
const recordManager = new PostgresSaver(args)
|
||||
return recordManager
|
||||
|
||||
@@ -283,7 +283,7 @@ CREATE TABLE IF NOT EXISTS ${tableName} (
|
||||
}
|
||||
|
||||
if (returnBaseMessages) {
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.config.orgId)
|
||||
}
|
||||
|
||||
let returnIMessages: IMessage[] = []
|
||||
|
||||
@@ -51,6 +51,7 @@ class SQLiteAgentMemory_Memory implements INode {
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const orgId = options.orgId as string
|
||||
|
||||
let additionalConfiguration = {}
|
||||
if (additionalConfig) {
|
||||
@@ -76,7 +77,8 @@ class SQLiteAgentMemory_Memory implements INode {
|
||||
threadId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
|
||||
const recordManager = new SqliteSaver(args)
|
||||
|
||||
@@ -266,7 +266,7 @@ CREATE TABLE IF NOT EXISTS ${tableName} (
|
||||
}
|
||||
|
||||
if (returnBaseMessages) {
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.config.orgId)
|
||||
}
|
||||
|
||||
let returnIMessages: IMessage[] = []
|
||||
|
||||
@@ -9,6 +9,7 @@ export type SaverOptions = {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
}
|
||||
|
||||
export interface CheckpointTuple {
|
||||
|
||||
@@ -61,6 +61,7 @@ class BufferMemory_Memory implements INode {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const orgId = options.orgId as string
|
||||
|
||||
return new BufferMemoryExtended({
|
||||
returnMessages: true,
|
||||
@@ -68,7 +69,8 @@ class BufferMemory_Memory implements INode {
|
||||
sessionId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -78,12 +80,14 @@ interface BufferMemoryExtendedInput {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
sessionId = ''
|
||||
|
||||
constructor(fields: BufferMemoryInput & BufferMemoryExtendedInput) {
|
||||
@@ -92,6 +96,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
this.appDataSource = fields.appDataSource
|
||||
this.databaseEntities = fields.databaseEntities
|
||||
this.chatflowid = fields.chatflowid
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async getChatMessages(
|
||||
@@ -117,7 +122,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
}
|
||||
|
||||
if (returnBaseMessages) {
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.orgId)
|
||||
}
|
||||
|
||||
let returnIMessages: IMessage[] = []
|
||||
|
||||
@@ -69,6 +69,7 @@ class BufferWindowMemory_Memory implements INode {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const orgId = options.orgId as string
|
||||
|
||||
const obj: Partial<BufferWindowMemoryInput> & BufferMemoryExtendedInput = {
|
||||
returnMessages: true,
|
||||
@@ -77,7 +78,8 @@ class BufferWindowMemory_Memory implements INode {
|
||||
k: parseInt(k, 10),
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
|
||||
return new BufferWindowMemoryExtended(obj)
|
||||
@@ -89,12 +91,14 @@ interface BufferMemoryExtendedInput {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class BufferWindowMemoryExtended extends FlowiseWindowMemory implements MemoryMethods {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
sessionId = ''
|
||||
|
||||
constructor(fields: BufferWindowMemoryInput & BufferMemoryExtendedInput) {
|
||||
@@ -103,6 +107,7 @@ class BufferWindowMemoryExtended extends FlowiseWindowMemory implements MemoryMe
|
||||
this.appDataSource = fields.appDataSource
|
||||
this.databaseEntities = fields.databaseEntities
|
||||
this.chatflowid = fields.chatflowid
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async getChatMessages(
|
||||
@@ -134,7 +139,7 @@ class BufferWindowMemoryExtended extends FlowiseWindowMemory implements MemoryMe
|
||||
}
|
||||
|
||||
if (returnBaseMessages) {
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.orgId)
|
||||
}
|
||||
|
||||
let returnIMessages: IMessage[] = []
|
||||
|
||||
+7
-2
@@ -78,6 +78,7 @@ class ConversationSummaryBufferMemory_Memory implements INode {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const orgId = options.orgId as string
|
||||
|
||||
const obj: ConversationSummaryBufferMemoryInput & BufferMemoryExtendedInput = {
|
||||
llm: model,
|
||||
@@ -87,7 +88,8 @@ class ConversationSummaryBufferMemory_Memory implements INode {
|
||||
returnMessages: true,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
|
||||
return new ConversationSummaryBufferMemoryExtended(obj)
|
||||
@@ -99,12 +101,14 @@ interface BufferMemoryExtendedInput {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class ConversationSummaryBufferMemoryExtended extends FlowiseSummaryBufferMemory implements MemoryMethods {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
sessionId = ''
|
||||
|
||||
constructor(fields: ConversationSummaryBufferMemoryInput & BufferMemoryExtendedInput) {
|
||||
@@ -113,6 +117,7 @@ class ConversationSummaryBufferMemoryExtended extends FlowiseSummaryBufferMemory
|
||||
this.appDataSource = fields.appDataSource
|
||||
this.databaseEntities = fields.databaseEntities
|
||||
this.chatflowid = fields.chatflowid
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async getChatMessages(
|
||||
@@ -137,7 +142,7 @@ class ConversationSummaryBufferMemoryExtended extends FlowiseSummaryBufferMemory
|
||||
chatMessage.unshift(...prependMessages)
|
||||
}
|
||||
|
||||
let baseMessages = await mapChatMessageToBaseMessage(chatMessage)
|
||||
let baseMessages = await mapChatMessageToBaseMessage(chatMessage, this.orgId)
|
||||
|
||||
// Prune baseMessages if it exceeds max token limit
|
||||
if (this.movingSummaryBuffer) {
|
||||
|
||||
+7
-2
@@ -69,6 +69,7 @@ class ConversationSummaryMemory_Memory implements INode {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const chatflowid = options.chatflowid as string
|
||||
const orgId = options.orgId as string
|
||||
|
||||
const obj: ConversationSummaryMemoryInput & BufferMemoryExtendedInput = {
|
||||
llm: model,
|
||||
@@ -77,7 +78,8 @@ class ConversationSummaryMemory_Memory implements INode {
|
||||
sessionId,
|
||||
appDataSource,
|
||||
databaseEntities,
|
||||
chatflowid
|
||||
chatflowid,
|
||||
orgId
|
||||
}
|
||||
|
||||
return new ConversationSummaryMemoryExtended(obj)
|
||||
@@ -89,12 +91,14 @@ interface BufferMemoryExtendedInput {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class ConversationSummaryMemoryExtended extends FlowiseSummaryMemory implements MemoryMethods {
|
||||
appDataSource: DataSource
|
||||
databaseEntities: IDatabaseEntity
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
sessionId = ''
|
||||
|
||||
constructor(fields: ConversationSummaryMemoryInput & BufferMemoryExtendedInput) {
|
||||
@@ -103,6 +107,7 @@ class ConversationSummaryMemoryExtended extends FlowiseSummaryMemory implements
|
||||
this.appDataSource = fields.appDataSource
|
||||
this.databaseEntities = fields.databaseEntities
|
||||
this.chatflowid = fields.chatflowid
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async getChatMessages(
|
||||
@@ -128,7 +133,7 @@ class ConversationSummaryMemoryExtended extends FlowiseSummaryMemory implements
|
||||
chatMessage.unshift(...prependMessages)
|
||||
}
|
||||
|
||||
const baseMessages = await mapChatMessageToBaseMessage(chatMessage)
|
||||
const baseMessages = await mapChatMessageToBaseMessage(chatMessage, this.orgId)
|
||||
|
||||
// Get summary
|
||||
if (this.llm && typeof this.llm !== 'string') {
|
||||
|
||||
@@ -125,6 +125,8 @@ const initializeDynamoDB = async (nodeData: INodeData, options: ICommonObject):
|
||||
config
|
||||
})
|
||||
|
||||
const orgId = options.orgId as string
|
||||
|
||||
const memory = new BufferMemoryExtended({
|
||||
memoryKey: memoryKey ?? 'chat_history',
|
||||
chatHistory: dynamoDb,
|
||||
@@ -132,7 +134,8 @@ const initializeDynamoDB = async (nodeData: INodeData, options: ICommonObject):
|
||||
dynamodbClient: client,
|
||||
tableName,
|
||||
partitionKey,
|
||||
dynamoKey: { [partitionKey]: { S: sessionId } }
|
||||
dynamoKey: { [partitionKey]: { S: sessionId } },
|
||||
orgId
|
||||
})
|
||||
return memory
|
||||
}
|
||||
@@ -143,6 +146,7 @@ interface BufferMemoryExtendedInput {
|
||||
tableName: string
|
||||
partitionKey: string
|
||||
dynamoKey: Record<string, AttributeValue>
|
||||
orgId: string
|
||||
}
|
||||
|
||||
interface DynamoDBSerializedChatMessage {
|
||||
@@ -165,6 +169,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
private dynamoKey: Record<string, AttributeValue>
|
||||
private messageAttributeName: string
|
||||
sessionId = ''
|
||||
orgId = ''
|
||||
dynamodbClient: DynamoDBClient
|
||||
|
||||
constructor(fields: BufferMemoryInput & BufferMemoryExtendedInput) {
|
||||
@@ -174,6 +179,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
this.tableName = fields.tableName
|
||||
this.partitionKey = fields.partitionKey
|
||||
this.dynamoKey = fields.dynamoKey
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
overrideDynamoKey(overrideSessionId = '') {
|
||||
@@ -260,7 +266,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
.filter((x): x is StoredMessage => x.type !== undefined && x.data.content !== undefined)
|
||||
const baseMessages = messages.map(mapStoredMessageToChatMessage)
|
||||
if (prependMessages?.length) {
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages)))
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages, this.orgId)))
|
||||
}
|
||||
return returnBaseMessages ? baseMessages : convertBaseMessagetoIMessage(baseMessages)
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ class Mem0_Memory implements INode {
|
||||
const initializeMem0 = async (nodeData: INodeData, options: ICommonObject): Promise<BaseMem0Memory> => {
|
||||
const initialUserId = nodeData.inputs?.user_id as string
|
||||
const useFlowiseChatId = nodeData.inputs?.useFlowiseChatId as boolean
|
||||
const orgId = options.orgId as string
|
||||
|
||||
if (!useFlowiseChatId && !initialUserId) {
|
||||
throw new Error('User ID field cannot be empty when "Use Flowise Chat ID" is OFF.')
|
||||
@@ -198,7 +199,8 @@ const initializeMem0 = async (nodeData: INodeData, options: ICommonObject): Prom
|
||||
databaseEntities: options.databaseEntities as IDatabaseEntity,
|
||||
chatflowid: options.chatflowid as string,
|
||||
searchOnly: (nodeData.inputs?.searchOnly as boolean) || false,
|
||||
useFlowiseChatId: useFlowiseChatId
|
||||
useFlowiseChatId: useFlowiseChatId,
|
||||
orgId: orgId
|
||||
}
|
||||
|
||||
return new Mem0MemoryExtended(obj)
|
||||
@@ -207,11 +209,13 @@ const initializeMem0 = async (nodeData: INodeData, options: ICommonObject): Prom
|
||||
interface Mem0MemoryExtendedInput extends Mem0MemoryInput {
|
||||
memoryOptions?: MemoryOptions | SearchOptions
|
||||
useFlowiseChatId: boolean
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class Mem0MemoryExtended extends BaseMem0Memory implements MemoryMethods {
|
||||
initialUserId: string
|
||||
userId: string
|
||||
orgId: string
|
||||
memoryKey: string
|
||||
inputKey: string
|
||||
appDataSource: DataSource
|
||||
@@ -233,6 +237,7 @@ class Mem0MemoryExtended extends BaseMem0Memory implements MemoryMethods {
|
||||
this.chatflowid = fields.chatflowid
|
||||
this.searchOnly = fields.searchOnly
|
||||
this.useFlowiseChatId = fields.useFlowiseChatId
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
// Selects Mem0 user_id based on toggle state (Flowise chat ID or input field)
|
||||
@@ -337,7 +342,7 @@ class Mem0MemoryExtended extends BaseMem0Memory implements MemoryMethods {
|
||||
console.warn('Mem0 history is not a string, cannot prepend directly.')
|
||||
}
|
||||
|
||||
return await mapChatMessageToBaseMessage(chatMessage)
|
||||
return await mapChatMessageToBaseMessage(chatMessage, this.orgId)
|
||||
}
|
||||
|
||||
return returnIMessages
|
||||
|
||||
@@ -88,9 +88,12 @@ const initializeMongoDB = async (nodeData: INodeData, options: ICommonObject): P
|
||||
const mongoDBConnectUrl = getCredentialParam('mongoDBConnectUrl', credentialData, nodeData)
|
||||
const driverInfo = { name: 'Flowise', version: (await getVersion()).version }
|
||||
|
||||
const orgId = options.orgId as string
|
||||
|
||||
return new BufferMemoryExtended({
|
||||
memoryKey: memoryKey ?? 'chat_history',
|
||||
sessionId,
|
||||
orgId,
|
||||
mongoConnection: {
|
||||
databaseName,
|
||||
collectionName,
|
||||
@@ -102,6 +105,7 @@ const initializeMongoDB = async (nodeData: INodeData, options: ICommonObject): P
|
||||
|
||||
interface BufferMemoryExtendedInput {
|
||||
sessionId: string
|
||||
orgId: string
|
||||
mongoConnection: {
|
||||
databaseName: string
|
||||
collectionName: string
|
||||
@@ -112,6 +116,7 @@ interface BufferMemoryExtendedInput {
|
||||
|
||||
class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
sessionId = ''
|
||||
orgId = ''
|
||||
mongoConnection: {
|
||||
databaseName: string
|
||||
collectionName: string
|
||||
@@ -122,6 +127,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
constructor(fields: BufferMemoryInput & BufferMemoryExtendedInput) {
|
||||
super(fields)
|
||||
this.sessionId = fields.sessionId
|
||||
this.orgId = fields.orgId
|
||||
this.mongoConnection = fields.mongoConnection
|
||||
}
|
||||
|
||||
@@ -138,7 +144,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
const messages = document?.messages || []
|
||||
const baseMessages = messages.map(mapStoredMessageToChatMessage)
|
||||
if (prependMessages?.length) {
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages)))
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages, this.orgId)))
|
||||
}
|
||||
|
||||
await client.close()
|
||||
|
||||
@@ -88,6 +88,7 @@ const initializeRedis = async (nodeData: INodeData, options: ICommonObject): Pro
|
||||
|
||||
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||
const redisUrl = getCredentialParam('redisUrl', credentialData, nodeData)
|
||||
const orgId = options.orgId as string
|
||||
|
||||
const redisOptions = redisUrl
|
||||
? redisUrl
|
||||
@@ -104,7 +105,8 @@ const initializeRedis = async (nodeData: INodeData, options: ICommonObject): Pro
|
||||
sessionId,
|
||||
windowSize,
|
||||
sessionTTL,
|
||||
redisOptions
|
||||
redisOptions,
|
||||
orgId
|
||||
})
|
||||
|
||||
return memory
|
||||
@@ -114,11 +116,13 @@ interface BufferMemoryExtendedInput {
|
||||
sessionId: string
|
||||
windowSize?: number
|
||||
sessionTTL?: number
|
||||
orgId: string
|
||||
redisOptions: RedisOptions | string
|
||||
}
|
||||
|
||||
class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
sessionId = ''
|
||||
orgId = ''
|
||||
windowSize?: number
|
||||
sessionTTL?: number
|
||||
redisOptions: RedisOptions | string
|
||||
@@ -128,6 +132,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
this.sessionId = fields.sessionId
|
||||
this.windowSize = fields.windowSize
|
||||
this.sessionTTL = fields.sessionTTL
|
||||
this.orgId = fields.orgId
|
||||
this.redisOptions = fields.redisOptions
|
||||
}
|
||||
|
||||
@@ -165,7 +170,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
const orderedMessages = rawStoredMessages.reverse().map((message) => JSON.parse(message))
|
||||
const baseMessages = orderedMessages.map(mapStoredMessageToChatMessage)
|
||||
if (prependMessages?.length) {
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages)))
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages, this.orgId)))
|
||||
}
|
||||
return returnBaseMessages ? baseMessages : convertBaseMessagetoIMessage(baseMessages)
|
||||
})
|
||||
|
||||
+7
-3
@@ -100,13 +100,14 @@ const initalizeUpstashRedis = async (nodeData: INodeData, options: ICommonObject
|
||||
sessionTTL,
|
||||
client
|
||||
})
|
||||
|
||||
const orgId = options.orgId as string
|
||||
const memory = new BufferMemoryExtended({
|
||||
memoryKey: memoryKey ?? 'chat_history',
|
||||
chatHistory: redisChatMessageHistory,
|
||||
sessionId,
|
||||
sessionTTL,
|
||||
redisClient: client
|
||||
redisClient: client,
|
||||
orgId
|
||||
})
|
||||
|
||||
return memory
|
||||
@@ -115,11 +116,13 @@ const initalizeUpstashRedis = async (nodeData: INodeData, options: ICommonObject
|
||||
interface BufferMemoryExtendedInput {
|
||||
redisClient: Redis
|
||||
sessionId: string
|
||||
orgId: string
|
||||
sessionTTL?: number
|
||||
}
|
||||
|
||||
class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
sessionId = ''
|
||||
orgId = ''
|
||||
redisClient: Redis
|
||||
sessionTTL?: number
|
||||
|
||||
@@ -128,6 +131,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
this.sessionId = fields.sessionId
|
||||
this.redisClient = fields.redisClient
|
||||
this.sessionTTL = fields.sessionTTL
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async getChatMessages(
|
||||
@@ -143,7 +147,7 @@ class BufferMemoryExtended extends FlowiseMemory implements MemoryMethods {
|
||||
const previousMessages = orderedMessages.filter((x): x is StoredMessage => x.type !== undefined && x.data.content !== undefined)
|
||||
const baseMessages = previousMessages.map(mapStoredMessageToChatMessage)
|
||||
if (prependMessages?.length) {
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages)))
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages, this.orgId)))
|
||||
}
|
||||
return returnBaseMessages ? baseMessages : convertBaseMessagetoIMessage(baseMessages)
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ const initializeZep = async (nodeData: INodeData, options: ICommonObject): Promi
|
||||
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||
const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
|
||||
|
||||
const orgId = options.orgId as string
|
||||
const obj: ZepMemoryInput & ZepMemoryExtendedInput = {
|
||||
baseURL,
|
||||
aiPrefix,
|
||||
@@ -127,6 +128,7 @@ const initializeZep = async (nodeData: INodeData, options: ICommonObject): Promi
|
||||
memoryKey,
|
||||
inputKey,
|
||||
sessionId,
|
||||
orgId,
|
||||
k: k ? parseInt(k, 10) : undefined
|
||||
}
|
||||
if (apiKey) obj.apiKey = apiKey
|
||||
@@ -136,14 +138,17 @@ const initializeZep = async (nodeData: INodeData, options: ICommonObject): Promi
|
||||
|
||||
interface ZepMemoryExtendedInput {
|
||||
k?: number
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class ZepMemoryExtended extends ZepMemory implements MemoryMethods {
|
||||
lastN?: number
|
||||
orgId = ''
|
||||
|
||||
constructor(fields: ZepMemoryInput & ZepMemoryExtendedInput) {
|
||||
super(fields)
|
||||
this.lastN = fields.k
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async loadMemoryVariables(values: InputValues, overrideSessionId = ''): Promise<MemoryVariables> {
|
||||
@@ -176,7 +181,7 @@ class ZepMemoryExtended extends ZepMemory implements MemoryMethods {
|
||||
const memoryVariables = await this.loadMemoryVariables({}, id)
|
||||
const baseMessages = memoryVariables[this.memoryKey]
|
||||
if (prependMessages?.length) {
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages)))
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages, this.orgId)))
|
||||
}
|
||||
return returnBaseMessages ? baseMessages : convertBaseMessagetoIMessage(baseMessages)
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ const initializeZep = async (nodeData: INodeData, options: ICommonObject): Promi
|
||||
|
||||
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||
const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
|
||||
const orgId = options.orgId as string
|
||||
const obj: ZepMemoryInput & ZepMemoryExtendedInput = {
|
||||
apiKey,
|
||||
aiPrefix,
|
||||
@@ -121,7 +122,8 @@ const initializeZep = async (nodeData: INodeData, options: ICommonObject): Promi
|
||||
sessionId,
|
||||
inputKey,
|
||||
memoryType: memoryType,
|
||||
returnMessages: true
|
||||
returnMessages: true,
|
||||
orgId
|
||||
}
|
||||
|
||||
return new ZepMemoryExtended(obj)
|
||||
@@ -129,14 +131,17 @@ const initializeZep = async (nodeData: INodeData, options: ICommonObject): Promi
|
||||
|
||||
interface ZepMemoryExtendedInput {
|
||||
memoryType?: 'perpetual' | 'message_window'
|
||||
orgId: string
|
||||
}
|
||||
|
||||
class ZepMemoryExtended extends ZepMemory implements MemoryMethods {
|
||||
memoryType: 'perpetual' | 'message_window'
|
||||
orgId: string
|
||||
|
||||
constructor(fields: ZepMemoryInput & ZepMemoryExtendedInput) {
|
||||
super(fields)
|
||||
this.memoryType = fields.memoryType ?? 'perpetual'
|
||||
this.orgId = fields.orgId
|
||||
}
|
||||
|
||||
async loadMemoryVariables(values: InputValues, overrideSessionId = ''): Promise<MemoryVariables> {
|
||||
@@ -169,7 +174,7 @@ class ZepMemoryExtended extends ZepMemory implements MemoryMethods {
|
||||
const memoryVariables = await this.loadMemoryVariables({}, id)
|
||||
const baseMessages = memoryVariables[this.memoryKey]
|
||||
if (prependMessages?.length) {
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages)))
|
||||
baseMessages.unshift(...(await mapChatMessageToBaseMessage(prependMessages, this.orgId)))
|
||||
}
|
||||
return returnBaseMessages ? baseMessages : convertBaseMessagetoIMessage(baseMessages)
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ async function createAgent(
|
||||
sessionId: flowObj?.sessionId,
|
||||
chatId: flowObj?.chatId,
|
||||
input: flowObj?.input,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
maxIterations: maxIterations ? parseFloat(maxIterations) : undefined
|
||||
})
|
||||
return executor
|
||||
|
||||
@@ -120,7 +120,7 @@ class ChatPromptTemplate_Prompts implements INode {
|
||||
) {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, {})
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, {})
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${messageHistoryCode}}()`, __dirname)
|
||||
if (!Array.isArray(response)) throw new Error('Returned message history must be an array')
|
||||
|
||||
@@ -680,7 +680,7 @@ async function createAgent(
|
||||
sessionId: flowObj?.sessionId,
|
||||
chatId: flowObj?.chatId,
|
||||
input: flowObj?.input,
|
||||
verbose: process.env.DEBUG === 'true',
|
||||
verbose: process.env.DEBUG === 'true' ? true : false,
|
||||
maxIterations: maxIterations ? parseFloat(maxIterations) : undefined
|
||||
})
|
||||
return executor
|
||||
@@ -877,7 +877,7 @@ const getReturnOutput = async (nodeData: INodeData, input: string, options: ICom
|
||||
const updateStateMemory = nodeData.inputs?.updateStateMemory as string
|
||||
|
||||
const selectedTab = tabIdentifier ? tabIdentifier.split(`_${nodeData.id}`)[0] : 'updateStateMemoryUI'
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
@@ -930,7 +930,7 @@ const getReturnOutput = async (nodeData: INodeData, input: string, options: ICom
|
||||
throw new Error(e)
|
||||
}
|
||||
} else if (selectedTab === 'updateStateMemoryCode' && updateStateMemoryCode) {
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, flow)
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, flow)
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${updateStateMemoryCode}}()`, __dirname)
|
||||
if (typeof response !== 'object') throw new Error('Return output must be an object')
|
||||
|
||||
@@ -267,7 +267,7 @@ const runCondition = async (nodeData: INodeData, input: string, options: ICommon
|
||||
const tabIdentifier = nodeData.inputs?.[`${TAB_IDENTIFIER}_${nodeData.id}`] as string
|
||||
|
||||
const selectedTab = tabIdentifier ? tabIdentifier.split(`_${nodeData.id}`)[0] : 'conditionUI'
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
@@ -279,7 +279,7 @@ const runCondition = async (nodeData: INodeData, input: string, options: ICommon
|
||||
}
|
||||
|
||||
if (selectedTab === 'conditionFunction' && conditionFunction) {
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, flow)
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, flow)
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${conditionFunction}}()`, __dirname)
|
||||
if (typeof response !== 'string') throw new Error('Condition function must return a string')
|
||||
|
||||
@@ -540,7 +540,7 @@ const runCondition = async (
|
||||
result = { ...jsonResult, additional_kwargs: { nodeId: nodeData.id } }
|
||||
}
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
@@ -553,7 +553,7 @@ const runCondition = async (
|
||||
}
|
||||
|
||||
if (selectedTab === 'conditionFunction' && conditionFunction) {
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, flow)
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, flow)
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${conditionFunction}}()`, __dirname)
|
||||
if (typeof response !== 'string') throw new Error('Condition function must return a string')
|
||||
|
||||
@@ -102,7 +102,7 @@ class CustomFunction_SeqAgents implements INode {
|
||||
if (!sequentialNodes || !sequentialNodes.length) throw new Error('Custom function must have a predecessor!')
|
||||
|
||||
const executeFunc = async (state: ISeqAgentsState) => {
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
|
||||
@@ -141,7 +141,8 @@ class ExecuteFlow_SeqAgents implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const chatflows = await appDataSource.getRepository(databaseEntities['ChatFlow']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const chatflows = await appDataSource.getRepository(databaseEntities['ChatFlow']).findBy(searchOptions)
|
||||
|
||||
for (let i = 0; i < chatflows.length; i += 1) {
|
||||
const data = {
|
||||
@@ -189,7 +190,7 @@ class ExecuteFlow_SeqAgents implements INode {
|
||||
const chatId = options.chatId
|
||||
|
||||
const executeFunc = async (state: ISeqAgentsState) => {
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
let flowInput = ''
|
||||
if (seqExecuteFlowInput === 'userQuestion') {
|
||||
@@ -223,7 +224,7 @@ class ExecuteFlow_SeqAgents implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
const options = {
|
||||
const callOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -234,7 +235,7 @@ class ExecuteFlow_SeqAgents implements INode {
|
||||
|
||||
let sandbox: ICommonObject = {
|
||||
$input: flowInput,
|
||||
$callOptions: options,
|
||||
$callOptions: callOptions,
|
||||
$callBody: body,
|
||||
util: undefined,
|
||||
Symbol: undefined,
|
||||
|
||||
@@ -668,7 +668,7 @@ const getReturnOutput = async (nodeData: INodeData, input: string, options: ICom
|
||||
const updateStateMemory = nodeData.inputs?.updateStateMemory as string
|
||||
|
||||
const selectedTab = tabIdentifier ? tabIdentifier.split(`_${nodeData.id}`)[0] : 'updateStateMemoryUI'
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
@@ -721,7 +721,7 @@ const getReturnOutput = async (nodeData: INodeData, input: string, options: ICom
|
||||
throw new Error(e)
|
||||
}
|
||||
} else if (selectedTab === 'updateStateMemoryCode' && updateStateMemoryCode) {
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, flow)
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, flow)
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${updateStateMemoryCode}}()`, __dirname)
|
||||
if (typeof response !== 'object') throw new Error('Return output must be an object')
|
||||
|
||||
@@ -190,7 +190,7 @@ class State_SeqAgents implements INode {
|
||||
throw new Error(e)
|
||||
}
|
||||
} else if (selectedTab === 'stateMemoryCode' && stateMemoryCode) {
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
|
||||
@@ -498,7 +498,7 @@ const getReturnOutput = async (
|
||||
const updateStateMemory = nodeData.inputs?.updateStateMemory as string
|
||||
|
||||
const selectedTab = tabIdentifier ? tabIdentifier.split(`_${nodeData.id}`)[0] : 'updateStateMemoryUI'
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const reformattedOutput = outputs.map((output) => {
|
||||
return {
|
||||
@@ -561,7 +561,7 @@ const getReturnOutput = async (
|
||||
throw new Error(e)
|
||||
}
|
||||
} else if (selectedTab === 'updateStateMemoryCode' && updateStateMemoryCode) {
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, flow)
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, flow)
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${updateStateMemoryCode}}()`, __dirname)
|
||||
if (typeof response !== 'object') throw new Error('Return output must be an object')
|
||||
|
||||
@@ -150,8 +150,14 @@ export const processImageMessage = async (llm: BaseChatModel, nodeData: INodeDat
|
||||
return multiModalMessageContent
|
||||
}
|
||||
|
||||
export const getVM = async (appDataSource: DataSource, databaseEntities: IDatabaseEntity, nodeData: INodeData, flow: ICommonObject) => {
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
export const getVM = async (
|
||||
appDataSource: DataSource,
|
||||
databaseEntities: IDatabaseEntity,
|
||||
nodeData: INodeData,
|
||||
options: ICommonObject,
|
||||
flow: ICommonObject
|
||||
) => {
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
let sandbox: any = {
|
||||
util: undefined,
|
||||
@@ -420,7 +426,7 @@ export const checkMessageHistory = async (
|
||||
if (messageHistory) {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, {})
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, {})
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${messageHistory}}()`, __dirname)
|
||||
if (!Array.isArray(response)) throw new Error('Returned message history must be an array')
|
||||
|
||||
@@ -14,17 +14,41 @@ export class ChainTool extends DynamicTool {
|
||||
super({
|
||||
...rest,
|
||||
func: async (input, runManager) => {
|
||||
const childManagers = runManager?.getChild()
|
||||
const handlers = childManagers?.handlers?.filter((handler) => !(handler instanceof CustomChainHandler)) || []
|
||||
if (childManagers) childManagers.handlers = handlers
|
||||
// prevent sending SSE events of the sub-chain
|
||||
const sseStreamer = runManager?.handlers.find((handler) => handler instanceof CustomChainHandler)?.sseStreamer
|
||||
if (runManager) {
|
||||
const callbacks = runManager.handlers
|
||||
for (let i = 0; i < callbacks.length; i += 1) {
|
||||
if (callbacks[i] instanceof CustomChainHandler) {
|
||||
;(callbacks[i] as any).sseStreamer = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((chain as any).prompt && (chain as any).prompt.promptValues) {
|
||||
const promptValues = handleEscapeCharacters((chain as any).prompt.promptValues, true)
|
||||
const values = await chain.call(promptValues, childManagers)
|
||||
|
||||
const values = await chain.call(promptValues, runManager?.getChild())
|
||||
if (runManager && sseStreamer) {
|
||||
const callbacks = runManager.handlers
|
||||
for (let i = 0; i < callbacks.length; i += 1) {
|
||||
if (callbacks[i] instanceof CustomChainHandler) {
|
||||
;(callbacks[i] as any).sseStreamer = sseStreamer
|
||||
}
|
||||
}
|
||||
}
|
||||
return values?.text
|
||||
}
|
||||
|
||||
const values = chain.run(input, childManagers)
|
||||
const values = chain.run(input, runManager?.getChild())
|
||||
if (runManager && sseStreamer) {
|
||||
const callbacks = runManager.handlers
|
||||
for (let i = 0; i < callbacks.length; i += 1) {
|
||||
if (callbacks[i] instanceof CustomChainHandler) {
|
||||
;(callbacks[i] as any).sseStreamer = sseStreamer
|
||||
}
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
})
|
||||
|
||||
@@ -122,7 +122,8 @@ class ChatflowTool_Tools implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const chatflows = await appDataSource.getRepository(databaseEntities['ChatFlow']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const chatflows = await appDataSource.getRepository(databaseEntities['ChatFlow']).findBy(searchOptions)
|
||||
|
||||
for (let i = 0; i < chatflows.length; i += 1) {
|
||||
const data = {
|
||||
|
||||
@@ -80,7 +80,8 @@ class Code_Interpreter_Tools implements INode {
|
||||
schema: z.object({
|
||||
input: z.string().describe('Python code to be executed in the sandbox environment')
|
||||
}),
|
||||
chatflowid: options.chatflowid
|
||||
chatflowid: options.chatflowid,
|
||||
orgId: options.orgId
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -92,6 +93,7 @@ type E2BToolInput = {
|
||||
apiKey: string
|
||||
schema: any
|
||||
chatflowid: string
|
||||
orgId: string
|
||||
templateCodeInterpreterE2B?: string
|
||||
domainCodeInterpreterE2B?: string
|
||||
}
|
||||
@@ -113,6 +115,8 @@ export class E2BTool extends StructuredTool {
|
||||
|
||||
chatflowid: string
|
||||
|
||||
orgId: string
|
||||
|
||||
flowObj: ICommonObject
|
||||
|
||||
templateCodeInterpreterE2B?: string
|
||||
@@ -125,6 +129,7 @@ export class E2BTool extends StructuredTool {
|
||||
this.apiKey = options.apiKey
|
||||
this.schema = options.schema
|
||||
this.chatflowid = options.chatflowid
|
||||
this.orgId = options.orgId
|
||||
this.templateCodeInterpreterE2B = options.templateCodeInterpreterE2B
|
||||
this.domainCodeInterpreterE2B = options.domainCodeInterpreterE2B
|
||||
}
|
||||
@@ -136,6 +141,7 @@ export class E2BTool extends StructuredTool {
|
||||
apiKey: options.apiKey,
|
||||
schema: options.schema,
|
||||
chatflowid: options.chatflowid,
|
||||
orgId: options.orgId,
|
||||
templateCodeInterpreterE2B: options.templateCodeInterpreterE2B,
|
||||
domainCodeInterpreterE2B: options.domainCodeInterpreterE2B
|
||||
})
|
||||
@@ -212,28 +218,33 @@ export class E2BTool extends StructuredTool {
|
||||
|
||||
const filename = `artifact_${Date.now()}.png`
|
||||
|
||||
const res = await addSingleFileToStorage(
|
||||
// Don't check storage usage because this is incoming file, and if we throw error, agent will keep on retrying
|
||||
const { path } = await addSingleFileToStorage(
|
||||
'image/png',
|
||||
pngData,
|
||||
filename,
|
||||
this.orgId,
|
||||
this.chatflowid,
|
||||
flowConfig!.chatId as string
|
||||
)
|
||||
artifacts.push({ type: 'png', data: res })
|
||||
|
||||
artifacts.push({ type: 'png', data: path })
|
||||
} else if (key === 'jpeg') {
|
||||
//@ts-ignore
|
||||
const jpegData = Buffer.from(result.jpeg, 'base64')
|
||||
|
||||
const filename = `artifact_${Date.now()}.jpg`
|
||||
|
||||
const res = await addSingleFileToStorage(
|
||||
const { path } = await addSingleFileToStorage(
|
||||
'image/jpg',
|
||||
jpegData,
|
||||
filename,
|
||||
this.orgId,
|
||||
this.chatflowid,
|
||||
flowConfig!.chatId as string
|
||||
)
|
||||
artifacts.push({ type: 'jpeg', data: res })
|
||||
|
||||
artifacts.push({ type: 'jpeg', data: path })
|
||||
} else if (key === 'html' || key === 'markdown' || key === 'latex' || key === 'json' || key === 'javascript') {
|
||||
artifacts.push({ type: key, data: (result as any)[key] })
|
||||
} //TODO: support for pdf
|
||||
|
||||
@@ -77,7 +77,8 @@ class CustomTool_Tools implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const tools = await appDataSource.getRepository(databaseEntities['Tool']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const tools = await appDataSource.getRepository(databaseEntities['Tool']).findBy(searchOptions)
|
||||
|
||||
for (let i = 0; i < tools.length; i += 1) {
|
||||
const data = {
|
||||
@@ -122,7 +123,7 @@ class CustomTool_Tools implements INode {
|
||||
obj.schema = zodSchemaFunction(z)
|
||||
}
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const flow = { chatflowId: options.chatflowid }
|
||||
|
||||
|
||||
@@ -85,8 +85,9 @@ class OpenAPIToolkit_Tools implements INode {
|
||||
let data
|
||||
if (yamlFileBase64.startsWith('FILE-STORAGE::')) {
|
||||
const file = yamlFileBase64.replace('FILE-STORAGE::', '')
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const utf8String = fileData.toString('utf-8')
|
||||
|
||||
data = load(utf8String)
|
||||
@@ -110,7 +111,7 @@ class OpenAPIToolkit_Tools implements INode {
|
||||
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
const flow = { chatflowId: options.chatflowid }
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class CustomFunction_Utilities implements INode {
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const tools = Object.fromEntries((flatten(nodeData.inputs?.tools) as StructuredTool[])?.map((tool) => [tool.name, tool]) ?? [])
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
|
||||
@@ -85,7 +85,7 @@ class IfElseFunction_Utilities implements INode {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData)
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
|
||||
@@ -213,7 +213,6 @@ class Chroma_VectorStores implements INode {
|
||||
const chromaApiKey = getCredentialParam('chromaApiKey', credentialData, nodeData)
|
||||
const chromaTenant = getCredentialParam('chromaTenant', credentialData, nodeData)
|
||||
const chromaDatabase = getCredentialParam('chromaDatabase', credentialData, nodeData)
|
||||
|
||||
const chromaMetadataFilter = nodeData.inputs?.chromaMetadataFilter
|
||||
|
||||
const obj: {
|
||||
|
||||
@@ -56,7 +56,8 @@ class DocStore_VectorStores implements INode {
|
||||
return returnData
|
||||
}
|
||||
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).find()
|
||||
const searchOptions = options.searchOptions || {}
|
||||
const stores = await appDataSource.getRepository(databaseEntities['DocumentStore']).findBy(searchOptions)
|
||||
for (const store of stores) {
|
||||
if (store.status === 'UPSERTED') {
|
||||
const obj = {
|
||||
|
||||
@@ -191,11 +191,12 @@ class Vectara_VectorStores implements INode {
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
if (!file) continue
|
||||
const fileData = await getFileFromStorage(file, chatflowid)
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
vectaraFiles.push({ blob: blob, fileName: getFileName(file) })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
import { VectaraStore, VectaraLibArgs, VectaraFilter, VectaraContextConfig, VectaraFile } from '@langchain/community/vectorstores/vectara'
|
||||
import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
|
||||
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
|
||||
import { getFileFromStorage } from '../../../src'
|
||||
|
||||
class VectaraUpload_VectorStores implements INode {
|
||||
label: string
|
||||
name: string
|
||||
version: number
|
||||
description: string
|
||||
type: string
|
||||
icon: string
|
||||
category: string
|
||||
badge: string
|
||||
baseClasses: string[]
|
||||
inputs: INodeParams[]
|
||||
credential: INodeParams
|
||||
outputs: INodeOutputsValue[]
|
||||
|
||||
constructor() {
|
||||
this.label = 'Vectara Upload File'
|
||||
this.name = 'vectaraUpload'
|
||||
this.version = 1.0
|
||||
this.type = 'Vectara'
|
||||
this.icon = 'vectara.png'
|
||||
this.category = 'Vector Stores'
|
||||
this.description = 'Upload files to Vectara'
|
||||
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
|
||||
this.badge = 'DEPRECATING'
|
||||
this.credential = {
|
||||
label: 'Connect Credential',
|
||||
name: 'credential',
|
||||
type: 'credential',
|
||||
credentialNames: ['vectaraApi']
|
||||
}
|
||||
this.inputs = [
|
||||
{
|
||||
label: 'File',
|
||||
name: 'file',
|
||||
description:
|
||||
'File to upload to Vectara. Supported file types: https://docs.vectara.com/docs/api-reference/indexing-apis/file-upload/file-upload-filetypes',
|
||||
type: 'file'
|
||||
},
|
||||
{
|
||||
label: 'Metadata Filter',
|
||||
name: 'filter',
|
||||
description:
|
||||
'Filter to apply to Vectara metadata. Refer to the <a target="_blank" href="https://docs.flowiseai.com/vector-stores/vectara">documentation</a> on how to use Vectara filters with Flowise.',
|
||||
type: 'string',
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Sentences Before',
|
||||
name: 'sentencesBefore',
|
||||
description: 'Number of sentences to fetch before the matched sentence. Defaults to 2.',
|
||||
type: 'number',
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Sentences After',
|
||||
name: 'sentencesAfter',
|
||||
description: 'Number of sentences to fetch after the matched sentence. Defaults to 2.',
|
||||
type: 'number',
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Lambda',
|
||||
name: 'lambda',
|
||||
description:
|
||||
'Improves retrieval accuracy by adjusting the balance (from 0 to 1) between neural search and keyword-based search factors.',
|
||||
type: 'number',
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Top K',
|
||||
name: 'topK',
|
||||
description: 'Number of top results to fetch. Defaults to 4',
|
||||
placeholder: '4',
|
||||
type: 'number',
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
}
|
||||
]
|
||||
this.outputs = [
|
||||
{
|
||||
label: 'Vectara Retriever',
|
||||
name: 'retriever',
|
||||
baseClasses: this.baseClasses
|
||||
},
|
||||
{
|
||||
label: 'Vectara Vector Store',
|
||||
name: 'vectorStore',
|
||||
baseClasses: [this.type, ...getBaseClasses(VectaraStore)]
|
||||
}
|
||||
]
|
||||
}
|
||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||
const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
|
||||
const customerId = getCredentialParam('customerID', credentialData, nodeData)
|
||||
const corpusId = getCredentialParam('corpusID', credentialData, nodeData).split(',')
|
||||
|
||||
const fileBase64 = nodeData.inputs?.file
|
||||
const vectaraMetadataFilter = nodeData.inputs?.filter as string
|
||||
const sentencesBefore = nodeData.inputs?.sentencesBefore as number
|
||||
const sentencesAfter = nodeData.inputs?.sentencesAfter as number
|
||||
const lambda = nodeData.inputs?.lambda as number
|
||||
const output = nodeData.outputs?.output as string
|
||||
const topK = nodeData.inputs?.topK as string
|
||||
const k = topK ? parseInt(topK, 10) : 4
|
||||
|
||||
const vectaraArgs: VectaraLibArgs = {
|
||||
apiKey: apiKey,
|
||||
customerId: customerId,
|
||||
corpusId: corpusId,
|
||||
source: 'flowise'
|
||||
}
|
||||
|
||||
const vectaraFilter: VectaraFilter = {}
|
||||
if (vectaraMetadataFilter) vectaraFilter.filter = vectaraMetadataFilter
|
||||
if (lambda) vectaraFilter.lambda = lambda
|
||||
|
||||
const vectaraContextConfig: VectaraContextConfig = {}
|
||||
if (sentencesBefore) vectaraContextConfig.sentencesBefore = sentencesBefore
|
||||
if (sentencesAfter) vectaraContextConfig.sentencesAfter = sentencesAfter
|
||||
vectaraFilter.contextConfig = vectaraContextConfig
|
||||
|
||||
let files: string[] = []
|
||||
const vectaraFiles: VectaraFile[] = []
|
||||
|
||||
if (fileBase64.startsWith('FILE-STORAGE::')) {
|
||||
const fileName = fileBase64.replace('FILE-STORAGE::', '')
|
||||
if (fileName.startsWith('[') && fileName.endsWith(']')) {
|
||||
files = JSON.parse(fileName)
|
||||
} else {
|
||||
files = [fileName]
|
||||
}
|
||||
const orgId = options.orgId
|
||||
const chatflowid = options.chatflowid
|
||||
|
||||
for (const file of files) {
|
||||
const fileData = await getFileFromStorage(file, orgId, chatflowid)
|
||||
const blob = new Blob([fileData])
|
||||
vectaraFiles.push({ blob: blob, fileName: getFileName(file) })
|
||||
}
|
||||
} else {
|
||||
if (fileBase64.startsWith('[') && fileBase64.endsWith(']')) {
|
||||
files = JSON.parse(fileBase64)
|
||||
} else {
|
||||
files = [fileBase64]
|
||||
}
|
||||
|
||||
for (const file of files) {
|
||||
const splitDataURI = file.split(',')
|
||||
splitDataURI.pop()
|
||||
const bf = Buffer.from(splitDataURI.pop() || '', 'base64')
|
||||
const blob = new Blob([bf])
|
||||
vectaraFiles.push({ blob: blob, fileName: getFileName(file) })
|
||||
}
|
||||
}
|
||||
|
||||
const vectorStore = new VectaraStore(vectaraArgs)
|
||||
await vectorStore.addFiles(vectaraFiles)
|
||||
|
||||
if (output === 'retriever') {
|
||||
const retriever = vectorStore.asRetriever(k, vectaraFilter)
|
||||
return retriever
|
||||
} else if (output === 'vectorStore') {
|
||||
;(vectorStore as any).k = k
|
||||
return vectorStore
|
||||
}
|
||||
return vectorStore
|
||||
}
|
||||
}
|
||||
|
||||
const getFileName = (fileBase64: string) => {
|
||||
let fileNames = []
|
||||
if (fileBase64.startsWith('[') && fileBase64.endsWith(']')) {
|
||||
const files = JSON.parse(fileBase64)
|
||||
for (const file of files) {
|
||||
const splitDataURI = file.split(',')
|
||||
const filename = splitDataURI[splitDataURI.length - 1].split(':')[1]
|
||||
fileNames.push(filename)
|
||||
}
|
||||
return fileNames.join(', ')
|
||||
} else {
|
||||
const splitDataURI = fileBase64.split(',')
|
||||
const filename = splitDataURI[splitDataURI.length - 1].split(':')[1]
|
||||
return filename
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { nodeClass: VectaraUpload_VectorStores }
|
||||
Reference in New Issue
Block a user