mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-29 09:01:06 +03:00
Merge branch 'main' into feature/FlowiseMultiDatabaseSupport
This commit is contained in:
@@ -128,19 +128,21 @@ FLOWISE_PASSWORD=1234
|
|||||||
|
|
||||||
## 🌱 Env Variables
|
## 🌱 Env Variables
|
||||||
|
|
||||||
Flowise support different environment variables to configure your instance. You can specify the following variables in the `.env` file inside `packages/server` folder.
|
Flowise support different environment variables to configure your instance. You can specify the following variables in the `.env` file inside `packages/server` folder. Read [more](https://docs.flowiseai.com/environment-variables)
|
||||||
|
|
||||||
| Variable | Description | Type | Default |
|
| Variable | Description | Type | Default |
|
||||||
| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
| -------------------------- | ---------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||||
| PORT | The HTTP port Flowise runs on | Number | 3000 |
|
| PORT | The HTTP port Flowise runs on | Number | 3000 |
|
||||||
| FLOWISE_USERNAME | Username to login | String |
|
| FLOWISE_USERNAME | Username to login | String |
|
||||||
| FLOWISE_PASSWORD | Password to login | String |
|
| FLOWISE_PASSWORD | Password to login | String |
|
||||||
| DEBUG | Print logs from components | Boolean |
|
| DEBUG | Print logs onto terminal/console | Boolean |
|
||||||
| LOG_PATH | Location where log files are stored | String | `your-path/Flowise/logs` |
|
| LOG_PATH | Location where log files are stored | String | `your-path/Flowise/packages/server` |
|
||||||
| LOG_LEVEL | Different levels of logs | Enum String: `error`, `info`, `verbose`, `debug` | `info` |
|
| LOG_LEVEL | Different log levels for loggers to be saved | Enum String: `error`, `info`, `verbose`, `debug` | `info` |
|
||||||
| DATABASE_PATH | Location where database is saved | String | `your-home-dir/.flowise` |
|
| DATABASE_PATH | Location where database is saved | String | `your-home-dir/.flowise` |
|
||||||
| APIKEY_PATH | Location where api keys are saved | String | `your-path/Flowise/packages/server` |
|
| APIKEY_PATH | Location where api keys are saved | String | `your-path/Flowise/packages/server` |
|
||||||
| EXECUTION_MODE | Whether predictions run in their own process or the main process | Enum String: `child`, `main` | `main` |
|
| EXECUTION_MODE | Whether predictions run in their own process or the main process | Enum String: `child`, `main` | `main` |
|
||||||
|
| TOOL_FUNCTION_BUILTIN_DEP | NodeJS built-in modules to be used for Tool Function | String | |
|
||||||
|
| TOOL_FUNCTION_EXTERNAL_DEP | External modules to be used for Tool Function | String | |
|
||||||
|
|
||||||
You can also specify the env variables when using `npx`. For example:
|
You can also specify the env variables when using `npx`. For example:
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -1,8 +1,11 @@
|
|||||||
PORT=3000
|
PORT=3000
|
||||||
|
DATABASE_PATH=/root/.flowise
|
||||||
|
APIKEY_PATH=/root/.flowise
|
||||||
|
LOG_PATH=/root/.flowise/logs
|
||||||
# FLOWISE_USERNAME=user
|
# FLOWISE_USERNAME=user
|
||||||
# FLOWISE_PASSWORD=1234
|
# FLOWISE_PASSWORD=1234
|
||||||
# DEBUG=true
|
# DEBUG=true
|
||||||
# DATABASE_PATH=/your_database_path/.flowise
|
# LOG_LEVEL=debug (error | warn | info | verbose | debug)
|
||||||
# APIKEY_PATH=/your_api_key_path/.flowise
|
|
||||||
# LOG_PATH=/your_log_path/logs
|
|
||||||
# EXECUTION_MODE=child or main
|
# EXECUTION_MODE=child or main
|
||||||
|
# TOOL_FUNCTION_BUILTIN_DEP=crypto,fs
|
||||||
|
# TOOL_FUNCTION_EXTERNAL_DEP=moment,lodash
|
||||||
+25
-1
@@ -9,7 +9,7 @@ Starts Flowise from [DockerHub Image](https://hub.docker.com/repository/docker/f
|
|||||||
3. Open [http://localhost:3000](http://localhost:3000)
|
3. Open [http://localhost:3000](http://localhost:3000)
|
||||||
4. You can bring the containers down by `docker-compose stop`
|
4. You can bring the containers down by `docker-compose stop`
|
||||||
|
|
||||||
## With Authrorization
|
## 🔒 Authrorization
|
||||||
|
|
||||||
1. Create `.env` file and specify the `PORT`, `FLOWISE_USERNAME`, and `FLOWISE_PASSWORD` (refer to `.env.example`)
|
1. Create `.env` file and specify the `PORT`, `FLOWISE_USERNAME`, and `FLOWISE_PASSWORD` (refer to `.env.example`)
|
||||||
2. Pass `FLOWISE_USERNAME` and `FLOWISE_PASSWORD` to the `docker-compose.yml` file:
|
2. Pass `FLOWISE_USERNAME` and `FLOWISE_PASSWORD` to the `docker-compose.yml` file:
|
||||||
@@ -22,3 +22,27 @@ Starts Flowise from [DockerHub Image](https://hub.docker.com/repository/docker/f
|
|||||||
3. `docker-compose up -d`
|
3. `docker-compose up -d`
|
||||||
4. Open [http://localhost:3000](http://localhost:3000)
|
4. Open [http://localhost:3000](http://localhost:3000)
|
||||||
5. You can bring the containers down by `docker-compose stop`
|
5. You can bring the containers down by `docker-compose stop`
|
||||||
|
|
||||||
|
## 🌱 Env Variables
|
||||||
|
|
||||||
|
If you like to persist your data (flows, logs, apikeys), set these variables in the `.env` file inside `docker` folder:
|
||||||
|
|
||||||
|
- DATABASE_PATH=/root/.flowise
|
||||||
|
- APIKEY_PATH=/root/.flowise
|
||||||
|
- LOG_PATH=/root/.flowise/logs
|
||||||
|
|
||||||
|
Flowise also support different environment variables to configure your instance. Read [more](https://docs.flowiseai.com/environment-variables)
|
||||||
|
|
||||||
|
| Variable | Description | Type | Default |
|
||||||
|
| -------------------------- | ---------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||||
|
| PORT | The HTTP port Flowise runs on | Number | 3000 |
|
||||||
|
| FLOWISE_USERNAME | Username to login | String |
|
||||||
|
| FLOWISE_PASSWORD | Password to login | String |
|
||||||
|
| DEBUG | Print logs onto terminal/console | Boolean |
|
||||||
|
| LOG_PATH | Location where log files are stored | String | `your-path/Flowise/packages/server` |
|
||||||
|
| LOG_LEVEL | Different log levels for loggers to be saved | Enum String: `error`, `info`, `verbose`, `debug` | `info` |
|
||||||
|
| DATABASE_PATH | Location where database is saved | String | `your-home-dir/.flowise` |
|
||||||
|
| APIKEY_PATH | Location where api keys are saved | String | `your-path/Flowise/packages/server` |
|
||||||
|
| EXECUTION_MODE | Whether predictions run in their own process or the main process | Enum String: `child`, `main` | `main` |
|
||||||
|
| TOOL_FUNCTION_BUILTIN_DEP | NodeJS built-in modules to be used for Tool Function | String | |
|
||||||
|
| TOOL_FUNCTION_EXTERNAL_DEP | External modules to be used for Tool Function | String | |
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ services:
|
|||||||
- PORT=${PORT}
|
- PORT=${PORT}
|
||||||
- FLOWISE_USERNAME=${FLOWISE_USERNAME}
|
- FLOWISE_USERNAME=${FLOWISE_USERNAME}
|
||||||
- FLOWISE_PASSWORD=${FLOWISE_PASSWORD}
|
- FLOWISE_PASSWORD=${FLOWISE_PASSWORD}
|
||||||
|
- DEBUG=${DEBUG}
|
||||||
- DATABASE_PATH=${DATABASE_PATH}
|
- DATABASE_PATH=${DATABASE_PATH}
|
||||||
- APIKEY_PATH=${APIKEY_PATH}
|
- APIKEY_PATH=${APIKEY_PATH}
|
||||||
- LOG_PATH=${LOG_PATH}
|
- LOG_PATH=${LOG_PATH}
|
||||||
|
- LOG_LEVEL=${LOG_LEVEL}
|
||||||
- EXECUTION_MODE=${EXECUTION_MODE}
|
- EXECUTION_MODE=${EXECUTION_MODE}
|
||||||
- DEBUG=${DEBUG}
|
|
||||||
ports:
|
ports:
|
||||||
- '${PORT}:${PORT}'
|
- '${PORT}:${PORT}'
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
+2
-2
@@ -7,14 +7,14 @@ import { BaseChatMemory, BufferMemory, ChatMessageHistory } from 'langchain/memo
|
|||||||
import { PromptTemplate } from 'langchain/prompts'
|
import { PromptTemplate } from 'langchain/prompts'
|
||||||
import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
|
import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
|
||||||
|
|
||||||
const default_qa_template = `Use the following pieces of context to answer the question at the end, in its original language. If you don't know the answer, just say that you don't know in its original language, don't try to make up an answer.
|
const default_qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
||||||
|
|
||||||
{context}
|
{context}
|
||||||
|
|
||||||
Question: {question}
|
Question: {question}
|
||||||
Helpful Answer:`
|
Helpful Answer:`
|
||||||
|
|
||||||
const qa_template = `Use the following pieces of context to answer the question at the end, in its original language.
|
const qa_template = `Use the following pieces of context to answer the question at the end.
|
||||||
|
|
||||||
{context}
|
{context}
|
||||||
|
|
||||||
|
|||||||
@@ -65,37 +65,47 @@ class DynamoDb_Memory implements INode {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
const tableName = nodeData.inputs?.tableName as string
|
return initalizeDynamoDB(nodeData, options)
|
||||||
const partitionKey = nodeData.inputs?.partitionKey as string
|
}
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
|
||||||
const region = nodeData.inputs?.region as string
|
|
||||||
const accessKey = nodeData.inputs?.accessKey as string
|
|
||||||
const secretAccessKey = nodeData.inputs?.secretAccessKey as string
|
|
||||||
const memoryKey = nodeData.inputs?.memoryKey as string
|
|
||||||
|
|
||||||
const chatId = options.chatId
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const dynamodbMemory = initalizeDynamoDB(nodeData, options)
|
||||||
const dynamoDb = new DynamoDBChatMessageHistory({
|
dynamodbMemory.clear()
|
||||||
tableName,
|
|
||||||
partitionKey,
|
|
||||||
sessionId: sessionId ? sessionId : chatId,
|
|
||||||
config: {
|
|
||||||
region,
|
|
||||||
credentials: {
|
|
||||||
accessKeyId: accessKey,
|
|
||||||
secretAccessKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const memory = new BufferMemory({
|
|
||||||
memoryKey,
|
|
||||||
chatHistory: dynamoDb,
|
|
||||||
returnMessages: true
|
|
||||||
})
|
|
||||||
return memory
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initalizeDynamoDB = (nodeData: INodeData, options: ICommonObject): BufferMemory => {
|
||||||
|
const tableName = nodeData.inputs?.tableName as string
|
||||||
|
const partitionKey = nodeData.inputs?.partitionKey as string
|
||||||
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
const region = nodeData.inputs?.region as string
|
||||||
|
const accessKey = nodeData.inputs?.accessKey as string
|
||||||
|
const secretAccessKey = nodeData.inputs?.secretAccessKey as string
|
||||||
|
const memoryKey = nodeData.inputs?.memoryKey as string
|
||||||
|
|
||||||
|
const chatId = options.chatId
|
||||||
|
|
||||||
|
const dynamoDb = new DynamoDBChatMessageHistory({
|
||||||
|
tableName,
|
||||||
|
partitionKey,
|
||||||
|
sessionId: sessionId ? sessionId : chatId,
|
||||||
|
config: {
|
||||||
|
region,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: accessKey,
|
||||||
|
secretAccessKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const memory = new BufferMemory({
|
||||||
|
memoryKey,
|
||||||
|
chatHistory: dynamoDb,
|
||||||
|
returnMessages: true
|
||||||
|
})
|
||||||
|
return memory
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { nodeClass: DynamoDb_Memory }
|
module.exports = { nodeClass: DynamoDb_Memory }
|
||||||
|
|||||||
@@ -64,35 +64,44 @@ class MotorMemory_Memory implements INode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
const memoryKey = nodeData.inputs?.memoryKey as string
|
return initalizeMotorhead(nodeData, options)
|
||||||
const baseURL = nodeData.inputs?.baseURL as string
|
}
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
|
||||||
const apiKey = nodeData.inputs?.apiKey as string
|
|
||||||
const clientId = nodeData.inputs?.clientId as string
|
|
||||||
|
|
||||||
const chatId = options?.chatId as string
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const motorhead = initalizeMotorhead(nodeData, options)
|
||||||
let obj: MotorheadMemoryInput = {
|
motorhead.clear()
|
||||||
returnMessages: true,
|
|
||||||
sessionId: sessionId ? sessionId : chatId,
|
|
||||||
memoryKey
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseURL) {
|
|
||||||
obj = {
|
|
||||||
...obj,
|
|
||||||
url: baseURL
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
obj = {
|
|
||||||
...obj,
|
|
||||||
apiKey,
|
|
||||||
clientId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MotorheadMemory(obj)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initalizeMotorhead = (nodeData: INodeData, options: ICommonObject): MotorheadMemory => {
|
||||||
|
const memoryKey = nodeData.inputs?.memoryKey as string
|
||||||
|
const baseURL = nodeData.inputs?.baseURL as string
|
||||||
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
const apiKey = nodeData.inputs?.apiKey as string
|
||||||
|
const clientId = nodeData.inputs?.clientId as string
|
||||||
|
|
||||||
|
const chatId = options?.chatId as string
|
||||||
|
|
||||||
|
let obj: MotorheadMemoryInput = {
|
||||||
|
returnMessages: true,
|
||||||
|
sessionId: sessionId ? sessionId : chatId,
|
||||||
|
memoryKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseURL) {
|
||||||
|
obj = {
|
||||||
|
...obj,
|
||||||
|
url: baseURL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
obj = {
|
||||||
|
...obj,
|
||||||
|
apiKey,
|
||||||
|
clientId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MotorheadMemory(obj)
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { nodeClass: MotorMemory_Memory }
|
module.exports = { nodeClass: MotorMemory_Memory }
|
||||||
|
|||||||
@@ -56,31 +56,40 @@ class RedisBackedChatMemory_Memory implements INode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
const baseURL = nodeData.inputs?.baseURL as string
|
return initalizeRedis(nodeData, options)
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
}
|
||||||
const sessionTTL = nodeData.inputs?.sessionTTL as number
|
|
||||||
const memoryKey = nodeData.inputs?.memoryKey as string
|
|
||||||
|
|
||||||
const chatId = options?.chatId as string
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const redis = initalizeRedis(nodeData, options)
|
||||||
const redisClient = createClient({ url: baseURL })
|
redis.clear()
|
||||||
let obj: RedisChatMessageHistoryInput = {
|
|
||||||
sessionId: sessionId ? sessionId : chatId,
|
|
||||||
client: redisClient
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessionTTL) {
|
|
||||||
obj = {
|
|
||||||
...obj,
|
|
||||||
sessionTTL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let redisChatMessageHistory = new RedisChatMessageHistory(obj)
|
|
||||||
let redis = new BufferMemory({ memoryKey, chatHistory: redisChatMessageHistory, returnMessages: true })
|
|
||||||
|
|
||||||
return redis
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initalizeRedis = (nodeData: INodeData, options: ICommonObject): BufferMemory => {
|
||||||
|
const baseURL = nodeData.inputs?.baseURL as string
|
||||||
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
const sessionTTL = nodeData.inputs?.sessionTTL as number
|
||||||
|
const memoryKey = nodeData.inputs?.memoryKey as string
|
||||||
|
|
||||||
|
const chatId = options?.chatId as string
|
||||||
|
|
||||||
|
const redisClient = createClient({ url: baseURL })
|
||||||
|
let obj: RedisChatMessageHistoryInput = {
|
||||||
|
sessionId: sessionId ? sessionId : chatId,
|
||||||
|
client: redisClient
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionTTL) {
|
||||||
|
obj = {
|
||||||
|
...obj,
|
||||||
|
sessionTTL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let redisChatMessageHistory = new RedisChatMessageHistory(obj)
|
||||||
|
let redis = new BufferMemory({ memoryKey, chatHistory: redisChatMessageHistory, returnMessages: true })
|
||||||
|
|
||||||
|
return redis
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { nodeClass: RedisBackedChatMemory_Memory }
|
module.exports = { nodeClass: RedisBackedChatMemory_Memory }
|
||||||
|
|||||||
@@ -104,31 +104,11 @@ class ZepMemory_Memory implements INode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
const baseURL = nodeData.inputs?.baseURL as string
|
|
||||||
const aiPrefix = nodeData.inputs?.aiPrefix as string
|
|
||||||
const humanPrefix = nodeData.inputs?.humanPrefix as string
|
|
||||||
const memoryKey = nodeData.inputs?.memoryKey as string
|
|
||||||
const inputKey = nodeData.inputs?.inputKey as string
|
|
||||||
const autoSummaryTemplate = nodeData.inputs?.autoSummaryTemplate as string
|
const autoSummaryTemplate = nodeData.inputs?.autoSummaryTemplate as string
|
||||||
const autoSummary = nodeData.inputs?.autoSummary as boolean
|
const autoSummary = nodeData.inputs?.autoSummary as boolean
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
|
||||||
const apiKey = nodeData.inputs?.apiKey as string
|
|
||||||
const k = nodeData.inputs?.k as string
|
const k = nodeData.inputs?.k as string
|
||||||
|
|
||||||
const chatId = options?.chatId as string
|
let zep = initalizeZep(nodeData, options)
|
||||||
|
|
||||||
const obj: ZepMemoryInput = {
|
|
||||||
baseURL,
|
|
||||||
sessionId: sessionId ? sessionId : chatId,
|
|
||||||
aiPrefix,
|
|
||||||
humanPrefix,
|
|
||||||
returnMessages: true,
|
|
||||||
memoryKey,
|
|
||||||
inputKey
|
|
||||||
}
|
|
||||||
if (apiKey) obj.apiKey = apiKey
|
|
||||||
|
|
||||||
let zep = new ZepMemory(obj)
|
|
||||||
|
|
||||||
// hack to support summary
|
// hack to support summary
|
||||||
let tmpFunc = zep.loadMemoryVariables
|
let tmpFunc = zep.loadMemoryVariables
|
||||||
@@ -153,6 +133,37 @@ class ZepMemory_Memory implements INode {
|
|||||||
}
|
}
|
||||||
return zep
|
return zep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const zep = initalizeZep(nodeData, options)
|
||||||
|
zep.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initalizeZep = (nodeData: INodeData, options: ICommonObject) => {
|
||||||
|
const baseURL = nodeData.inputs?.baseURL as string
|
||||||
|
const aiPrefix = nodeData.inputs?.aiPrefix as string
|
||||||
|
const humanPrefix = nodeData.inputs?.humanPrefix as string
|
||||||
|
const memoryKey = nodeData.inputs?.memoryKey as string
|
||||||
|
const inputKey = nodeData.inputs?.inputKey as string
|
||||||
|
|
||||||
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
const apiKey = nodeData.inputs?.apiKey as string
|
||||||
|
|
||||||
|
const chatId = options?.chatId as string
|
||||||
|
|
||||||
|
const obj: ZepMemoryInput = {
|
||||||
|
baseURL,
|
||||||
|
sessionId: sessionId ? sessionId : chatId,
|
||||||
|
aiPrefix,
|
||||||
|
humanPrefix,
|
||||||
|
returnMessages: true,
|
||||||
|
memoryKey,
|
||||||
|
inputKey
|
||||||
|
}
|
||||||
|
if (apiKey) obj.apiKey = apiKey
|
||||||
|
|
||||||
|
return new ZepMemory(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { nodeClass: ZepMemory_Memory }
|
module.exports = { nodeClass: ZepMemory_Memory }
|
||||||
|
|||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
import { INode, INodeData, INodeParams } from '../../../src/Interface'
|
||||||
|
import { getBaseClasses } from '../../../src/utils'
|
||||||
|
import { MarkdownTextSplitter, MarkdownTextSplitterParams } from 'langchain/text_splitter'
|
||||||
|
import { NodeHtmlMarkdown } from 'node-html-markdown'
|
||||||
|
|
||||||
|
class HtmlToMarkdownTextSplitter_TextSplitters implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'HtmlToMarkdown Text Splitter'
|
||||||
|
this.name = 'htmlToMarkdownTextSplitter'
|
||||||
|
this.type = 'HtmlToMarkdownTextSplitter'
|
||||||
|
this.icon = 'htmlToMarkdownTextSplitter.svg'
|
||||||
|
this.category = 'Text Splitters'
|
||||||
|
this.description = `Converts Html to Markdown and then split your content into documents based on the Markdown headers`
|
||||||
|
this.baseClasses = [this.type, ...getBaseClasses(HtmlToMarkdownTextSplitter)]
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'Chunk Size',
|
||||||
|
name: 'chunkSize',
|
||||||
|
type: 'number',
|
||||||
|
default: 1000,
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Chunk Overlap',
|
||||||
|
name: 'chunkOverlap',
|
||||||
|
type: 'number',
|
||||||
|
optional: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(nodeData: INodeData): Promise<any> {
|
||||||
|
const chunkSize = nodeData.inputs?.chunkSize as string
|
||||||
|
const chunkOverlap = nodeData.inputs?.chunkOverlap as string
|
||||||
|
|
||||||
|
const obj = {} as MarkdownTextSplitterParams
|
||||||
|
|
||||||
|
if (chunkSize) obj.chunkSize = parseInt(chunkSize, 10)
|
||||||
|
if (chunkOverlap) obj.chunkOverlap = parseInt(chunkOverlap, 10)
|
||||||
|
|
||||||
|
const splitter = new HtmlToMarkdownTextSplitter(obj)
|
||||||
|
|
||||||
|
return splitter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class HtmlToMarkdownTextSplitter extends MarkdownTextSplitter implements MarkdownTextSplitterParams {
|
||||||
|
constructor(fields?: Partial<MarkdownTextSplitterParams>) {
|
||||||
|
{
|
||||||
|
super(fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
splitText(text: string): Promise<string[]> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const markdown = NodeHtmlMarkdown.translate(text)
|
||||||
|
super.splitText(markdown).then((result) => {
|
||||||
|
resolve(result)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = { nodeClass: HtmlToMarkdownTextSplitter_TextSplitters }
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-markdown" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
|
<path d="M3 5m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z"></path>
|
||||||
|
<path d="M7 15v-6l2 2l2 -2v6"></path>
|
||||||
|
<path d="M14 13l2 2l2 -2m-2 2v-6"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 482 B |
@@ -0,0 +1,38 @@
|
|||||||
|
import { INode, INodeData, INodeParams } from '../../../src/Interface'
|
||||||
|
import { getBaseClasses } from '../../../src/utils'
|
||||||
|
import { BraveSearch } from 'langchain/tools'
|
||||||
|
|
||||||
|
class BraveSearchAPI_Tools implements INode {
|
||||||
|
label: string
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
category: string
|
||||||
|
baseClasses: string[]
|
||||||
|
inputs: INodeParams[]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.label = 'BraveSearch API'
|
||||||
|
this.name = 'braveSearchAPI'
|
||||||
|
this.type = 'BraveSearchAPI'
|
||||||
|
this.icon = 'brave.svg'
|
||||||
|
this.category = 'Tools'
|
||||||
|
this.description = 'Wrapper around BraveSearch API - a real-time API to access Brave search results'
|
||||||
|
this.inputs = [
|
||||||
|
{
|
||||||
|
label: 'BraveSearch API Key',
|
||||||
|
name: 'apiKey',
|
||||||
|
type: 'password'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
this.baseClasses = [this.type, ...getBaseClasses(BraveSearch)]
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(nodeData: INodeData): Promise<any> {
|
||||||
|
const apiKey = nodeData.inputs?.apiKey as string
|
||||||
|
return new BraveSearch({ apiKey })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { nodeClass: BraveSearchAPI_Tools }
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><path fill="#ff651f" d="M41,13l1,4l-4.09,16.35c-0.59,2.35-2.01,4.41-4.01,5.79l-8.19,5.68c-0.51,0.36-1.11,0.53-1.71,0.53 c-0.6,0-1.2-0.17-1.71-0.53l-8.19-5.68c-2-1.38-3.42-3.44-4.01-5.79L6,17l1-4l-1-2l3.25-3.25c1.05-1.05,2.6-1.44,4.02-0.99 c0.04,0.01,0.07,0.02,0.1,0.03L14,7l4-4h12l4,4l0.65-0.22c0.83-0.28,1.7-0.27,2.5,0c0.58,0.19,1.13,0.51,1.58,0.95 c0.01,0.01,0.01,0.01,0.02,0.02L42,11L41,13z"/><path fill="#f4592b" d="M38.73,7.73L33,11l-9,2l-9-3l-2.07-2.07c-0.56-0.56-1.41-0.74-2.15-0.44L8.67,8.33l0.58-0.58 c1.05-1.05,2.6-1.44,4.02-0.99c0.04,0.01,0.07,0.02,0.1,0.03L14,7l4-4h12l4,4l0.65-0.22c0.83-0.28,1.7-0.27,2.5,0 C37.73,6.97,38.28,7.29,38.73,7.73z"/><path fill="#fff" d="M32.51,23.49c-0.3,0.3-0.38,0.77-0.19,1.15l0.34,0.68c0.22,0.45,0.34,0.94,0.34,1.44 c0,0.8-0.29,1.57-0.83,2.16l-0.66,0.74c-0.32,0.21-0.72,0.23-1.04,0.05l-5.23-2.88c-0.59-0.4-0.6-1.27-0.01-1.66l3.91-2.66 c0.48-0.28,0.63-0.89,0.35-1.37l-1.9-3.16C27.28,17.46,27.45,17.24,28,17l6-3h-5l-3,0.75c-0.55,0.14-0.87,0.7-0.72,1.24l1.46,5.09 c0.14,0.51-0.14,1.05-0.65,1.22l-1.47,0.49c-0.21,0.07-0.41,0.11-0.62,0.11c-0.21,0-0.42-0.04-0.63-0.11l-1.46-0.49 c-0.51-0.17-0.79-0.71-0.65-1.22l1.46-5.09c0.15-0.54-0.17-1.1-0.72-1.24L19,14h-5l6,3c0.55,0.24,0.72,0.46,0.41,0.98l-1.9,3.16 c-0.28,0.48-0.13,1.09,0.35,1.37l3.91,2.66c0.59,0.39,0.58,1.26-0.01,1.66l-5.23,2.88c-0.32,0.18-0.72,0.16-1.04-0.05l-0.66-0.74 C15.29,28.33,15,27.56,15,26.76c0-0.5,0.12-0.99,0.34-1.44l0.34-0.68c0.19-0.38,0.11-0.85-0.19-1.15l-4.09-4.83 c-0.83-0.99-0.94-2.41-0.26-3.51l3.4-5.54c0.27-0.36,0.75-0.49,1.17-0.33l2.62,1.05c0.48,0.19,0.99,0.29,1.49,0.29 c0.61,0,1.23-0.14,1.79-0.42c0.75-0.38,1.57-0.57,2.39-0.57s1.64,0.19,2.39,0.57c1.03,0.51,2.22,0.56,3.28,0.13l2.62-1.05 c0.42-0.16,0.9-0.03,1.17,0.33l3.4,5.54c0.68,1.1,0.57,2.52-0.26,3.51L32.51,23.49z"/><path fill="#fff" d="M29.51,32.49l-4.8,3.8c-0.19,0.19-0.45,0.29-0.71,0.29s-0.52-0.1-0.71-0.29l-4.8-3.8 c-0.24-0.24-0.17-0.65,0.13-0.8l4.93-2.47c0.14-0.07,0.29-0.1,0.45-0.1s0.31,0.03,0.45,0.1l4.93,2.47 C29.68,31.84,29.75,32.25,29.51,32.49z"/><path fill="#ed4d01" d="M41,13l1,4l-4.09,16.35c-0.59,2.35-2.01,4.41-4.01,5.79l-8.19,5.68c-0.51,0.36-1.11,0.53-1.71,0.53 V10.36L25,12h7v-2l5.15-3.22c0.59,0.19,1.15,0.52,1.6,0.97L42,11L41,13z"/><path fill="#f5f5f5" d="M32.51,23.49c-0.3,0.3-0.38,0.77-0.19,1.15l0.34,0.68c0.22,0.45,0.34,0.94,0.34,1.44 c0,0.8-0.29,1.57-0.83,2.16l-0.66,0.74c-0.32,0.21-0.72,0.23-1.04,0.05l-5.23-2.88c-0.59-0.4-0.6-1.27-0.01-1.66l3.91-2.66 c0.48-0.28,0.63-0.89,0.35-1.37l-1.9-3.16C27.28,17.46,27.45,17.24,28,17l6-3h-5l-3,0.75c-0.55,0.14-0.87,0.7-0.72,1.24l1.46,5.09 c0.14,0.51-0.14,1.05-0.65,1.22l-1.47,0.49c-0.21,0.07-0.41,0.11-0.62,0.11V9.63c0.82,0,1.64,0.19,2.39,0.57 c1.03,0.51,2.22,0.56,3.28,0.13l2.62-1.05c0.42-0.16,0.9-0.03,1.17,0.33l3.4,5.54c0.68,1.1,0.57,2.52-0.26,3.51L32.51,23.49z"/><path fill="#f5f5f5" d="M29.51,32.49l-4.8,3.8c-0.19,0.19-0.45,0.29-0.71,0.29v-7.46c0.16,0,0.31,0.03,0.45,0.1l4.93,2.47 C29.68,31.84,29.75,32.25,29.51,32.49z"/></svg>
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -51,25 +51,37 @@ export class DynamicStructuredTool<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultAllowBuiltInDep = [
|
||||||
|
'assert',
|
||||||
|
'buffer',
|
||||||
|
'crypto',
|
||||||
|
'events',
|
||||||
|
'http',
|
||||||
|
'https',
|
||||||
|
'net',
|
||||||
|
'path',
|
||||||
|
'querystring',
|
||||||
|
'timers',
|
||||||
|
'tls',
|
||||||
|
'url',
|
||||||
|
'zlib'
|
||||||
|
]
|
||||||
|
|
||||||
|
const builtinDeps = process.env.TOOL_FUNCTION_BUILTIN_DEP
|
||||||
|
? defaultAllowBuiltInDep.concat(process.env.TOOL_FUNCTION_BUILTIN_DEP.split(','))
|
||||||
|
: defaultAllowBuiltInDep
|
||||||
|
const externalDeps = process.env.TOOL_FUNCTION_EXTERNAL_DEP ? process.env.TOOL_FUNCTION_EXTERNAL_DEP.split(',') : []
|
||||||
|
const deps = availableDependencies.concat(externalDeps)
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
console: 'inherit',
|
console: 'inherit',
|
||||||
sandbox,
|
sandbox,
|
||||||
require: {
|
require: {
|
||||||
external: false as boolean | { modules: string[] },
|
external: { modules: deps },
|
||||||
builtin: ['*']
|
builtin: builtinDeps
|
||||||
}
|
}
|
||||||
} as any
|
} as any
|
||||||
|
|
||||||
const external = JSON.stringify(availableDependencies)
|
|
||||||
if (external) {
|
|
||||||
const deps = JSON.parse(external)
|
|
||||||
if (deps && deps.length) {
|
|
||||||
options.require.external = {
|
|
||||||
modules: deps
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const vm = new NodeVM(options)
|
const vm = new NodeVM(options)
|
||||||
const response = await vm.run(`module.exports = async function() {${this.code}}()`, __dirname)
|
const response = await vm.run(`module.exports = async function() {${this.code}}()`, __dirname)
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-dynamodb": "^3.360.0",
|
"@aws-sdk/client-dynamodb": "^3.360.0",
|
||||||
"@dqbd/tiktoken": "^1.0.7",
|
"@dqbd/tiktoken": "^1.0.7",
|
||||||
"@getzep/zep-js": "^0.3.1",
|
"@getzep/zep-js": "^0.4.1",
|
||||||
"@huggingface/inference": "^2.6.1",
|
"@huggingface/inference": "^2.6.1",
|
||||||
"@opensearch-project/opensearch": "^1.2.0",
|
"@opensearch-project/opensearch": "^1.2.0",
|
||||||
"@pinecone-database/pinecone": "^0.0.12",
|
"@pinecone-database/pinecone": "^0.0.12",
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
"mammoth": "^1.5.1",
|
"mammoth": "^1.5.1",
|
||||||
"moment": "^2.29.3",
|
"moment": "^2.29.3",
|
||||||
"node-fetch": "^2.6.11",
|
"node-fetch": "^2.6.11",
|
||||||
|
"node-html-markdown": "^1.3.0",
|
||||||
"pdf-parse": "^1.1.1",
|
"pdf-parse": "^1.1.1",
|
||||||
"pdfjs-dist": "^3.7.107",
|
"pdfjs-dist": "^3.7.107",
|
||||||
"playwright": "^1.35.0",
|
"playwright": "^1.35.0",
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ export interface INode extends INodeProperties {
|
|||||||
}
|
}
|
||||||
init?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<any>
|
init?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<any>
|
||||||
run?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<string | ICommonObject>
|
run?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<string | ICommonObject>
|
||||||
|
clearSessionMemory?(nodeData: INodeData, options?: ICommonObject): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INodeData extends INodeProperties {
|
export interface INodeData extends INodeProperties {
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ export async function xmlScrape(currentURL: string, limit: number): Promise<stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
const contentType: string | null = resp.headers.get('content-type')
|
const contentType: string | null = resp.headers.get('content-type')
|
||||||
if ((contentType && !contentType.includes('application/xml')) || !contentType) {
|
if ((contentType && !contentType.includes('application/xml') && !contentType.includes('text/xml')) || !contentType) {
|
||||||
if (process.env.DEBUG === 'true') console.error(`non xml response, content type: ${contentType}, on page: ${currentURL}`)
|
if (process.env.DEBUG === 'true') console.error(`non xml response, content type: ${contentType}, on page: ${currentURL}`)
|
||||||
return urls
|
return urls
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ PORT=3000
|
|||||||
# FLOWISE_PASSWORD=1234
|
# FLOWISE_PASSWORD=1234
|
||||||
# DEBUG=true
|
# DEBUG=true
|
||||||
# APIKEY_PATH=/your_api_key_path/.flowise
|
# APIKEY_PATH=/your_api_key_path/.flowise
|
||||||
# LOG_PATH=/your_log_path/logs
|
# LOG_PATH=/your_log_path/.flowise/logs
|
||||||
# LOG_LEVEL=debug (error | warn | info | verbose | debug)
|
# LOG_LEVEL=debug (error | warn | info | verbose | debug)
|
||||||
# EXECUTION_MODE=main (child | main)
|
# EXECUTION_MODE=main (child | main)
|
||||||
|
|
||||||
@@ -19,3 +19,6 @@ DATABASE_TYPE="sqlite" # sqlite, mysql, postgres
|
|||||||
# DATABASE_NAME="flowise"
|
# DATABASE_NAME="flowise"
|
||||||
# DATABASE_USER="root"
|
# DATABASE_USER="root"
|
||||||
# DATABASE_PASSWORD="atish123"
|
# DATABASE_PASSWORD="atish123"
|
||||||
|
|
||||||
|
# TOOL_FUNCTION_BUILTIN_DEP=crypto,fs
|
||||||
|
# TOOL_FUNCTION_EXTERNAL_DEP=moment,lodash
|
||||||
|
|||||||
+21
-19
@@ -31,26 +31,28 @@ FLOWISE_PASSWORD=1234
|
|||||||
|
|
||||||
## 🌱 Env Variables
|
## 🌱 Env Variables
|
||||||
|
|
||||||
Flowise support different environment variables to configure your instance. You can specify the following variables in the `.env` file inside `packages/server` folder.
|
Flowise support different environment variables to configure your instance. You can specify the following variables in the `.env` file inside `packages/server` folder. Read [more](https://docs.flowiseai.com/environment-variables)
|
||||||
|
|
||||||
| Variable | Description | Type | Default |
|
| Variable | Description | Type | Default |
|
||||||
| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------- |
|
||||||
| PORT | The HTTP port Flowise runs on | Number | 3000 |
|
| PORT | The HTTP port Flowise runs on | Number | 3000 |
|
||||||
| FLOWISE_USERNAME | Username to login | String |
|
| FLOWISE_USERNAME | Username to login | String | |
|
||||||
| FLOWISE_PASSWORD | Password to login | String |
|
| FLOWISE_PASSWORD | Password to login | String | |
|
||||||
| DEBUG | Print logs from components | Boolean |
|
| DEBUG | Print logs from components | Boolean | |
|
||||||
| LOG_PATH | Location where log files are stored | String | `your-path/Flowise/logs` |
|
| LOG_PATH | Location where log files are stored | String | `your-path/Flowise/logs` |
|
||||||
| LOG_LEVEL | Different levels of logs | Enum String: `error`, `info`, `verbose`, `debug` | `info` |
|
| LOG_LEVEL | Different levels of logs | Enum String: `error`, `info`, `verbose`, `debug` | `info` |
|
||||||
| APIKEY_PATH | Location where api keys are saved | String | `your-path/Flowise/packages/server` |
|
| APIKEY_PATH | Location where api keys are saved | String | `your-path/Flowise/packages/server` |
|
||||||
| EXECUTION_MODE | Whether predictions run in their own process or the main process | Enum String: `child`, `main` | `main` |
|
| EXECUTION_MODE | Whether predictions run in their own process or the main process | Enum String: `child`, `main` | `main` |
|
||||||
| OVERRIDE_DATABASE| Override current database with default | Enum String: `true`, `false` | `true` |
|
| TOOL_FUNCTION_BUILTIN_DEP | NodeJS built-in modules to be used for Tool Function | String | |
|
||||||
| DATABASE_TYPE | Type of database to store the flowise data | Enum String: `sqlite`, `mysql`, `postgres` | `sqlite` |
|
| TOOL_FUNCTION_EXTERNAL_DEP | External modules to be used for Tool Function | String | |
|
||||||
| DATABASE_PATH | Location where database is saved (When DATABASE_TYPE is sqlite) | String | `your-home-dir/.flowise` |
|
| OVERRIDE_DATABASE | Override current database with default | Enum String: `true`, `false` | `true` |
|
||||||
| DATABASE_HOST | Host URL or IP address (When DATABASE_TYPE is not sqlite) | String | |
|
| DATABASE_TYPE | Type of database to store the flowise data | Enum String: `sqlite`, `mysql`, `postgres` | `sqlite` |
|
||||||
| DATABASE_PORT | Database port (When DATABASE_TYPE is not sqlite) | String | |
|
| DATABASE_PATH | Location where database is saved (When DATABASE_TYPE is sqlite) | String | `your-home-dir/.flowise` |
|
||||||
| DATABASE_USERNAME| Database username (When DATABASE_TYPE is not sqlite) | String | |
|
| DATABASE_HOST | Host URL or IP address (When DATABASE_TYPE is not sqlite) | String | |
|
||||||
| DATABASE_PASSWORD| Database password (When DATABASE_TYPE is not sqlite) | String | |
|
| DATABASE_PORT | Database port (When DATABASE_TYPE is not sqlite) | String | |
|
||||||
| DATABASE_NAME | Database name (When DATABASE_TYPE is not sqlite) | String | |
|
| DATABASE_USERNAME | 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 | |
|
||||||
|
|
||||||
You can also specify the env variables when using `npx`. For example:
|
You can also specify the env variables when using `npx`. For example:
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export default class Start extends Command {
|
|||||||
APIKEY_PATH: Flags.string(),
|
APIKEY_PATH: Flags.string(),
|
||||||
LOG_PATH: Flags.string(),
|
LOG_PATH: Flags.string(),
|
||||||
LOG_LEVEL: Flags.string(),
|
LOG_LEVEL: Flags.string(),
|
||||||
EXECUTION_MODE: Flags.string()
|
EXECUTION_MODE: Flags.string(),
|
||||||
|
TOOL_FUNCTION_BUILTIN_DEP: Flags.string(),
|
||||||
|
TOOL_FUNCTION_EXTERNAL_DEP: Flags.string()
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopProcess() {
|
async stopProcess() {
|
||||||
@@ -65,6 +67,8 @@ export default class Start extends Command {
|
|||||||
if (flags.LOG_LEVEL) process.env.LOG_LEVEL = flags.LOG_LEVEL
|
if (flags.LOG_LEVEL) process.env.LOG_LEVEL = flags.LOG_LEVEL
|
||||||
if (flags.EXECUTION_MODE) process.env.EXECUTION_MODE = flags.EXECUTION_MODE
|
if (flags.EXECUTION_MODE) process.env.EXECUTION_MODE = flags.EXECUTION_MODE
|
||||||
if (flags.DEBUG) process.env.DEBUG = flags.DEBUG
|
if (flags.DEBUG) process.env.DEBUG = flags.DEBUG
|
||||||
|
if (flags.TOOL_FUNCTION_BUILTIN_DEP) process.env.TOOL_FUNCTION_BUILTIN_DEP = flags.TOOL_FUNCTION_BUILTIN_DEP
|
||||||
|
if (flags.TOOL_FUNCTION_EXTERNAL_DEP) process.env.TOOL_FUNCTION_EXTERNAL_DEP = flags.TOOL_FUNCTION_EXTERNAL_DEP
|
||||||
|
|
||||||
await (async () => {
|
await (async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ import {
|
|||||||
isFlowValidForStream,
|
isFlowValidForStream,
|
||||||
isVectorStoreFaiss,
|
isVectorStoreFaiss,
|
||||||
databaseEntities,
|
databaseEntities,
|
||||||
getApiKey
|
getApiKey,
|
||||||
|
clearSessionMemory
|
||||||
} from './utils'
|
} from './utils'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { getDataSource } from './DataSource'
|
import { getDataSource } from './DataSource'
|
||||||
@@ -59,9 +60,6 @@ export class App {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.app = express()
|
this.app = express()
|
||||||
|
|
||||||
// Add the expressRequestLogger middleware to log all requests
|
|
||||||
this.app.use(expressRequestLogger)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async initDatabase() {
|
async initDatabase() {
|
||||||
@@ -92,6 +90,9 @@ export class App {
|
|||||||
// Allow access from *
|
// Allow access from *
|
||||||
this.app.use(cors())
|
this.app.use(cors())
|
||||||
|
|
||||||
|
// Add the expressRequestLogger middleware to log all requests
|
||||||
|
this.app.use(expressRequestLogger)
|
||||||
|
|
||||||
if (process.env.FLOWISE_USERNAME && process.env.FLOWISE_PASSWORD) {
|
if (process.env.FLOWISE_USERNAME && process.env.FLOWISE_PASSWORD) {
|
||||||
const username = process.env.FLOWISE_USERNAME
|
const username = process.env.FLOWISE_USERNAME
|
||||||
const password = process.env.FLOWISE_PASSWORD
|
const password = process.env.FLOWISE_PASSWORD
|
||||||
@@ -306,8 +307,13 @@ export class App {
|
|||||||
|
|
||||||
// Get all chatmessages from chatflowid
|
// Get all chatmessages from chatflowid
|
||||||
this.app.get('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
|
this.app.get('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
|
||||||
const chatmessages = await this.AppDataSource.getRepository(ChatMessage).findBy({
|
const chatmessages = await this.AppDataSource.getRepository(ChatMessage).find({
|
||||||
chatflowid: req.params.id
|
where: {
|
||||||
|
chatflowid: req.params.id
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
createdDate: 'ASC'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return res.json(chatmessages)
|
return res.json(chatmessages)
|
||||||
})
|
})
|
||||||
@@ -326,6 +332,19 @@ export class App {
|
|||||||
|
|
||||||
// Delete all chatmessages from chatflowid
|
// Delete all chatmessages from chatflowid
|
||||||
this.app.delete('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
|
this.app.delete('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
|
||||||
|
const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({
|
||||||
|
id: req.params.id
|
||||||
|
})
|
||||||
|
if (!chatflow) {
|
||||||
|
res.status(404).send(`Chatflow ${req.params.id} not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const flowData = chatflow.flowData
|
||||||
|
const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
|
||||||
|
const nodes = parsedFlowData.nodes
|
||||||
|
let chatId = await getChatId(chatflow.id)
|
||||||
|
if (!chatId) chatId = chatflow.id
|
||||||
|
clearSessionMemory(nodes, this.nodesPool.componentNodes, chatId, req.query.sessionId as string)
|
||||||
const results = await this.AppDataSource.getRepository(ChatMessage).delete({ chatflowid: req.params.id })
|
const results = await this.AppDataSource.getRepository(ChatMessage).delete({ chatflowid: req.params.id })
|
||||||
return res.json(results)
|
return res.json(results)
|
||||||
})
|
})
|
||||||
@@ -668,7 +687,7 @@ export class App {
|
|||||||
if (!chatflow) return res.status(404).send(`Chatflow ${chatflowid} not found`)
|
if (!chatflow) return res.status(404).send(`Chatflow ${chatflowid} not found`)
|
||||||
|
|
||||||
let chatId = await getChatId(chatflow.id)
|
let chatId = await getChatId(chatflow.id)
|
||||||
if (!chatId) chatId = Date.now().toString()
|
if (!chatId) chatId = chatflowid
|
||||||
|
|
||||||
if (!isInternal) {
|
if (!isInternal) {
|
||||||
await this.validateKey(req, res, chatflow)
|
await this.validateKey(req, res, chatflow)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ dotenv.config({ path: path.join(__dirname, '..', '..', '.env'), override: true }
|
|||||||
|
|
||||||
// default config
|
// default config
|
||||||
const loggingConfig = {
|
const loggingConfig = {
|
||||||
dir: process.env.LOG_PATH ?? path.join(__dirname, '..', '..', '..', '..', 'logs'),
|
dir: process.env.LOG_PATH ?? path.join(__dirname, '..', '..', 'logs'),
|
||||||
server: {
|
server: {
|
||||||
level: process.env.LOG_LEVEL ?? 'info',
|
level: process.env.LOG_LEVEL ?? 'info',
|
||||||
filename: 'server.log',
|
filename: 'server.log',
|
||||||
|
|||||||
@@ -273,6 +273,29 @@ export const buildLangchain = async (
|
|||||||
return flowNodes
|
return flowNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear memory
|
||||||
|
* @param {IReactFlowNode[]} reactFlowNodes
|
||||||
|
* @param {IComponentNodes} componentNodes
|
||||||
|
* @param {string} chatId
|
||||||
|
* @param {string} sessionId
|
||||||
|
*/
|
||||||
|
export const clearSessionMemory = async (
|
||||||
|
reactFlowNodes: IReactFlowNode[],
|
||||||
|
componentNodes: IComponentNodes,
|
||||||
|
chatId: string,
|
||||||
|
sessionId?: string
|
||||||
|
) => {
|
||||||
|
for (const node of reactFlowNodes) {
|
||||||
|
if (node.data.category !== 'Memory') continue
|
||||||
|
const nodeInstanceFilePath = componentNodes[node.data.name].filePath as string
|
||||||
|
const nodeModule = await import(nodeInstanceFilePath)
|
||||||
|
const newNodeInstance = new nodeModule.nodeClass()
|
||||||
|
if (sessionId && node.data.inputs) node.data.inputs.sessionId = sessionId
|
||||||
|
if (newNodeInstance.clearSessionMemory) await newNodeInstance?.clearSessionMemory(node.data, { chatId })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get variable value from outputResponses.output
|
* Get variable value from outputResponses.output
|
||||||
* @param {string} paramValue
|
* @param {string} paramValue
|
||||||
|
|||||||
@@ -57,43 +57,46 @@ const logger = createLogger({
|
|||||||
* this.app.use(expressRequestLogger)
|
* this.app.use(expressRequestLogger)
|
||||||
*/
|
*/
|
||||||
export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void {
|
export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void {
|
||||||
const fileLogger = createLogger({
|
const unwantedLogURLs = ['/api/v1/node-icon/']
|
||||||
format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.json(), errors({ stack: true })),
|
if (req.url.includes('/api/v1/') && !unwantedLogURLs.some((url) => req.url.includes(url))) {
|
||||||
defaultMeta: {
|
const fileLogger = createLogger({
|
||||||
package: 'server',
|
format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.json(), errors({ stack: true })),
|
||||||
request: {
|
defaultMeta: {
|
||||||
method: req.method,
|
package: 'server',
|
||||||
url: req.url,
|
request: {
|
||||||
body: req.body,
|
method: req.method,
|
||||||
query: req.query,
|
url: req.url,
|
||||||
params: req.params,
|
body: req.body,
|
||||||
headers: req.headers
|
query: req.query,
|
||||||
}
|
params: req.params,
|
||||||
},
|
headers: req.headers
|
||||||
transports: [
|
}
|
||||||
new transports.File({
|
},
|
||||||
filename: path.join(logDir, config.logging.express.filename ?? 'server-requests.log.jsonl'),
|
transports: [
|
||||||
level: config.logging.express.level ?? 'debug'
|
new transports.File({
|
||||||
})
|
filename: path.join(logDir, config.logging.express.filename ?? 'server-requests.log.jsonl'),
|
||||||
]
|
level: config.logging.express.level ?? 'debug'
|
||||||
})
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
const getRequestEmoji = (method: string) => {
|
const getRequestEmoji = (method: string) => {
|
||||||
const requetsEmojis: Record<string, string> = {
|
const requetsEmojis: Record<string, string> = {
|
||||||
GET: '⬇️',
|
GET: '⬇️',
|
||||||
POST: '⬆️',
|
POST: '⬆️',
|
||||||
PUT: '🖊',
|
PUT: '🖊',
|
||||||
DELETE: '❌'
|
DELETE: '❌'
|
||||||
|
}
|
||||||
|
|
||||||
|
return requetsEmojis[method] || '?'
|
||||||
}
|
}
|
||||||
|
|
||||||
return requetsEmojis[method] || '?'
|
if (req.method !== 'GET') {
|
||||||
}
|
fileLogger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
|
||||||
|
logger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
|
||||||
if (req.method !== 'GET') {
|
} else {
|
||||||
fileLogger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
|
fileLogger.http(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
|
||||||
logger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
|
}
|
||||||
} else {
|
|
||||||
fileLogger.http(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next()
|
next()
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export const Input = ({ inputParam, value, onChange, disabled = false, showDialo
|
|||||||
|
|
||||||
Input.propTypes = {
|
Input.propTypes = {
|
||||||
inputParam: PropTypes.object,
|
inputParam: PropTypes.object,
|
||||||
value: PropTypes.string,
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
showDialog: PropTypes.bool,
|
showDialog: PropTypes.bool,
|
||||||
|
|||||||
@@ -190,7 +190,10 @@ output = query({
|
|||||||
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
@@ -204,7 +207,8 @@ query({"question": "Hey, how are you?"}).then((response) => {
|
|||||||
} else if (codeLang === 'cURL') {
|
} else if (codeLang === 'cURL') {
|
||||||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||||
-X POST \\
|
-X POST \\
|
||||||
-d '{"question": "Hey, how are you?"}'`
|
-d '{"question": "Hey, how are you?"}' \\
|
||||||
|
-H "Content-Type: application/json"`
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@@ -229,9 +233,12 @@ output = query({
|
|||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
||||||
{
|
{
|
||||||
headers: { Authorization: "Bearer ${selectedApiKey?.apiKey}" },
|
headers: {
|
||||||
|
Authorization: "Bearer ${selectedApiKey?.apiKey}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data
|
body: JSON.stringify(data)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
@@ -246,6 +253,7 @@ query({"question": "Hey, how are you?"}).then((response) => {
|
|||||||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||||
-X POST \\
|
-X POST \\
|
||||||
-d '{"question": "Hey, how are you?"}' \\
|
-d '{"question": "Hey, how are you?"}' \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
@@ -316,7 +324,8 @@ query(formData).then((response) => {
|
|||||||
`
|
`
|
||||||
} else if (codeLang === 'cURL') {
|
} else if (codeLang === 'cURL') {
|
||||||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||||
-X POST \\${getConfigExamplesForCurl(configData, 'formData')}`
|
-X POST \\${getConfigExamplesForCurl(configData, 'formData')} \\
|
||||||
|
-H "Content-Type: multipart/form-data"`
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@@ -363,6 +372,7 @@ query(formData).then((response) => {
|
|||||||
} else if (codeLang === 'cURL') {
|
} else if (codeLang === 'cURL') {
|
||||||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||||
-X POST \\${getConfigExamplesForCurl(configData, 'formData')} \\
|
-X POST \\${getConfigExamplesForCurl(configData, 'formData')} \\
|
||||||
|
-H "Content-Type: multipart/form-data" \\
|
||||||
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
@@ -392,7 +402,10 @@ output = query({
|
|||||||
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
@@ -410,7 +423,8 @@ query({
|
|||||||
} else if (codeLang === 'cURL') {
|
} else if (codeLang === 'cURL') {
|
||||||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||||
-X POST \\
|
-X POST \\
|
||||||
-d '{"question": "Hey, how are you?", "overrideConfig": {${getConfigExamplesForCurl(configData, 'json')}}'`
|
-d '{"question": "Hey, how are you?", "overrideConfig": {${getConfigExamplesForCurl(configData, 'json')}}' \\
|
||||||
|
-H "Content-Type: application/json"`
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@@ -439,9 +453,12 @@ output = query({
|
|||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
|
||||||
{
|
{
|
||||||
headers: { Authorization: "Bearer ${selectedApiKey?.apiKey}" },
|
headers: {
|
||||||
|
Authorization: "Bearer ${selectedApiKey?.apiKey}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data
|
body: JSON.stringify(data)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
@@ -460,6 +477,7 @@ query({
|
|||||||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||||
-X POST \\
|
-X POST \\
|
||||||
-d '{"question": "Hey, how are you?", "overrideConfig": {${getConfigExamplesForCurl(configData, 'json')}}' \\
|
-d '{"question": "Hey, how are you?", "overrideConfig": {${getConfigExamplesForCurl(configData, 'json')}}' \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
Reference in New Issue
Block a user