diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88d1aaac..25a27e84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -123,6 +123,8 @@ Flowise support different environment variables to configure your instance. You | Variable | Description | Type | Default | | --------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- | | PORT | The HTTP port Flowise runs on | Number | 3000 | +| CORS_ORIGINS | The allowed origins for all cross-origin HTTP calls | String | | +| IFRAME_ORIGINS | The allowed origins for iframe src embedding | String | | | FLOWISE_USERNAME | Username to login | String | | | FLOWISE_PASSWORD | Password to login | String | | | DEBUG | Print logs from components | Boolean | | @@ -138,6 +140,7 @@ Flowise support different environment variables to configure your instance. You | DATABASE_USER | Database username (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_PASSWORD | Database password (When DATABASE_TYPE is not sqlite) | String | | | DATABASE_NAME | Database name (When DATABASE_TYPE is not sqlite) | String | | +| DATABASE_SSL_KEY_BASE64 | Database SSL client cert in base64 (takes priority over DATABASE_SSL) | Boolean | false | | DATABASE_SSL | Database connection overssl (When DATABASE_TYPE is postgre) | Boolean | false | | SECRETKEY_PATH | Location where encryption key (used to encrypt/decrypt credentials) is saved | String | `your-path/Flowise/packages/server` | | FLOWISE_SECRETKEY_OVERWRITE | Encryption key to be used instead of the key stored in SECRETKEY_PATH | String | diff --git a/docker/.env.example b/docker/.env.example index 0fe69dd1..a4beaf8a 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -4,6 +4,9 @@ APIKEY_PATH=/root/.flowise SECRETKEY_PATH=/root/.flowise LOG_PATH=/root/.flowise/logs +# CORS_ORIGINS="*" +# IFRAME_ORIGINS="*" + # NUMBER_OF_PROXIES= 1 # DATABASE_TYPE=postgres @@ -13,6 +16,7 @@ LOG_PATH=/root/.flowise/logs # DATABASE_USER="" # DATABASE_PASSWORD="" # DATABASE_SSL=true +# DATABASE_SSL_KEY_BASE64= # FLOWISE_USERNAME=user # FLOWISE_PASSWORD=1234 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c8c88bf3..71bcfcfb 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -6,6 +6,8 @@ services: restart: always environment: - PORT=${PORT} + - CORS_ORIGINS=${CORS_ORIGINS} + - IFRAME_ORIGINS=${IFRAME_ORIGINS} - FLOWISE_USERNAME=${FLOWISE_USERNAME} - FLOWISE_PASSWORD=${FLOWISE_PASSWORD} - DEBUG=${DEBUG} @@ -17,6 +19,7 @@ services: - DATABASE_USER=${DATABASE_USER} - DATABASE_PASSWORD=${DATABASE_PASSWORD} - DATABASE_SSL=${DATABASE_SSL} + - DATABASE_SSL_KEY_BASE64=${DATABASE_SSL_KEY_BASE64} - APIKEY_PATH=${APIKEY_PATH} - SECRETKEY_PATH=${SECRETKEY_PATH} - FLOWISE_SECRETKEY_OVERWRITE=${FLOWISE_SECRETKEY_OVERWRITE} diff --git a/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts b/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts index 7af8457d..0acadca1 100644 --- a/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts +++ b/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts @@ -65,7 +65,7 @@ class OpenAIFunctionAgent_Agents implements INode { return prepareAgent(nodeData, { sessionId: this.sessionId, chatId: options.chatId, input }, options.chatHistory) } - async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { + async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { const memory = nodeData.inputs?.memory as FlowiseMemory const executor = prepareAgent(nodeData, { sessionId: this.sessionId, chatId: options.chatId, input }, options.chatHistory) @@ -73,12 +73,20 @@ class OpenAIFunctionAgent_Agents implements INode { const callbacks = await additionalCallbacks(nodeData, options) let res: ChainValues = {} + let sourceDocuments: ICommonObject[] = [] if (options.socketIO && options.socketIOClientId) { const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId) res = await executor.invoke({ input }, { callbacks: [loggerHandler, handler, ...callbacks] }) + if (res.sourceDocuments) { + options.socketIO.to(options.socketIOClientId).emit('sourceDocuments', flatten(res.sourceDocuments)) + sourceDocuments = res.sourceDocuments + } } else { res = await executor.invoke({ input }, { callbacks: [loggerHandler, ...callbacks] }) + if (res.sourceDocuments) { + sourceDocuments = res.sourceDocuments + } } await memory.addChatMessages( @@ -95,7 +103,7 @@ class OpenAIFunctionAgent_Agents implements INode { this.sessionId ) - return res?.output + return sourceDocuments.length ? { text: res?.output, sourceDocuments: flatten(sourceDocuments) } : res?.output } } diff --git a/packages/components/nodes/cache/RedisCache/RedisCache.ts b/packages/components/nodes/cache/RedisCache/RedisCache.ts index 6fe02e99..c43a9562 100644 --- a/packages/components/nodes/cache/RedisCache/RedisCache.ts +++ b/packages/components/nodes/cache/RedisCache/RedisCache.ts @@ -1,10 +1,47 @@ -import { Redis } from 'ioredis' +import { Redis, RedisOptions } from 'ioredis' +import { isEqual } from 'lodash' import hash from 'object-hash' import { RedisCache as LangchainRedisCache } from '@langchain/community/caches/ioredis' import { StoredGeneration, mapStoredMessageToChatMessage } from '@langchain/core/messages' import { Generation, ChatGeneration } from '@langchain/core/outputs' import { getBaseClasses, getCredentialData, getCredentialParam, ICommonObject, INode, INodeData, INodeParams } from '../../../src' +let redisClientSingleton: Redis +let redisClientOption: RedisOptions +let redisClientUrl: string + +const getRedisClientbyOption = (option: RedisOptions) => { + 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.quit() + redisClientSingleton = new Redis(option) + redisClientOption = option + return redisClientSingleton + } + return redisClientSingleton +} + +const getRedisClientbyUrl = (url: string) => { + if (!redisClientSingleton) { + // if client doesn't exists + redisClientSingleton = new Redis(url) + redisClientUrl = url + return redisClientSingleton + } else if (redisClientSingleton && url !== redisClientUrl) { + // if client exists but option changed + redisClientSingleton.quit() + redisClientSingleton = new Redis(url) + redisClientUrl = url + return redisClientSingleton + } + return redisClientSingleton +} + class RedisCache implements INode { label: string name: string @@ -61,7 +98,7 @@ class RedisCache implements INode { const tlsOptions = sslEnabled === true ? { tls: { rejectUnauthorized: false } } : {} - client = new Redis({ + client = getRedisClientbyOption({ port: portStr ? parseInt(portStr) : 6379, host, username, @@ -69,7 +106,7 @@ class RedisCache implements INode { ...tlsOptions }) } else { - client = new Redis(redisUrl) + client = getRedisClientbyUrl(redisUrl) } const redisClient = new LangchainRedisCache(client) @@ -95,7 +132,7 @@ class RedisCache implements INode { for (let i = 0; i < value.length; i += 1) { const key = getCacheKey(prompt, llmKey, String(i)) if (ttl) { - await client.set(key, JSON.stringify(serializeGeneration(value[i])), 'EX', parseInt(ttl, 10)) + await client.set(key, JSON.stringify(serializeGeneration(value[i])), 'PX', parseInt(ttl, 10)) } else { await client.set(key, JSON.stringify(serializeGeneration(value[i]))) } diff --git a/packages/components/nodes/cache/RedisCache/RedisEmbeddingsCache.ts b/packages/components/nodes/cache/RedisCache/RedisEmbeddingsCache.ts index 36dddeb6..807d10b0 100644 --- a/packages/components/nodes/cache/RedisCache/RedisEmbeddingsCache.ts +++ b/packages/components/nodes/cache/RedisCache/RedisEmbeddingsCache.ts @@ -1,9 +1,46 @@ -import { Redis } from 'ioredis' +import { Redis, RedisOptions } from 'ioredis' +import { isEqual } from 'lodash' import { RedisByteStore } from '@langchain/community/storage/ioredis' import { Embeddings } from '@langchain/core/embeddings' import { CacheBackedEmbeddings } from 'langchain/embeddings/cache_backed' import { getBaseClasses, getCredentialData, getCredentialParam, ICommonObject, INode, INodeData, INodeParams } from '../../../src' +let redisClientSingleton: Redis +let redisClientOption: RedisOptions +let redisClientUrl: string + +const getRedisClientbyOption = (option: RedisOptions) => { + 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.quit() + redisClientSingleton = new Redis(option) + redisClientOption = option + return redisClientSingleton + } + return redisClientSingleton +} + +const getRedisClientbyUrl = (url: string) => { + if (!redisClientSingleton) { + // if client doesn't exists + redisClientSingleton = new Redis(url) + redisClientUrl = url + return redisClientSingleton + } else if (redisClientSingleton && url !== redisClientUrl) { + // if client exists but option changed + redisClientSingleton.quit() + redisClientSingleton = new Redis(url) + redisClientUrl = url + return redisClientSingleton + } + return redisClientSingleton +} + class RedisEmbeddingsCache implements INode { label: string name: string @@ -75,7 +112,7 @@ class RedisEmbeddingsCache implements INode { const tlsOptions = sslEnabled === true ? { tls: { rejectUnauthorized: false } } : {} - client = new Redis({ + client = getRedisClientbyOption({ port: portStr ? parseInt(portStr) : 6379, host, username, @@ -83,7 +120,7 @@ class RedisEmbeddingsCache implements INode { ...tlsOptions }) } else { - client = new Redis(redisUrl) + client = getRedisClientbyUrl(redisUrl) } ttl ??= '3600' diff --git a/packages/components/nodes/chains/ConversationChain/ConversationChain.ts b/packages/components/nodes/chains/ConversationChain/ConversationChain.ts index 9681ef6d..e82d6804 100644 --- a/packages/components/nodes/chains/ConversationChain/ConversationChain.ts +++ b/packages/components/nodes/chains/ConversationChain/ConversationChain.ts @@ -7,6 +7,8 @@ import { ConversationChain } from 'langchain/chains' import { FlowiseMemory, ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface' import { ConsoleCallbackHandler, CustomChainHandler, additionalCallbacks } from '../../../src/handler' import { getBaseClasses, handleEscapeCharacters } from '../../../src/utils' +import { checkInputs, Moderation, streamResponse } from '../../moderation/Moderation' +import { formatResponse } from '../../outputparsers/OutputParserHelpers' let systemMessage = `The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.` const inputKey = 'input' @@ -26,7 +28,7 @@ class ConversationChain_Chains implements INode { constructor(fields?: { sessionId?: string }) { this.label = 'Conversation Chain' this.name = 'conversationChain' - this.version = 2.0 + this.version = 3.0 this.type = 'ConversationChain' this.icon = 'conv.svg' this.category = 'Chains' @@ -60,6 +62,14 @@ class ConversationChain_Chains implements INode { optional: true, list: true },*/ + { + label: 'Input Moderation', + description: 'Detect text that could generate harmful output and prevent it from being sent to the language model', + name: 'inputModeration', + type: 'Moderation', + optional: true, + list: true + }, { label: 'System Message', name: 'systemMessagePrompt', @@ -80,8 +90,21 @@ class ConversationChain_Chains implements INode { return chain } - async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { + async run(nodeData: INodeData, input: string, options: ICommonObject): Promise { const memory = nodeData.inputs?.memory + const moderations = nodeData.inputs?.inputModeration as Moderation[] + + if (moderations && moderations.length > 0) { + try { + // Use the output of the moderation chain as input for the LLM chain + input = await checkInputs(moderations, input) + } catch (e) { + await new Promise((resolve) => setTimeout(resolve, 500)) + streamResponse(options.socketIO && options.socketIOClientId, e.message, options.socketIO, options.socketIOClientId) + return formatResponse(e.message) + } + } + const chain = prepareChain(nodeData, this.sessionId, options.chatHistory) const loggerHandler = new ConsoleCallbackHandler(options.logger) diff --git a/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts b/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts index 2e882f33..385d14e5 100644 --- a/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts +++ b/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts @@ -19,7 +19,7 @@ class ChatOpenAI_ChatModels implements INode { constructor() { this.label = 'ChatOpenAI' this.name = 'chatOpenAI' - this.version = 2.0 + this.version = 3.0 this.type = 'ChatOpenAI' this.icon = 'openai.svg' this.category = 'Chat Models' diff --git a/packages/components/nodes/documentloaders/Airtable/Airtable.ts b/packages/components/nodes/documentloaders/Airtable/Airtable.ts index 225ed288..b179dc20 100644 --- a/packages/components/nodes/documentloaders/Airtable/Airtable.ts +++ b/packages/components/nodes/documentloaders/Airtable/Airtable.ts @@ -20,7 +20,7 @@ class Airtable_DocumentLoaders implements INode { constructor() { this.label = 'Airtable' this.name = 'airtable' - this.version = 2.0 + this.version = 3.0 this.type = 'Document' this.icon = 'airtable.svg' this.category = 'Document Loaders' @@ -64,10 +64,21 @@ class Airtable_DocumentLoaders implements INode { 'If your view URL looks like: https://airtable.com/app11RobdGoX0YNsC/tblJdmvbrgizbYICO/viw9UrP77Id0CE4ee, viw9UrP77Id0CE4ee is the view id', optional: true }, + { + label: 'Include Only Fields', + name: 'fields', + type: 'string', + placeholder: 'Name, Assignee, fld1u0qUz0SoOQ9Gg, fldew39v6LBN5CjUl', + optional: true, + additionalParams: true, + description: + 'Comma-separated list of field names or IDs to include. If empty, then ALL fields are used. Use field IDs if field names contain commas.' + }, { label: 'Return All', name: 'returnAll', type: 'boolean', + optional: true, default: true, additionalParams: true, description: 'If all results should be returned or only up to a given limit' @@ -76,9 +87,10 @@ class Airtable_DocumentLoaders implements INode { label: 'Limit', name: 'limit', type: 'number', + optional: true, default: 100, additionalParams: true, - description: 'Number of results to return' + description: 'Number of results to return. Ignored when Return All is enabled.' }, { label: 'Metadata', @@ -93,6 +105,8 @@ class Airtable_DocumentLoaders implements INode { const baseId = nodeData.inputs?.baseId as string const tableId = nodeData.inputs?.tableId as string const viewId = nodeData.inputs?.viewId as string + const fieldsInput = nodeData.inputs?.fields as string + const fields = fieldsInput ? fieldsInput.split(',').map((field) => field.trim()) : [] const returnAll = nodeData.inputs?.returnAll as boolean const limit = nodeData.inputs?.limit as string const textSplitter = nodeData.inputs?.textSplitter as TextSplitter @@ -105,6 +119,7 @@ class Airtable_DocumentLoaders implements INode { baseId, tableId, viewId, + fields, returnAll, accessToken, limit: limit ? parseInt(limit, 10) : 100 @@ -112,6 +127,10 @@ class Airtable_DocumentLoaders implements INode { const loader = new AirtableLoader(airtableOptions) + if (!baseId || !tableId) { + throw new Error('Base ID and Table ID must be provided.') + } + let docs = [] if (textSplitter) { @@ -145,10 +164,18 @@ interface AirtableLoaderParams { tableId: string accessToken: string viewId?: string + fields?: string[] limit?: number returnAll?: boolean } +interface AirtableLoaderRequest { + maxRecords?: number + view: string | undefined + fields?: string[] + offset?: string +} + interface AirtableLoaderResponse { records: AirtableLoaderPage[] offset?: string @@ -167,17 +194,20 @@ class AirtableLoader extends BaseDocumentLoader { public readonly viewId?: string + public readonly fields: string[] + public readonly accessToken: string public readonly limit: number public readonly returnAll: boolean - constructor({ baseId, tableId, viewId, accessToken, limit = 100, returnAll = false }: AirtableLoaderParams) { + constructor({ baseId, tableId, viewId, fields = [], accessToken, limit = 100, returnAll = false }: AirtableLoaderParams) { super() this.baseId = baseId this.tableId = tableId this.viewId = viewId + this.fields = fields this.accessToken = accessToken this.limit = limit this.returnAll = returnAll @@ -190,17 +220,21 @@ class AirtableLoader extends BaseDocumentLoader { return this.loadLimit() } - protected async fetchAirtableData(url: string, params: ICommonObject): Promise { + protected async fetchAirtableData(url: string, data: AirtableLoaderRequest): Promise { try { const headers = { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json', Accept: 'application/json' } - const response = await axios.get(url, { params, headers }) + const response = await axios.post(url, data, { headers }) return response.data } catch (error) { - throw new Error(`Failed to fetch ${url} from Airtable: ${error}`) + if (axios.isAxiosError(error)) { + throw new Error(`Failed to fetch ${url} from Airtable: ${error.message}, status: ${error.response?.status}`) + } else { + throw new Error(`Failed to fetch ${url} from Airtable: ${error}`) + } } } @@ -218,24 +252,53 @@ class AirtableLoader extends BaseDocumentLoader { } private async loadLimit(): Promise { - const params = { maxRecords: this.limit, view: this.viewId } - const data = await this.fetchAirtableData(`https://api.airtable.com/v0/${this.baseId}/${this.tableId}`, params) - if (data.records.length === 0) { - return [] + let data: AirtableLoaderRequest = { + maxRecords: this.limit, + view: this.viewId } - return data.records.map((page) => this.createDocumentFromPage(page)) + + if (this.fields.length > 0) { + data.fields = this.fields + } + + let response: AirtableLoaderResponse + let returnPages: AirtableLoaderPage[] = [] + + // Paginate if the user specifies a limit > 100 (like 200) but not return all. + do { + response = await this.fetchAirtableData(`https://api.airtable.com/v0/${this.baseId}/${this.tableId}/listRecords`, data) + returnPages.push(...response.records) + data.offset = response.offset + + // Stop if we have fetched enough records + if (returnPages.length >= this.limit) break + } while (response.offset !== undefined) + + // Truncate array to the limit if necessary + if (returnPages.length > this.limit) { + returnPages.length = this.limit + } + + return returnPages.map((page) => this.createDocumentFromPage(page)) } private async loadAll(): Promise { - const params: ICommonObject = { pageSize: 100, view: this.viewId } - let data: AirtableLoaderResponse + let data: AirtableLoaderRequest = { + view: this.viewId + } + + if (this.fields.length > 0) { + data.fields = this.fields + } + + let response: AirtableLoaderResponse let returnPages: AirtableLoaderPage[] = [] do { - data = await this.fetchAirtableData(`https://api.airtable.com/v0/${this.baseId}/${this.tableId}`, params) - returnPages.push.apply(returnPages, data.records) - params.offset = data.offset - } while (data.offset !== undefined) + response = await this.fetchAirtableData(`https://api.airtable.com/v0/${this.baseId}/${this.tableId}/listRecords`, data) + returnPages.push(...response.records) + data.offset = response.offset + } while (response.offset !== undefined) return returnPages.map((page) => this.createDocumentFromPage(page)) } } diff --git a/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts b/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts index c77f79f6..df98c3d4 100644 --- a/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts +++ b/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts @@ -34,7 +34,7 @@ class AzureOpenAIEmbedding_Embeddings implements INode { label: 'Batch Size', name: 'batchSize', type: 'number', - default: '1', + default: '100', optional: true, additionalParams: true }, diff --git a/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts b/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts index 4ddabe11..b34e4ae5 100644 --- a/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts +++ b/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts @@ -17,7 +17,7 @@ class OpenAIEmbedding_Embeddings implements INode { constructor() { this.label = 'OpenAI Embeddings' this.name = 'openAIEmbeddings' - this.version = 1.0 + this.version = 2.0 this.type = 'OpenAIEmbeddings' this.icon = 'openai.svg' this.category = 'Embeddings' @@ -30,6 +30,27 @@ class OpenAIEmbedding_Embeddings implements INode { credentialNames: ['openAIApi'] } this.inputs = [ + { + label: 'Model Name', + name: 'modelName', + type: 'options', + options: [ + { + label: 'text-embedding-3-large', + name: 'text-embedding-3-large' + }, + { + label: 'text-embedding-3-small', + name: 'text-embedding-3-small' + }, + { + label: 'text-embedding-ada-002', + name: 'text-embedding-ada-002' + } + ], + default: 'text-embedding-ada-002', + optional: true + }, { label: 'Strip New Lines', name: 'stripNewLines', @@ -66,12 +87,14 @@ class OpenAIEmbedding_Embeddings implements INode { const batchSize = nodeData.inputs?.batchSize as string const timeout = nodeData.inputs?.timeout as string const basePath = nodeData.inputs?.basepath as string + const modelName = nodeData.inputs?.modelName as string const credentialData = await getCredentialData(nodeData.credential ?? '', options) const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData) const obj: Partial & { openAIApiKey?: string } = { - openAIApiKey + openAIApiKey, + modelName } if (stripNewLines) obj.stripNewLines = stripNewLines diff --git a/packages/components/nodes/memory/MongoDBMemory/MongoDBMemory.ts b/packages/components/nodes/memory/MongoDBMemory/MongoDBMemory.ts index f5156c8d..1352f305 100644 --- a/packages/components/nodes/memory/MongoDBMemory/MongoDBMemory.ts +++ b/packages/components/nodes/memory/MongoDBMemory/MongoDBMemory.ts @@ -5,6 +5,24 @@ import { mapStoredMessageToChatMessage, AIMessage, HumanMessage, BaseMessage } f import { convertBaseMessagetoIMessage, getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' import { FlowiseMemory, ICommonObject, IMessage, INode, INodeData, INodeParams, MemoryMethods, MessageType } from '../../../src/Interface' +let mongoClientSingleton: MongoClient +let mongoUrl: string + +const getMongoClient = async (newMongoUrl: string) => { + if (!mongoClientSingleton) { + // if client doesn't exists + mongoClientSingleton = new MongoClient(newMongoUrl) + mongoUrl = newMongoUrl + return mongoClientSingleton + } else if (mongoClientSingleton && newMongoUrl !== mongoUrl) { + // if client exists but url changed + mongoClientSingleton.close() + mongoClientSingleton = new MongoClient(newMongoUrl) + mongoUrl = newMongoUrl + return mongoClientSingleton + } + return mongoClientSingleton +} class MongoDB_Memory implements INode { label: string name: string @@ -79,9 +97,7 @@ const initializeMongoDB = async (nodeData: INodeData, options: ICommonObject): P const credentialData = await getCredentialData(nodeData.credential ?? '', options) const mongoDBConnectUrl = getCredentialParam('mongoDBConnectUrl', credentialData, nodeData) - const client = new MongoClient(mongoDBConnectUrl) - await client.connect() - + const client = await getMongoClient(mongoDBConnectUrl) const collection = client.db(databaseName).collection(collectionName) const mongoDBChatMessageHistory = new MongoDBChatMessageHistory({ diff --git a/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts b/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts index e831ca89..0eaf649c 100644 --- a/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts +++ b/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts @@ -1,10 +1,47 @@ -import { Redis } from 'ioredis' +import { Redis, RedisOptions } from 'ioredis' +import { isEqual } from 'lodash' import { BufferMemory, BufferMemoryInput } from 'langchain/memory' import { RedisChatMessageHistory, RedisChatMessageHistoryInput } from '@langchain/community/stores/message/ioredis' import { mapStoredMessageToChatMessage, BaseMessage, AIMessage, HumanMessage } from '@langchain/core/messages' import { INode, INodeData, INodeParams, ICommonObject, MessageType, IMessage, MemoryMethods, FlowiseMemory } from '../../../src/Interface' import { convertBaseMessagetoIMessage, getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' +let redisClientSingleton: Redis +let redisClientOption: RedisOptions +let redisClientUrl: string + +const getRedisClientbyOption = (option: RedisOptions) => { + 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.quit() + redisClientSingleton = new Redis(option) + redisClientOption = option + return redisClientSingleton + } + return redisClientSingleton +} + +const getRedisClientbyUrl = (url: string) => { + if (!redisClientSingleton) { + // if client doesn't exists + redisClientSingleton = new Redis(url) + redisClientUrl = url + return redisClientSingleton + } else if (redisClientSingleton && url !== redisClientUrl) { + // if client exists but option changed + redisClientSingleton.quit() + redisClientSingleton = new Redis(url) + redisClientUrl = url + return redisClientSingleton + } + return redisClientSingleton +} + class RedisBackedChatMemory_Memory implements INode { label: string name: string @@ -95,7 +132,7 @@ const initalizeRedis = async (nodeData: INodeData, options: ICommonObject): Prom const tlsOptions = sslEnabled === true ? { tls: { rejectUnauthorized: false } } : {} - client = new Redis({ + client = getRedisClientbyOption({ port: portStr ? parseInt(portStr) : 6379, host, username, @@ -103,7 +140,7 @@ const initalizeRedis = async (nodeData: INodeData, options: ICommonObject): Prom ...tlsOptions }) } else { - client = new Redis(redisUrl) + client = getRedisClientbyUrl(redisUrl) } let obj: RedisChatMessageHistoryInput = { @@ -120,24 +157,6 @@ const initalizeRedis = async (nodeData: INodeData, options: ICommonObject): Prom const redisChatMessageHistory = new RedisChatMessageHistory(obj) - /*redisChatMessageHistory.getMessages = async (): Promise => { - const rawStoredMessages = await client.lrange((redisChatMessageHistory as any).sessionId, windowSize ? -windowSize : 0, -1) - const orderedMessages = rawStoredMessages.reverse().map((message) => JSON.parse(message)) - return orderedMessages.map(mapStoredMessageToChatMessage) - } - - redisChatMessageHistory.addMessage = async (message: BaseMessage): Promise => { - const messageToAdd = [message].map((msg) => msg.toDict()) - await client.lpush((redisChatMessageHistory as any).sessionId, JSON.stringify(messageToAdd[0])) - if (sessionTTL) { - await client.expire((redisChatMessageHistory as any).sessionId, sessionTTL) - } - } - - redisChatMessageHistory.clear = async (): Promise => { - await client.del((redisChatMessageHistory as any).sessionId) - }*/ - const memory = new BufferMemoryExtended({ memoryKey: memoryKey ?? 'chat_history', chatHistory: redisChatMessageHistory, diff --git a/packages/components/nodes/outputparsers/CustomListOutputParser/CustomListOutputParser.ts b/packages/components/nodes/outputparsers/CustomListOutputParser/CustomListOutputParser.ts index 8567324a..c49226d4 100644 --- a/packages/components/nodes/outputparsers/CustomListOutputParser/CustomListOutputParser.ts +++ b/packages/components/nodes/outputparsers/CustomListOutputParser/CustomListOutputParser.ts @@ -28,16 +28,17 @@ class CustomListOutputParser implements INode { label: 'Length', name: 'length', type: 'number', - default: 5, step: 1, - description: 'Number of values to return' + description: 'Number of values to return', + optional: true }, { label: 'Separator', name: 'separator', type: 'string', description: 'Separator between values', - default: ',' + default: ',', + optional: true }, { label: 'Autofix', @@ -53,10 +54,11 @@ class CustomListOutputParser implements INode { const separator = nodeData.inputs?.separator as string const lengthStr = nodeData.inputs?.length as string const autoFix = nodeData.inputs?.autofixParser as boolean - let length = 5 - if (lengthStr) length = parseInt(lengthStr, 10) - const parser = new LangchainCustomListOutputParser({ length: length, separator: separator }) + const parser = new LangchainCustomListOutputParser({ + length: lengthStr ? parseInt(lengthStr, 10) : undefined, + separator: separator + }) Object.defineProperty(parser, 'autoFix', { enumerable: true, configurable: true, diff --git a/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts b/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts index 65422bd5..c2322ddb 100644 --- a/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts +++ b/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts @@ -1,8 +1,11 @@ +import { z } from 'zod' +import { DynamicStructuredTool } from '@langchain/core/tools' +import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager' import { DynamicTool } from '@langchain/core/tools' import { BaseRetriever } from '@langchain/core/retrievers' -import { createRetrieverTool } from 'langchain/tools/retriever' import { INode, INodeData, INodeParams } from '../../../src/Interface' import { getBaseClasses } from '../../../src/utils' +import { SOURCE_DOCUMENTS_PREFIX } from '../../../src/agents' class Retriever_Tools implements INode { label: string @@ -19,7 +22,7 @@ class Retriever_Tools implements INode { constructor() { this.label = 'Retriever Tool' this.name = 'retrieverTool' - this.version = 1.0 + this.version = 2.0 this.type = 'RetrieverTool' this.icon = 'retrievertool.svg' this.category = 'Tools' @@ -44,6 +47,12 @@ class Retriever_Tools implements INode { label: 'Retriever', name: 'retriever', type: 'BaseRetriever' + }, + { + label: 'Return Source Documents', + name: 'returnSourceDocuments', + type: 'boolean', + optional: true } ] } @@ -52,12 +61,25 @@ class Retriever_Tools implements INode { const name = nodeData.inputs?.name as string const description = nodeData.inputs?.description as string const retriever = nodeData.inputs?.retriever as BaseRetriever + const returnSourceDocuments = nodeData.inputs?.returnSourceDocuments as boolean - const tool = createRetrieverTool(retriever, { + const input = { name, description + } + + const func = async ({ input }: { input: string }, runManager?: CallbackManagerForToolRun) => { + const docs = await retriever.getRelevantDocuments(input, runManager?.getChild('retriever')) + const content = docs.map((doc) => doc.pageContent).join('\n\n') + const sourceDocuments = JSON.stringify(docs) + return returnSourceDocuments ? content + SOURCE_DOCUMENTS_PREFIX + sourceDocuments : content + } + + const schema = z.object({ + input: z.string().describe('query to look up in retriever') }) + const tool = new DynamicStructuredTool({ ...input, func, schema }) return tool } } diff --git a/packages/components/nodes/vectorstores/Redis/Redis.ts b/packages/components/nodes/vectorstores/Redis/Redis.ts index 843303bd..c1b9c7d4 100644 --- a/packages/components/nodes/vectorstores/Redis/Redis.ts +++ b/packages/components/nodes/vectorstores/Redis/Redis.ts @@ -1,5 +1,5 @@ -import { flatten } from 'lodash' -import { createClient, SearchOptions } from 'redis' +import { flatten, isEqual } from 'lodash' +import { createClient, SearchOptions, RedisClientOptions } from 'redis' import { Embeddings } from '@langchain/core/embeddings' import { RedisVectorStore, RedisVectorStoreConfig } from '@langchain/community/vectorstores/redis' import { Document } from '@langchain/core/documents' @@ -7,6 +7,27 @@ import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' import { escapeAllStrings, escapeSpecialChars, unEscapeSpecialChars } from './utils' +let redisClientSingleton: ReturnType +let redisClientOption: RedisClientOptions + +const getRedisClient = async (option: RedisClientOptions) => { + if (!redisClientSingleton) { + // if client doesn't exists + redisClientSingleton = createClient(option) + await redisClientSingleton.connect() + redisClientOption = option + return redisClientSingleton + } else if (redisClientSingleton && !isEqual(option, redisClientOption)) { + // if client exists but option changed + redisClientSingleton.quit() + redisClientSingleton = createClient(option) + await redisClientSingleton.connect() + redisClientOption = option + return redisClientSingleton + } + return redisClientSingleton +} + class Redis_VectorStores implements INode { label: string name: string @@ -149,8 +170,7 @@ class Redis_VectorStores implements INode { } try { - const redisClient = createClient({ url: redisUrl }) - await redisClient.connect() + const redisClient = await getRedisClient({ url: redisUrl }) const storeConfig: RedisVectorStoreConfig = { redisClient: redisClient, @@ -210,8 +230,7 @@ class Redis_VectorStores implements INode { redisUrl = 'redis://' + username + ':' + password + '@' + host + ':' + portStr } - const redisClient = createClient({ url: redisUrl }) - await redisClient.connect() + const redisClient = await getRedisClient({ url: redisUrl }) const storeConfig: RedisVectorStoreConfig = { redisClient: redisClient, diff --git a/packages/components/nodes/vectorstores/Redis/RedisSearchBase.ts b/packages/components/nodes/vectorstores/Redis/RedisSearchBase.ts index f4200fda..fd7572e9 100644 --- a/packages/components/nodes/vectorstores/Redis/RedisSearchBase.ts +++ b/packages/components/nodes/vectorstores/Redis/RedisSearchBase.ts @@ -1,3 +1,10 @@ +import { createClient, SearchOptions, RedisClientOptions } from 'redis' +import { isEqual } from 'lodash' +import { Embeddings } from '@langchain/core/embeddings' +import { VectorStore } from '@langchain/core/vectorstores' +import { Document } from '@langchain/core/documents' +import { RedisVectorStore } from '@langchain/community/vectorstores/redis' +import { escapeSpecialChars, unEscapeSpecialChars } from './utils' import { getBaseClasses, getCredentialData, @@ -7,12 +14,27 @@ import { INodeOutputsValue, INodeParams } from '../../../src' -import { Embeddings } from '@langchain/core/embeddings' -import { VectorStore } from '@langchain/core/vectorstores' -import { Document } from '@langchain/core/documents' -import { createClient, SearchOptions } from 'redis' -import { RedisVectorStore } from '@langchain/community/vectorstores/redis' -import { escapeSpecialChars, unEscapeSpecialChars } from './utils' + +let redisClientSingleton: ReturnType +let redisClientOption: RedisClientOptions + +const getRedisClient = async (option: RedisClientOptions) => { + if (!redisClientSingleton) { + // if client doesn't exists + redisClientSingleton = createClient(option) + await redisClientSingleton.connect() + redisClientOption = option + return redisClientSingleton + } else if (redisClientSingleton && !isEqual(option, redisClientOption)) { + // if client exists but option changed + redisClientSingleton.quit() + redisClientSingleton = createClient(option) + await redisClientSingleton.connect() + redisClientOption = option + return redisClientSingleton + } + return redisClientSingleton +} export abstract class RedisSearchBase { label: string @@ -140,8 +162,7 @@ export abstract class RedisSearchBase { redisUrl = 'redis://' + username + ':' + password + '@' + host + ':' + portStr } - this.redisClient = createClient({ url: redisUrl }) - await this.redisClient.connect() + this.redisClient = await getRedisClient({ url: redisUrl }) const vectorStore = await this.constructVectorStore(embeddings, indexName, replaceIndex, docs) if (!contentKey || contentKey === '') contentKey = 'content' diff --git a/packages/components/src/agents.ts b/packages/components/src/agents.ts index 36adc201..c795784d 100644 --- a/packages/components/src/agents.ts +++ b/packages/components/src/agents.ts @@ -1,5 +1,6 @@ +import { flatten } from 'lodash' import { ChainValues } from '@langchain/core/utils/types' -import { AgentStep, AgentFinish, AgentAction } from '@langchain/core/agents' +import { AgentStep, AgentAction } from '@langchain/core/agents' import { BaseMessage, FunctionMessage, AIMessage } from '@langchain/core/messages' import { OutputParserException } from '@langchain/core/output_parsers' import { CallbackManager, CallbackManagerForChainRun, Callbacks } from '@langchain/core/callbacks/manager' @@ -9,6 +10,11 @@ import { Serializable } from '@langchain/core/load/serializable' import { BaseChain, SerializedLLMChain } from 'langchain/chains' import { AgentExecutorInput, BaseSingleActionAgent, BaseMultiActionAgent, RunnableAgent, StoppingMethod } from 'langchain/agents' +export const SOURCE_DOCUMENTS_PREFIX = '\n\n----FLOWISE_SOURCE_DOCUMENTS----\n\n' +type AgentFinish = { + returnValues: Record + log: string +} type AgentExecutorOutput = ChainValues interface AgentExecutorIteratorInput { @@ -317,10 +323,12 @@ export class AgentExecutor extends BaseChain { const steps: AgentStep[] = [] let iterations = 0 + let sourceDocuments: Array = [] const getOutput = async (finishStep: AgentFinish): Promise => { const { returnValues } = finishStep const additional = await this.agent.prepareForOutput(returnValues, steps) + if (sourceDocuments.length) additional.sourceDocuments = flatten(sourceDocuments) if (this.returnIntermediateSteps) { return { ...returnValues, intermediateSteps: steps, ...additional } @@ -408,6 +416,17 @@ export class AgentExecutor extends BaseChain { return { action, observation: observation ?? '' } } } + if (observation?.includes(SOURCE_DOCUMENTS_PREFIX)) { + const observationArray = observation.split(SOURCE_DOCUMENTS_PREFIX) + observation = observationArray[0] + const docs = observationArray[1] + try { + const parsedDocs = JSON.parse(docs) + sourceDocuments.push(parsedDocs) + } catch (e) { + console.error('Error parsing source documents from tool') + } + } return { action, observation: observation ?? '' } }) ) @@ -502,6 +521,10 @@ export class AgentExecutor extends BaseChain { chatId: this.chatId, input: this.input }) + if (observation?.includes(SOURCE_DOCUMENTS_PREFIX)) { + const observationArray = observation.split(SOURCE_DOCUMENTS_PREFIX) + observation = observationArray[0] + } } catch (e) { if (e instanceof ToolInputParsingException) { if (this.handleParsingErrors === true) { diff --git a/packages/server/.env.example b/packages/server/.env.example index ed54ac66..ebc59cf3 100644 --- a/packages/server/.env.example +++ b/packages/server/.env.example @@ -1,4 +1,6 @@ PORT=3000 +# CORS_ORIGINS="*" +# IFRAME_ORIGINS="*" # DATABASE_PATH=/your_database_path/.flowise # APIKEY_PATH=/your_api_key_path/.flowise # SECRETKEY_PATH=/your_api_key_path/.flowise @@ -13,6 +15,7 @@ PORT=3000 # DATABASE_USER="" # DATABASE_PASSWORD="" # DATABASE_SSL=true +# DATABASE_SSL_KEY_BASE64= # FLOWISE_USERNAME=user # FLOWISE_PASSWORD=1234 diff --git a/packages/server/marketplaces/chatflows/API Agent OpenAI.json b/packages/server/marketplaces/chatflows/API Agent OpenAI.json index 002c08c1..87f6d6d2 100644 --- a/packages/server/marketplaces/chatflows/API Agent OpenAI.json +++ b/packages/server/marketplaces/chatflows/API Agent OpenAI.json @@ -88,7 +88,7 @@ "data": { "id": "chatOpenAI_1", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -111,6 +111,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -127,6 +143,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -407,7 +427,7 @@ "data": { "id": "chatOpenAI_2", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -430,6 +450,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -446,6 +482,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/API Agent.json b/packages/server/marketplaces/chatflows/API Agent.json index eabc8f2e..af99be9d 100644 --- a/packages/server/marketplaces/chatflows/API Agent.json +++ b/packages/server/marketplaces/chatflows/API Agent.json @@ -396,7 +396,7 @@ "data": { "id": "chatOpenAI_2", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -419,6 +419,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -435,6 +451,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -567,7 +587,7 @@ "data": { "id": "chatOpenAI_1", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -590,6 +610,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -606,6 +642,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -738,7 +778,7 @@ "data": { "id": "chatOpenAI_3", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -761,6 +801,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -777,6 +833,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Antonym.json b/packages/server/marketplaces/chatflows/Antonym.json index 85cd5e4c..ef997feb 100644 --- a/packages/server/marketplaces/chatflows/Antonym.json +++ b/packages/server/marketplaces/chatflows/Antonym.json @@ -175,7 +175,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -198,6 +198,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -214,6 +230,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -381,13 +401,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{fewShotPromptTemplate_1.data.instance}}", "outputParser": "", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/AutoGPT.json b/packages/server/marketplaces/chatflows/AutoGPT.json index 0062cd43..4edbf823 100644 --- a/packages/server/marketplaces/chatflows/AutoGPT.json +++ b/packages/server/marketplaces/chatflows/AutoGPT.json @@ -251,7 +251,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -274,6 +274,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -290,6 +306,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -422,7 +442,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -436,6 +456,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -474,7 +516,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -506,7 +549,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 2, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], diff --git a/packages/server/marketplaces/chatflows/BabyAGI.json b/packages/server/marketplaces/chatflows/BabyAGI.json index 81e3f230..3137d511 100644 --- a/packages/server/marketplaces/chatflows/BabyAGI.json +++ b/packages/server/marketplaces/chatflows/BabyAGI.json @@ -77,7 +77,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -91,6 +91,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -129,7 +151,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -161,7 +184,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 2, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], @@ -321,7 +344,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -344,6 +367,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/CSV Agent.json b/packages/server/marketplaces/chatflows/CSV Agent.json index 61d97c4d..e16377d2 100644 --- a/packages/server/marketplaces/chatflows/CSV Agent.json +++ b/packages/server/marketplaces/chatflows/CSV Agent.json @@ -70,7 +70,7 @@ "id": "chatOpenAI_0", "label": "ChatOpenAI", "name": "chatOpenAI", - "version": 2, + "version": 3, "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], "category": "Chat Models", @@ -92,6 +92,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -108,6 +124,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Chat with a Podcast.json b/packages/server/marketplaces/chatflows/Chat with a Podcast.json index 0a5d4ac6..f8d8d26c 100644 --- a/packages/server/marketplaces/chatflows/Chat with a Podcast.json +++ b/packages/server/marketplaces/chatflows/Chat with a Podcast.json @@ -194,7 +194,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -217,6 +217,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -233,6 +249,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -440,7 +460,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -454,6 +474,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -492,7 +534,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/ChatGPTPlugin.json b/packages/server/marketplaces/chatflows/ChatGPTPlugin.json index b8e2cf01..12bea993 100644 --- a/packages/server/marketplaces/chatflows/ChatGPTPlugin.json +++ b/packages/server/marketplaces/chatflows/ChatGPTPlugin.json @@ -215,7 +215,7 @@ "id": "chatOpenAI_0", "label": "ChatOpenAI", "name": "chatOpenAI", - "version": 2, + "version": 3, "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], "category": "Chat Models", @@ -237,6 +237,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -253,6 +269,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Claude LLM.json b/packages/server/marketplaces/chatflows/Claude LLM.json index 5d632ff1..7b32de48 100644 --- a/packages/server/marketplaces/chatflows/Claude LLM.json +++ b/packages/server/marketplaces/chatflows/Claude LLM.json @@ -70,7 +70,7 @@ "data": { "id": "conversationChain_0", "label": "Conversation Chain", - "version": 2, + "version": 3, "name": "conversationChain", "type": "ConversationChain", "baseClasses": ["ConversationChain", "LLMChain", "BaseChain", "Runnable"], @@ -110,9 +110,19 @@ "description": "Override existing prompt with Chat Prompt Template. Human Message must includes {input} variable", "optional": true, "id": "conversationChain_0-input-chatPromptTemplate-ChatPromptTemplate" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "conversationChain_0-input-inputModeration-Moderation" } ], "inputs": { + "inputModeration": "", "model": "{{chatAnthropic_0.data.instance}}", "memory": "{{bufferMemory_0.data.instance}}", "chatPromptTemplate": "{{chatPromptTemplate_0.data.instance}}", diff --git a/packages/server/marketplaces/chatflows/Conversational Agent.json b/packages/server/marketplaces/chatflows/Conversational Agent.json index b27d3886..031a29c0 100644 --- a/packages/server/marketplaces/chatflows/Conversational Agent.json +++ b/packages/server/marketplaces/chatflows/Conversational Agent.json @@ -156,7 +156,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -179,6 +179,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -195,6 +211,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Conversational Retrieval Agent.json b/packages/server/marketplaces/chatflows/Conversational Retrieval Agent.json index 4378a47d..40c689f5 100644 --- a/packages/server/marketplaces/chatflows/Conversational Retrieval Agent.json +++ b/packages/server/marketplaces/chatflows/Conversational Retrieval Agent.json @@ -14,7 +14,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -28,6 +28,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -66,7 +88,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -194,6 +217,13 @@ "rows": 3, "placeholder": "Searches and returns documents regarding the state-of-the-union.", "id": "retrieverTool_0-input-description-string" + }, + { + "label": "Return Source Documents", + "name": "returnSourceDocuments", + "type": "boolean", + "optional": true, + "id": "retrieverTool_0-input-returnSourceDocuments-boolean" } ], "inputAnchors": [ @@ -207,7 +237,8 @@ "inputs": { "name": "search_website", "description": "Searches and return documents regarding Jane - a culinary institution that offers top quality coffee, pastries, breakfast, lunch, and a variety of baked goods. They have multiple locations, including Jane on Fillmore, Jane on Larkin, Jane the Bakery, Toy Boat By Jane, and Little Jane on Grant. They emphasize healthy eating with a focus on flavor and quality ingredients. They bake everything in-house and work with local suppliers to source ingredients directly from farmers. They also offer catering services and delivery options.", - "retriever": "{{pinecone_0.data.instance}}" + "retriever": "{{pinecone_0.data.instance}}", + "returnSourceDocuments": true }, "outputAnchors": [ { @@ -296,7 +327,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 2, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], @@ -456,7 +487,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -479,6 +510,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json b/packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json index 253a1dfc..e73a9d28 100644 --- a/packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json +++ b/packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json @@ -14,7 +14,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -28,6 +28,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -66,7 +88,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -346,7 +369,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -369,6 +392,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -536,7 +567,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 2, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], diff --git a/packages/server/marketplaces/chatflows/Flowise Docs QnA.json b/packages/server/marketplaces/chatflows/Flowise Docs QnA.json index 16f70801..6975fc68 100644 --- a/packages/server/marketplaces/chatflows/Flowise Docs QnA.json +++ b/packages/server/marketplaces/chatflows/Flowise Docs QnA.json @@ -376,7 +376,7 @@ "id": "chatOpenAI_0", "label": "ChatOpenAI", "name": "chatOpenAI", - "version": 2, + "version": 3, "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], "category": "Chat Models", @@ -398,6 +398,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -414,6 +430,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -547,7 +567,7 @@ "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", "name": "openAIEmbeddings", - "version": 1, + "version": 2, "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], "category": "Embeddings", @@ -560,6 +580,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -598,7 +640,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json b/packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json index 5e33b63a..93009574 100644 --- a/packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json +++ b/packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json @@ -234,13 +234,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{huggingFaceInference_LLMs_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/IfElse.json b/packages/server/marketplaces/chatflows/IfElse.json index 690d3ce5..f3fddebf 100644 --- a/packages/server/marketplaces/chatflows/IfElse.json +++ b/packages/server/marketplaces/chatflows/IfElse.json @@ -489,13 +489,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{openAI_1.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "FirstChain" + "chainName": "FirstChain", + "inputModeration": "" }, "outputAnchors": [ { @@ -578,13 +588,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_1-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_1-input-inputModeration-Moderation" } ], "inputs": { "model": "{{openAI_2.data.instance}}", "prompt": "{{promptTemplate_1.data.instance}}", "outputParser": "", - "chainName": "LastChain" + "chainName": "LastChain", + "inputModeration": "" }, "outputAnchors": [ { @@ -742,8 +762,8 @@ "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{promptTemplate_2.data.instance}}", "outputParser": "", - "inputModeration": "", - "chainName": "FallbackChain" + "chainName": "FallbackChain", + "inputModeration": "" }, "outputAnchors": [ { @@ -888,7 +908,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -911,6 +931,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/Image Generation.json b/packages/server/marketplaces/chatflows/Image Generation.json index 98d12238..7dafcedf 100644 --- a/packages/server/marketplaces/chatflows/Image Generation.json +++ b/packages/server/marketplaces/chatflows/Image Generation.json @@ -289,13 +289,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{replicate_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { @@ -378,13 +388,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_1-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_1-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{promptTemplate_1.data.instance}}", "outputParser": "", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { @@ -432,7 +452,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -455,6 +475,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/Input Moderation.json b/packages/server/marketplaces/chatflows/Input Moderation.json index 1f6cc624..ed823a21 100644 --- a/packages/server/marketplaces/chatflows/Input Moderation.json +++ b/packages/server/marketplaces/chatflows/Input Moderation.json @@ -164,7 +164,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -187,6 +187,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/List Output Parser.json b/packages/server/marketplaces/chatflows/List Output Parser.json index 33841d15..eaf56dff 100644 --- a/packages/server/marketplaces/chatflows/List Output Parser.json +++ b/packages/server/marketplaces/chatflows/List Output Parser.json @@ -49,13 +49,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "{{csvOutputParser_0.data.instance}}", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { @@ -213,7 +223,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -236,6 +246,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -252,6 +278,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Long Term Memory.json b/packages/server/marketplaces/chatflows/Long Term Memory.json index cf0fa4d4..1b3e48e1 100644 --- a/packages/server/marketplaces/chatflows/Long Term Memory.json +++ b/packages/server/marketplaces/chatflows/Long Term Memory.json @@ -112,7 +112,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -126,6 +126,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -164,7 +186,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -483,7 +506,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -506,6 +529,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/Metadata Filter.json b/packages/server/marketplaces/chatflows/Metadata Filter.json index f7b2fbfb..ef928854 100644 --- a/packages/server/marketplaces/chatflows/Metadata Filter.json +++ b/packages/server/marketplaces/chatflows/Metadata Filter.json @@ -346,7 +346,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -360,6 +360,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -398,7 +420,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -430,7 +453,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -453,6 +476,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -620,7 +651,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 2, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], diff --git a/packages/server/marketplaces/chatflows/Multi Prompt Chain.json b/packages/server/marketplaces/chatflows/Multi Prompt Chain.json index 0a888a6b..314e24a6 100644 --- a/packages/server/marketplaces/chatflows/Multi Prompt Chain.json +++ b/packages/server/marketplaces/chatflows/Multi Prompt Chain.json @@ -278,7 +278,7 @@ "id": "chatOpenAI_0", "label": "ChatOpenAI", "name": "chatOpenAI", - "version": 2, + "version": 3, "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], "category": "Chat Models", @@ -300,6 +300,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -316,6 +332,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json b/packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json index e86b28c9..8c9e8537 100644 --- a/packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json +++ b/packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json @@ -281,7 +281,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -295,6 +295,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -333,7 +355,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -365,7 +388,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -388,6 +411,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -555,7 +586,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 2, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], diff --git a/packages/server/marketplaces/chatflows/Multiple VectorDB.json b/packages/server/marketplaces/chatflows/Multiple VectorDB.json index d53cb55e..e5a16caa 100644 --- a/packages/server/marketplaces/chatflows/Multiple VectorDB.json +++ b/packages/server/marketplaces/chatflows/Multiple VectorDB.json @@ -271,7 +271,7 @@ "data": { "id": "openAIEmbeddings_1", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -285,6 +285,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_1-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_1-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -323,7 +345,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -355,7 +378,7 @@ "data": { "id": "openAIEmbeddings_2", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -369,6 +392,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_2-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_2-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -407,7 +452,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -439,7 +485,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -462,6 +508,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -949,7 +1003,7 @@ "data": { "id": "chatOpenAI_1", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -972,6 +1026,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -1139,7 +1201,7 @@ "data": { "id": "chatOpenAI_2", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -1162,6 +1224,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/OpenAI Agent.json b/packages/server/marketplaces/chatflows/OpenAI Agent.json index 17e59236..e3e80dcc 100644 --- a/packages/server/marketplaces/chatflows/OpenAI Agent.json +++ b/packages/server/marketplaces/chatflows/OpenAI Agent.json @@ -279,7 +279,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -302,6 +302,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -318,6 +334,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/Prompt Chaining with VectorStore.json b/packages/server/marketplaces/chatflows/Prompt Chaining with VectorStore.json index 0ddec74f..46e1257d 100644 --- a/packages/server/marketplaces/chatflows/Prompt Chaining with VectorStore.json +++ b/packages/server/marketplaces/chatflows/Prompt Chaining with VectorStore.json @@ -264,13 +264,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_2-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_2-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "RephraseQuestion" + "chainName": "RephraseQuestion", + "inputModeration": "" }, "outputAnchors": [ { @@ -353,13 +363,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_1-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_1-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_1.data.instance}}", "prompt": "{{chatPromptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "FinalResponse" + "chainName": "FinalResponse", + "inputModeration": "" }, "outputAnchors": [ { @@ -407,7 +427,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -430,6 +450,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -597,7 +625,7 @@ "data": { "id": "chatOpenAI_1", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -620,6 +648,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -934,7 +970,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -948,6 +984,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -986,7 +1044,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/Prompt Chaining.json b/packages/server/marketplaces/chatflows/Prompt Chaining.json index 3181bc47..267d8222 100644 --- a/packages/server/marketplaces/chatflows/Prompt Chaining.json +++ b/packages/server/marketplaces/chatflows/Prompt Chaining.json @@ -488,13 +488,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{openAI_1.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "FirstChain" + "chainName": "FirstChain", + "inputModeration": "" }, "outputAnchors": [ { @@ -577,13 +587,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_1-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_1-input-inputModeration-Moderation" } ], "inputs": { "model": "{{openAI_2.data.instance}}", "prompt": "{{promptTemplate_1.data.instance}}", "outputParser": "", - "chainName": "LastChain" + "chainName": "LastChain", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/ReAct Agent.json b/packages/server/marketplaces/chatflows/ReAct Agent.json index b776dd37..e4a7fab8 100644 --- a/packages/server/marketplaces/chatflows/ReAct Agent.json +++ b/packages/server/marketplaces/chatflows/ReAct Agent.json @@ -99,7 +99,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -122,6 +122,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/Replicate LLM.json b/packages/server/marketplaces/chatflows/Replicate LLM.json index bee565ce..832e85c7 100644 --- a/packages/server/marketplaces/chatflows/Replicate LLM.json +++ b/packages/server/marketplaces/chatflows/Replicate LLM.json @@ -227,13 +227,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{replicate_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/SQL DB Chain.json b/packages/server/marketplaces/chatflows/SQL DB Chain.json index 026a03d8..92e42178 100644 --- a/packages/server/marketplaces/chatflows/SQL DB Chain.json +++ b/packages/server/marketplaces/chatflows/SQL DB Chain.json @@ -13,7 +13,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -36,6 +36,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -52,6 +68,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/SQL Prompt.json b/packages/server/marketplaces/chatflows/SQL Prompt.json index ad08fed8..406c2e52 100644 --- a/packages/server/marketplaces/chatflows/SQL Prompt.json +++ b/packages/server/marketplaces/chatflows/SQL Prompt.json @@ -173,7 +173,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -196,6 +196,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -363,7 +371,7 @@ "data": { "id": "chatOpenAI_1", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -386,6 +394,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -1279,7 +1295,7 @@ "data": { "id": "chatOpenAI_2", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -1302,6 +1318,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" diff --git a/packages/server/marketplaces/chatflows/Simple Conversation Chain.json b/packages/server/marketplaces/chatflows/Simple Conversation Chain.json index 9689bf8c..1ffbee44 100644 --- a/packages/server/marketplaces/chatflows/Simple Conversation Chain.json +++ b/packages/server/marketplaces/chatflows/Simple Conversation Chain.json @@ -14,7 +14,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -37,6 +37,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -261,7 +269,7 @@ "data": { "id": "conversationChain_0", "label": "Conversation Chain", - "version": 2, + "version": 3, "name": "conversationChain", "type": "ConversationChain", "baseClasses": ["ConversationChain", "LLMChain", "BaseChain", "Runnable"], @@ -301,9 +309,19 @@ "description": "Override existing prompt with Chat Prompt Template. Human Message must includes {input} variable", "optional": true, "id": "conversationChain_0-input-chatPromptTemplate-ChatPromptTemplate" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "conversationChain_0-input-inputModeration-Moderation" } ], "inputs": { + "inputModeration": "", "model": "{{chatOpenAI_0.data.instance}}", "memory": "{{bufferMemory_0.data.instance}}", "chatPromptTemplate": "", diff --git a/packages/server/marketplaces/chatflows/Simple LLM Chain.json b/packages/server/marketplaces/chatflows/Simple LLM Chain.json index b07124c0..f2e3a4a2 100644 --- a/packages/server/marketplaces/chatflows/Simple LLM Chain.json +++ b/packages/server/marketplaces/chatflows/Simple LLM Chain.json @@ -268,13 +268,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{openAI_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/Structured Output Parser.json b/packages/server/marketplaces/chatflows/Structured Output Parser.json index 77a8bbfd..92336443 100644 --- a/packages/server/marketplaces/chatflows/Structured Output Parser.json +++ b/packages/server/marketplaces/chatflows/Structured Output Parser.json @@ -14,7 +14,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -37,6 +37,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -53,6 +69,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -227,13 +247,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{chatPromptTemplate_0.data.instance}}", "outputParser": "{{structuredOutputParser_0.data.instance}}", - "chainName": "" + "chainName": "", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/Translator.json b/packages/server/marketplaces/chatflows/Translator.json index f1fa0764..0bf49252 100644 --- a/packages/server/marketplaces/chatflows/Translator.json +++ b/packages/server/marketplaces/chatflows/Translator.json @@ -82,7 +82,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -105,6 +105,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -121,6 +137,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -288,13 +308,23 @@ "type": "BaseLLMOutputParser", "optional": true, "id": "llmChain_0-input-outputParser-BaseLLMOutputParser" + }, + { + "label": "Input Moderation", + "description": "Detect text that could generate harmful output and prevent it from being sent to the language model", + "name": "inputModeration", + "type": "Moderation", + "optional": true, + "list": true, + "id": "llmChain_0-input-inputModeration-Moderation" } ], "inputs": { "model": "{{chatOpenAI_0.data.instance}}", "prompt": "{{chatPromptTemplate_0.data.instance}}", "outputParser": "", - "chainName": "Language Translation" + "chainName": "Language Translation", + "inputModeration": "" }, "outputAnchors": [ { diff --git a/packages/server/marketplaces/chatflows/WebBrowser.json b/packages/server/marketplaces/chatflows/WebBrowser.json index d905b54b..2376e29e 100644 --- a/packages/server/marketplaces/chatflows/WebBrowser.json +++ b/packages/server/marketplaces/chatflows/WebBrowser.json @@ -125,7 +125,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -148,6 +148,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -164,6 +180,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" @@ -296,7 +316,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -310,6 +330,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -348,7 +390,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -380,7 +423,7 @@ "data": { "id": "chatOpenAI_1", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"], @@ -403,6 +446,22 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, + { + "label": "gpt-4-1106-preview", + "name": "gpt-4-1106-preview" + }, + { + "label": "gpt-4-vision-preview", + "name": "gpt-4-vision-preview" + }, { "label": "gpt-4-0613", "name": "gpt-4-0613" @@ -419,6 +478,10 @@ "label": "gpt-3.5-turbo", "name": "gpt-3.5-turbo" }, + { + "label": "gpt-3.5-turbo-1106", + "name": "gpt-3.5-turbo-1106" + }, { "label": "gpt-3.5-turbo-0613", "name": "gpt-3.5-turbo-0613" diff --git a/packages/server/marketplaces/chatflows/WebPage QnA.json b/packages/server/marketplaces/chatflows/WebPage QnA.json index df05feef..a5a53233 100644 --- a/packages/server/marketplaces/chatflows/WebPage QnA.json +++ b/packages/server/marketplaces/chatflows/WebPage QnA.json @@ -14,7 +14,7 @@ "data": { "id": "openAIEmbeddings_0", "label": "OpenAI Embeddings", - "version": 1, + "version": 2, "name": "openAIEmbeddings", "type": "OpenAIEmbeddings", "baseClasses": ["OpenAIEmbeddings", "Embeddings"], @@ -28,6 +28,28 @@ "credentialNames": ["openAIApi"], "id": "openAIEmbeddings_0-input-credential-credential" }, + { + "label": "Model Name", + "name": "modelName", + "type": "options", + "options": [ + { + "label": "text-embedding-3-large", + "name": "text-embedding-3-large" + }, + { + "label": "text-embedding-3-small", + "name": "text-embedding-3-small" + }, + { + "label": "text-embedding-ada-002", + "name": "text-embedding-ada-002" + } + ], + "default": "text-embedding-ada-002", + "optional": true, + "id": "openAIEmbeddings_0-input-modelName-options" + }, { "label": "Strip New Lines", "name": "stripNewLines", @@ -66,7 +88,8 @@ "stripNewLines": "", "batchSize": "", "timeout": "", - "basepath": "" + "basepath": "", + "modelName": "text-embedding-ada-002" }, "outputAnchors": [ { @@ -369,7 +392,7 @@ "data": { "id": "chatOpenAI_0", "label": "ChatOpenAI", - "version": 2, + "version": 3, "name": "chatOpenAI", "type": "ChatOpenAI", "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "Runnable"], @@ -392,6 +415,14 @@ "label": "gpt-4", "name": "gpt-4" }, + { + "label": "gpt-4-turbo-preview", + "name": "gpt-4-turbo-preview" + }, + { + "label": "gpt-4-0125-preview", + "name": "gpt-4-0125-preview" + }, { "label": "gpt-4-1106-preview", "name": "gpt-4-1106-preview" @@ -638,7 +669,7 @@ "data": { "id": "pinecone_0", "label": "Pinecone", - "version": 1, + "version": 3, "name": "pinecone", "type": "Pinecone", "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"], diff --git a/packages/server/src/DataSource.ts b/packages/server/src/DataSource.ts index 762315ac..83a7fa2c 100644 --- a/packages/server/src/DataSource.ts +++ b/packages/server/src/DataSource.ts @@ -1,5 +1,6 @@ import 'reflect-metadata' import path from 'path' +import * as fs from 'fs' import { DataSource } from 'typeorm' import { getUserHome } from './utils' import { entities } from './database/entities' @@ -11,9 +12,13 @@ let appDataSource: DataSource export const init = async (): Promise => { let homePath + let flowisePath = path.join(getUserHome(), '.flowise') + if (!fs.existsSync(flowisePath)) { + fs.mkdirSync(flowisePath) + } switch (process.env.DATABASE_TYPE) { case 'sqlite': - homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise') + homePath = process.env.DATABASE_PATH ?? flowisePath appDataSource = new DataSource({ type: 'sqlite', database: path.resolve(homePath, 'database.sqlite'), @@ -46,7 +51,18 @@ export const init = async (): Promise => { username: process.env.DATABASE_USER, password: process.env.DATABASE_PASSWORD, database: process.env.DATABASE_NAME, - ssl: process.env.DATABASE_SSL === 'true', + ...(process.env.DATABASE_SSL_KEY_BASE64 + ? { + ssl: { + rejectUnauthorized: false, + cert: Buffer.from(process.env.DATABASE_SSL_KEY_BASE64, 'base64') + } + } + : process.env.DATABASE_SSL === 'true' + ? { + ssl: true + } + : {}), synchronize: false, migrationsRun: false, entities: Object.values(entities), @@ -54,7 +70,7 @@ export const init = async (): Promise => { }) break default: - homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise') + homePath = process.env.DATABASE_PATH ?? flowisePath appDataSource = new DataSource({ type: 'sqlite', database: path.resolve(homePath, 'database.sqlite'), diff --git a/packages/server/src/commands/start.ts b/packages/server/src/commands/start.ts index 08cd8298..dfb20766 100644 --- a/packages/server/src/commands/start.ts +++ b/packages/server/src/commands/start.ts @@ -19,6 +19,8 @@ export default class Start extends Command { FLOWISE_USERNAME: Flags.string(), FLOWISE_PASSWORD: Flags.string(), PORT: Flags.string(), + CORS_ORIGINS: Flags.string(), + IFRAME_ORIGINS: Flags.string(), DEBUG: Flags.string(), APIKEY_PATH: Flags.string(), SECRETKEY_PATH: Flags.string(), @@ -36,6 +38,7 @@ export default class Start extends Command { DATABASE_USER: Flags.string(), DATABASE_PASSWORD: Flags.string(), DATABASE_SSL: Flags.string(), + DATABASE_SSL_KEY_BASE64: Flags.string(), LANGCHAIN_TRACING_V2: Flags.string(), LANGCHAIN_ENDPOINT: Flags.string(), LANGCHAIN_API_KEY: Flags.string(), @@ -78,6 +81,8 @@ export default class Start extends Command { const { flags } = await this.parse(Start) if (flags.PORT) process.env.PORT = flags.PORT + if (flags.CORS_ORIGINS) process.env.CORS_ORIGINS = flags.CORS_ORIGINS + if (flags.IFRAME_ORIGINS) process.env.IFRAME_ORIGINS = flags.IFRAME_ORIGINS if (flags.DEBUG) process.env.DEBUG = flags.DEBUG if (flags.NUMBER_OF_PROXIES) process.env.NUMBER_OF_PROXIES = flags.NUMBER_OF_PROXIES @@ -107,6 +112,7 @@ export default class Start extends Command { if (flags.DATABASE_USER) process.env.DATABASE_USER = flags.DATABASE_USER if (flags.DATABASE_PASSWORD) process.env.DATABASE_PASSWORD = flags.DATABASE_PASSWORD if (flags.DATABASE_SSL) process.env.DATABASE_SSL = flags.DATABASE_SSL + if (flags.DATABASE_SSL_KEY_BASE64) process.env.DATABASE_SSL_KEY_BASE64 = flags.DATABASE_SSL_KEY_BASE64 // Langsmith tracing if (flags.LANGCHAIN_TRACING_V2) process.env.LANGCHAIN_TRACING_V2 = flags.LANGCHAIN_TRACING_V2 diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index b8ebd5f7..045e40dd 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -62,7 +62,7 @@ import { CachePool } from './CachePool' import { ICommonObject, IMessage, INodeOptionsValue, handleEscapeCharacters, webCrawl, xmlScrape } from 'flowise-components' import { createRateLimiter, getRateLimiter, initializeRateLimiter } from './utils/rateLimit' import { addAPIKey, compareKeys, deleteAPIKey, getApiKey, getAPIKeys, updateAPIKey } from './utils/apiKey' -import { sanitizeMiddleware } from './utils/XSS' +import { sanitizeMiddleware, getCorsOptions, getAllowedIframeOrigins } from './utils/XSS' import axios from 'axios' import { Client } from 'langchainhub' import { parsePrompt } from './utils/hub' @@ -126,8 +126,20 @@ export class App { if (process.env.NUMBER_OF_PROXIES && parseInt(process.env.NUMBER_OF_PROXIES) > 0) this.app.set('trust proxy', parseInt(process.env.NUMBER_OF_PROXIES)) - // Allow access from * - this.app.use(cors()) + // Allow access from specified domains + this.app.use(cors(getCorsOptions())) + + // Allow embedding from specified domains. + this.app.use((req, res, next) => { + const allowedOrigins = getAllowedIframeOrigins() + if (allowedOrigins == '*') { + next() + } else { + const csp = `frame-ancestors ${allowedOrigins}` + res.setHeader('Content-Security-Policy', csp) + next() + } + }) // Switch off the default 'X-Powered-By: Express' header this.app.disable('x-powered-by') @@ -461,6 +473,8 @@ export class App { const endingNodes = nodes.filter((nd) => endingNodeIds.includes(nd.id)) let isStreaming = false + let isEndingNodeExists = endingNodes.find((node) => node.data?.outputs?.output === 'EndingNode') + for (const endingNode of endingNodes) { const endingNodeData = endingNode.data if (!endingNodeData) return res.status(500).send(`Ending node ${endingNode.id} data not found`) @@ -476,7 +490,8 @@ export class App { isStreaming = isEndingNode ? false : isFlowValidForStream(nodes, endingNodeData) } - const obj = { isStreaming } + // Once custom function ending node exists, flow is always unavailable to stream + const obj = { isStreaming: isEndingNodeExists ? false : isStreaming } return res.json(obj) }) @@ -1665,6 +1680,9 @@ export class App { if (!endingNodeIds.length) return res.status(500).send(`Ending nodes not found`) const endingNodes = nodes.filter((nd) => endingNodeIds.includes(nd.id)) + + let isEndingNodeExists = endingNodes.find((node) => node.data?.outputs?.output === 'EndingNode') + for (const endingNode of endingNodes) { const endingNodeData = endingNode.data if (!endingNodeData) return res.status(500).send(`Ending node ${endingNode.id} data not found`) @@ -1692,6 +1710,9 @@ export class App { isStreamValid = isFlowValidForStream(nodes, endingNodeData) } + // Once custom function ending node exists, flow is always unavailable to stream + isStreamValid = isEndingNodeExists ? false : isStreamValid + let chatHistory: IMessage[] = incomingInput.history ?? [] // When {{chat_history}} is used in Prompt Template, fetch the chat conversations from memory node @@ -1883,9 +1904,7 @@ export async function start(): Promise { const server = http.createServer(serverApp.app) const io = new Server(server, { - cors: { - origin: '*' - } + cors: getCorsOptions() }) await serverApp.initDatabase() diff --git a/packages/server/src/utils/XSS.ts b/packages/server/src/utils/XSS.ts index 5d8b81e9..96bbab57 100644 --- a/packages/server/src/utils/XSS.ts +++ b/packages/server/src/utils/XSS.ts @@ -18,3 +18,28 @@ export function sanitizeMiddleware(req: Request, res: Response, next: NextFuncti } next() } + +export function getAllowedCorsOrigins(): string { + // Expects FQDN separated by commas, otherwise nothing or * for all. + return process.env.CORS_ORIGINS ?? '*' +} + +export function getCorsOptions(): any { + const corsOptions = { + origin: function (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) { + const allowedOrigins = getAllowedCorsOrigins() + if (!origin || allowedOrigins == '*' || allowedOrigins.indexOf(origin) !== -1) { + callback(null, true) + } else { + callback(null, false) + } + } + } + return corsOptions +} + +export function getAllowedIframeOrigins(): string { + // Expects FQDN separated by commas, otherwise nothing or * for all. + // Also CSP allowed values: self or none + return process.env.IFRAME_ORIGINS ?? '*' +} diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index aa3e9ef6..2d3f000a 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -611,28 +611,35 @@ export const resolveVariables = ( export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig: ICommonObject) => { const types = 'inputs' - const getParamValues = (paramsObj: ICommonObject) => { + const getParamValues = (inputsObj: ICommonObject) => { for (const config in overrideConfig) { // If overrideConfig[key] is object if (overrideConfig[config] && typeof overrideConfig[config] === 'object') { const nodeIds = Object.keys(overrideConfig[config]) if (nodeIds.includes(flowNodeData.id)) { - paramsObj[config] = overrideConfig[config][flowNodeData.id] + inputsObj[config] = overrideConfig[config][flowNodeData.id] + continue + } else if (nodeIds.some((nodeId) => nodeId.includes(flowNodeData.name))) { + /* + * "systemMessagePrompt": { + * "chatPromptTemplate_0": "You are an assistant" <---- continue for loop if current node is chatPromptTemplate_1 + * } + */ continue } } - let paramValue = overrideConfig[config] ?? paramsObj[config] + let paramValue = overrideConfig[config] ?? inputsObj[config] // Check if boolean if (paramValue === 'true') paramValue = true else if (paramValue === 'false') paramValue = false - paramsObj[config] = paramValue + inputsObj[config] = paramValue } } - const paramsObj = flowNodeData[types] ?? {} + const inputsObj = flowNodeData[types] ?? {} - getParamValues(paramsObj) + getParamValues(inputsObj) return flowNodeData }