diff --git a/packages/components/nodes/memory/UpstashRedisBackedChatMemory/UpstashRedisBackedChatMemory.ts b/packages/components/nodes/memory/UpstashRedisBackedChatMemory/UpstashRedisBackedChatMemory.ts index 0f26fa33..52da0f37 100644 --- a/packages/components/nodes/memory/UpstashRedisBackedChatMemory/UpstashRedisBackedChatMemory.ts +++ b/packages/components/nodes/memory/UpstashRedisBackedChatMemory/UpstashRedisBackedChatMemory.ts @@ -1,4 +1,5 @@ -import { Redis } from '@upstash/redis' +import { Redis, RedisConfigNodejs } from '@upstash/redis' +import { isEqual } from 'lodash' import { BufferMemory, BufferMemoryInput } from 'langchain/memory' import { UpstashRedisChatMessageHistory } from '@langchain/community/stores/message/upstash_redis' import { mapStoredMessageToChatMessage, AIMessage, HumanMessage, StoredMessage, BaseMessage } from '@langchain/core/messages' @@ -6,6 +7,24 @@ import { FlowiseMemory, IMessage, INode, INodeData, INodeParams, MemoryMethods, import { convertBaseMessagetoIMessage, getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' import { ICommonObject } from '../../../src/Interface' +let redisClientSingleton: Redis +let redisClientOption: RedisConfigNodejs + +const getRedisClientbyOption = (option: RedisConfigNodejs) => { + if (!redisClientSingleton) { + // if client doesn't exists + redisClientSingleton = new Redis(option) + redisClientOption = option + return redisClientSingleton + } else if (redisClientSingleton && !isEqual(option, redisClientOption)) { + // if client exists but option changed + redisClientSingleton = new Redis(option) + redisClientOption = option + return redisClientSingleton + } + return redisClientSingleton +} + class UpstashRedisBackedChatMemory_Memory implements INode { label: string name: string @@ -75,7 +94,7 @@ const initalizeUpstashRedis = async (nodeData: INodeData, options: ICommonObject const credentialData = await getCredentialData(nodeData.credential ?? '', options) const upstashRestToken = getCredentialParam('upstashRestToken', credentialData, nodeData) - const client = new Redis({ + const client = getRedisClientbyOption({ url: baseURL, token: upstashRestToken }) diff --git a/packages/components/package.json b/packages/components/package.json index 3032ffa0..d59e563b 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -65,7 +65,7 @@ "langchain": "^0.1.20", "langfuse": "3.1.0", "langfuse-langchain": "^3.1.0", - "langsmith": "0.0.63", + "langsmith": "0.1.6", "linkifyjs": "^4.1.1", "llamaindex": "^0.0.48", "lunary": "^0.6.16", diff --git a/packages/server/src/NodesPool.ts b/packages/server/src/NodesPool.ts index 8b01e63a..82c97f2a 100644 --- a/packages/server/src/NodesPool.ts +++ b/packages/server/src/NodesPool.ts @@ -4,6 +4,7 @@ import { Dirent } from 'fs' import { getNodeModulesPackagePath } from './utils' import { promises } from 'fs' import { ICommonObject } from 'flowise-components' +import logger from './utils/logger' export class NodesPool { componentNodes: IComponentNodes = {} @@ -28,36 +29,40 @@ export class NodesPool { return Promise.all( nodeFiles.map(async (file) => { if (file.endsWith('.js')) { - const nodeModule = await require(file) + try { + const nodeModule = await require(file) - if (nodeModule.nodeClass) { - const newNodeInstance = new nodeModule.nodeClass() - newNodeInstance.filePath = file + if (nodeModule.nodeClass) { + const newNodeInstance = new nodeModule.nodeClass() + newNodeInstance.filePath = file - // Replace file icon with absolute path - if ( - newNodeInstance.icon && - (newNodeInstance.icon.endsWith('.svg') || - newNodeInstance.icon.endsWith('.png') || - newNodeInstance.icon.endsWith('.jpg')) - ) { - const filePath = file.replace(/\\/g, '/').split('/') - filePath.pop() - const nodeIconAbsolutePath = `${filePath.join('/')}/${newNodeInstance.icon}` - newNodeInstance.icon = nodeIconAbsolutePath + // Replace file icon with absolute path + if ( + newNodeInstance.icon && + (newNodeInstance.icon.endsWith('.svg') || + newNodeInstance.icon.endsWith('.png') || + newNodeInstance.icon.endsWith('.jpg')) + ) { + const filePath = file.replace(/\\/g, '/').split('/') + filePath.pop() + const nodeIconAbsolutePath = `${filePath.join('/')}/${newNodeInstance.icon}` + newNodeInstance.icon = nodeIconAbsolutePath - // Store icon path for componentCredentials - if (newNodeInstance.credential) { - for (const credName of newNodeInstance.credential.credentialNames) { - this.credentialIconPath[credName] = nodeIconAbsolutePath + // Store icon path for componentCredentials + if (newNodeInstance.credential) { + for (const credName of newNodeInstance.credential.credentialNames) { + this.credentialIconPath[credName] = nodeIconAbsolutePath + } } } - } - const skipCategories = ['Analytic', 'SpeechToText'] - if (!skipCategories.includes(newNodeInstance.category)) { - this.componentNodes[newNodeInstance.name] = newNodeInstance + const skipCategories = ['Analytic', 'SpeechToText'] + if (!skipCategories.includes(newNodeInstance.category)) { + this.componentNodes[newNodeInstance.name] = newNodeInstance + } } + } catch (err) { + logger.error(`❌ [server]: Error during initDatabase with file ${file}:`, err) } } }) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 938a2351..d52658b4 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -99,7 +99,7 @@ export class App { // Initialize database this.AppDataSource.initialize() .then(async () => { - logger.info('📦 [server]: Data Source has been initialized!') + logger.info('📦 [server]: Data Source is being initialized!') // Run Migrations Scripts await this.AppDataSource.runMigrations({ transaction: 'each' }) @@ -126,6 +126,7 @@ export class App { // Initialize telemetry this.telemetry = new Telemetry() + logger.info('📦 [server]: Data Source has been initialized!') }) .catch((err) => { logger.error('❌ [server]: Error during Data Source initialization:', err) diff --git a/packages/ui/src/views/chatflows/index.js b/packages/ui/src/views/chatflows/index.js index c87ad306..6426cdd6 100644 --- a/packages/ui/src/views/chatflows/index.js +++ b/packages/ui/src/views/chatflows/index.js @@ -47,6 +47,7 @@ const Chatflows = () => { const [view, setView] = React.useState(localStorage.getItem('flowDisplayStyle') || 'card') const handleChange = (event, nextView) => { + if (nextView === null) return localStorage.setItem('flowDisplayStyle', nextView) setView(nextView) } diff --git a/packages/ui/src/views/marketplaces/index.js b/packages/ui/src/views/marketplaces/index.js index e5a65cb9..a6d29e43 100644 --- a/packages/ui/src/views/marketplaces/index.js +++ b/packages/ui/src/views/marketplaces/index.js @@ -131,6 +131,7 @@ const Marketplace = () => { } const handleViewChange = (event, nextView) => { + if (nextView === null) return localStorage.setItem('mpDisplayStyle', nextView) setView(nextView) }