diff --git a/package.json b/package.json
index d0ac9b0d2..210a95c49 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise",
- "version": "1.3.5",
+ "version": "1.3.6",
"private": true,
"homepage": "https://flowiseai.com",
"workspaces": [
diff --git a/packages/components/credentials/LLMonitorApi.credential.ts b/packages/components/credentials/LLMonitorApi.credential.ts
new file mode 100644
index 000000000..e5ecc8aba
--- /dev/null
+++ b/packages/components/credentials/LLMonitorApi.credential.ts
@@ -0,0 +1,32 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class LLMonitorApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'LLMonitor API'
+ this.name = 'llmonitorApi'
+ this.version = 1.0
+ this.description = 'Refer to official guide to get APP ID'
+ this.inputs = [
+ {
+ label: 'APP ID',
+ name: 'llmonitorAppId',
+ type: 'password',
+ placeholder: ''
+ },
+ {
+ label: 'Endpoint',
+ name: 'llmonitorEndpoint',
+ type: 'string',
+ default: 'https://app.llmonitor.com'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: LLMonitorApi }
diff --git a/packages/components/nodes/analytic/LLMonitor/LLMonitor.ts b/packages/components/nodes/analytic/LLMonitor/LLMonitor.ts
new file mode 100644
index 000000000..a1ae317c4
--- /dev/null
+++ b/packages/components/nodes/analytic/LLMonitor/LLMonitor.ts
@@ -0,0 +1,33 @@
+import { INode, INodeParams } from '../../../src/Interface'
+
+class LLMonitor_Analytic implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs?: INodeParams[]
+ credential: INodeParams
+
+ constructor() {
+ this.label = 'LLMonitor'
+ this.name = 'llmonitor'
+ this.version = 1.0
+ this.type = 'LLMonitor'
+ this.icon = 'llmonitor.png'
+ this.category = 'Analytic'
+ this.baseClasses = [this.type]
+ this.inputs = []
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['llmonitorApi']
+ }
+ }
+}
+
+module.exports = { nodeClass: LLMonitor_Analytic }
diff --git a/packages/components/nodes/analytic/LLMonitor/llmonitor.png b/packages/components/nodes/analytic/LLMonitor/llmonitor.png
new file mode 100644
index 000000000..d50a70443
Binary files /dev/null and b/packages/components/nodes/analytic/LLMonitor/llmonitor.png differ
diff --git a/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts b/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts
index 5d270fd8e..ba9cd7f81 100644
--- a/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts
+++ b/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts
@@ -43,7 +43,7 @@ class SqlDatabaseChain_Chains implements INode {
constructor() {
this.label = 'Sql Database Chain'
this.name = 'sqlDatabaseChain'
- this.version = 3.0
+ this.version = 4.0
this.type = 'SqlDatabaseChain'
this.icon = 'sqlchain.svg'
this.category = 'Chains'
@@ -89,7 +89,8 @@ class SqlDatabaseChain_Chains implements INode {
label: 'Include Tables',
name: 'includesTables',
type: 'string',
- description: 'Tables to include for queries.',
+ description: 'Tables to include for queries, seperated by comma. Can only use Include Tables or Ignore Tables',
+ placeholder: 'table1, table2',
additionalParams: true,
optional: true
},
@@ -97,7 +98,8 @@ class SqlDatabaseChain_Chains implements INode {
label: 'Ignore Tables',
name: 'ignoreTables',
type: 'string',
- description: 'Tables to ignore for queries.',
+ description: 'Tables to ignore for queries, seperated by comma. Can only use Ignore Tables or Include Tables',
+ placeholder: 'table1, table2',
additionalParams: true,
optional: true
},
diff --git a/packages/components/nodes/chatmodels/Bittensor/Bittensor.ts b/packages/components/nodes/chatmodels/Bittensor/Bittensor.ts
new file mode 100644
index 000000000..cfcac863b
--- /dev/null
+++ b/packages/components/nodes/chatmodels/Bittensor/Bittensor.ts
@@ -0,0 +1,46 @@
+import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses } from '../../../src/utils'
+import { NIBittensorChatModel, BittensorInput } from 'langchain/experimental/chat_models/bittensor'
+
+class Bittensor_ChatModels implements INode {
+ label: string
+ name: string
+ version: number
+ type: string
+ icon: string
+ category: string
+ description: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'NIBittensorChat'
+ this.name = 'NIBittensorChatModel'
+ this.version = 1.0
+ this.type = 'BittensorChat'
+ this.icon = 'logo.png'
+ this.category = 'Chat Models'
+ this.description = 'Wrapper around Bittensor subnet 1 large language models'
+ this.baseClasses = [this.type, ...getBaseClasses(NIBittensorChatModel)]
+ this.inputs = [
+ {
+ label: 'System prompt',
+ name: 'system_prompt',
+ type: 'string',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string): Promise {
+ const system_prompt = nodeData.inputs?.system_prompt as string
+ const obj: Partial = {
+ systemPrompt: system_prompt
+ }
+ const model = new NIBittensorChatModel(obj)
+ return model
+ }
+}
+
+module.exports = { nodeClass: Bittensor_ChatModels }
diff --git a/packages/components/nodes/chatmodels/Bittensor/logo.png b/packages/components/nodes/chatmodels/Bittensor/logo.png
new file mode 100644
index 000000000..ad51774d5
Binary files /dev/null and b/packages/components/nodes/chatmodels/Bittensor/logo.png differ
diff --git a/packages/components/nodes/llms/Bittensor/Bittensor.ts b/packages/components/nodes/llms/Bittensor/Bittensor.ts
new file mode 100644
index 000000000..a87a7e480
--- /dev/null
+++ b/packages/components/nodes/llms/Bittensor/Bittensor.ts
@@ -0,0 +1,57 @@
+import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses } from '../../../src/utils'
+import { NIBittensorLLM, BittensorInput } from 'langchain/experimental/llms/bittensor'
+
+class Bittensor_LLMs implements INode {
+ label: string
+ name: string
+ version: number
+ type: string
+ icon: string
+ category: string
+ description: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'NIBittensorLLM'
+ this.name = 'NIBittensorLLM'
+ this.version = 1.0
+ this.type = 'Bittensor'
+ this.icon = 'logo.png'
+ this.category = 'LLMs'
+ this.description = 'Wrapper around Bittensor subnet 1 large language models'
+ this.baseClasses = [this.type, ...getBaseClasses(NIBittensorLLM)]
+ this.inputs = [
+ {
+ label: 'System prompt',
+ name: 'system_prompt',
+ type: 'string',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Top Responses',
+ name: 'topResponses',
+ type: 'number',
+ step: 1,
+ optional: true,
+ additionalParams: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string): Promise {
+ const system_prompt = nodeData.inputs?.system_prompt as string
+ const topResponses = Number(nodeData.inputs?.topResponses as number)
+ const obj: Partial = {
+ systemPrompt: system_prompt,
+ topResponses: topResponses
+ }
+
+ const model = new NIBittensorLLM(obj)
+ return model
+ }
+}
+
+module.exports = { nodeClass: Bittensor_LLMs }
diff --git a/packages/components/nodes/llms/Bittensor/logo.png b/packages/components/nodes/llms/Bittensor/logo.png
new file mode 100644
index 000000000..ad51774d5
Binary files /dev/null and b/packages/components/nodes/llms/Bittensor/logo.png differ
diff --git a/packages/components/nodes/vectorstores/Chroma/core.ts b/packages/components/nodes/vectorstores/Chroma/core.ts
index 8277c58ef..b1bf9cc79 100644
--- a/packages/components/nodes/vectorstores/Chroma/core.ts
+++ b/packages/components/nodes/vectorstores/Chroma/core.ts
@@ -30,7 +30,7 @@ export class ChromaExtended extends Chroma {
if (this.chromaApiKey) {
obj.fetchOptions = {
headers: {
- 'X-Api-Key': this.chromaApiKey
+ Authorization: `Bearer ${this.chromaApiKey}`
}
}
}
diff --git a/packages/components/package.json b/packages/components/package.json
index 94dcbdce4..936091062 100644
--- a/packages/components/package.json
+++ b/packages/components/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise-components",
- "version": "1.3.6",
+ "version": "1.3.7",
"description": "Flowiseai Components",
"main": "dist/src/index",
"types": "dist/src/index.d.ts",
@@ -46,6 +46,7 @@
"langfuse-langchain": "^1.0.14-alpha.0",
"langsmith": "^0.0.32",
"linkifyjs": "^4.1.1",
+ "llmonitor": "^0.5.5",
"mammoth": "^1.5.1",
"moment": "^2.29.3",
"mysql2": "^3.5.1",
diff --git a/packages/components/src/handler.ts b/packages/components/src/handler.ts
index f13719ce6..10f9a2141 100644
--- a/packages/components/src/handler.ts
+++ b/packages/components/src/handler.ts
@@ -4,6 +4,7 @@ import { Logger } from 'winston'
import { Server } from 'socket.io'
import { Client } from 'langsmith'
import { LangChainTracer } from 'langchain/callbacks'
+import { LLMonitorHandler } from 'langchain/callbacks/handlers/llmonitor'
import { getCredentialData, getCredentialParam } from './utils'
import { ICommonObject, INodeData } from './Interface'
import CallbackHandler from 'langfuse-langchain'
@@ -194,11 +195,11 @@ export const additionalCallbacks = async (nodeData: INodeData, options: ICommonO
for (const provider in analytic) {
const providerStatus = analytic[provider].status as boolean
if (providerStatus) {
+ const credentialId = analytic[provider].credentialId as string
+ const credentialData = await getCredentialData(credentialId ?? '', options)
if (provider === 'langSmith') {
- const credentialId = analytic[provider].credentialId as string
const langSmithProject = analytic[provider].projectName as string
- const credentialData = await getCredentialData(credentialId ?? '', options)
const langSmithApiKey = getCredentialParam('langSmithApiKey', credentialData, nodeData)
const langSmithEndpoint = getCredentialParam('langSmithEndpoint', credentialData, nodeData)
@@ -214,13 +215,11 @@ export const additionalCallbacks = async (nodeData: INodeData, options: ICommonO
})
callbacks.push(tracer)
} else if (provider === 'langFuse') {
- const credentialId = analytic[provider].credentialId as string
const flushAt = analytic[provider].flushAt as string
const flushInterval = analytic[provider].flushInterval as string
const requestTimeout = analytic[provider].requestTimeout as string
const release = analytic[provider].release as string
- const credentialData = await getCredentialData(credentialId ?? '', options)
const langFuseSecretKey = getCredentialParam('langFuseSecretKey', credentialData, nodeData)
const langFusePublicKey = getCredentialParam('langFusePublicKey', credentialData, nodeData)
const langFuseEndpoint = getCredentialParam('langFuseEndpoint', credentialData, nodeData)
@@ -237,6 +236,17 @@ export const additionalCallbacks = async (nodeData: INodeData, options: ICommonO
const handler = new CallbackHandler(langFuseOptions)
callbacks.push(handler)
+ } else if (provider === 'llmonitor') {
+ const llmonitorAppId = getCredentialParam('llmonitorAppId', credentialData, nodeData)
+ const llmonitorEndpoint = getCredentialParam('llmonitorEndpoint', credentialData, nodeData)
+
+ const llmonitorFields: ICommonObject = {
+ appId: llmonitorAppId,
+ apiUrl: llmonitorEndpoint ?? 'https://app.llmonitor.com'
+ }
+
+ const handler = new LLMonitorHandler(llmonitorFields)
+ callbacks.push(handler)
}
}
}
diff --git a/packages/server/marketplaces/chatflows/SQL DB Chain.json b/packages/server/marketplaces/chatflows/SQL DB Chain.json
index acec5432e..646db5d42 100644
--- a/packages/server/marketplaces/chatflows/SQL DB Chain.json
+++ b/packages/server/marketplaces/chatflows/SQL DB Chain.json
@@ -167,7 +167,7 @@
"data": {
"id": "sqlDatabaseChain_0",
"label": "Sql Database Chain",
- "version": 2,
+ "version": 4,
"name": "sqlDatabaseChain",
"type": "SqlDatabaseChain",
"baseClasses": ["SqlDatabaseChain", "BaseChain", "Runnable"],
@@ -206,6 +206,46 @@
"placeholder": "1270.0.0.1:5432/chinook",
"id": "sqlDatabaseChain_0-input-url-string"
},
+ {
+ "label": "Include Tables",
+ "name": "includesTables",
+ "type": "string",
+ "description": "Tables to include for queries, seperated by comma. Can only use Include Tables or Ignore Tables",
+ "placeholder": "table1, table2",
+ "additionalParams": true,
+ "optional": true,
+ "id": "sqlDatabaseChain_0-input-includesTables-string"
+ },
+ {
+ "label": "Ignore Tables",
+ "name": "ignoreTables",
+ "type": "string",
+ "description": "Tables to ignore for queries, seperated by comma. Can only use Ignore Tables or Include Tables",
+ "placeholder": "table1, table2",
+ "additionalParams": true,
+ "optional": true,
+ "id": "sqlDatabaseChain_0-input-ignoreTables-string"
+ },
+ {
+ "label": "Sample table's rows info",
+ "name": "sampleRowsInTableInfo",
+ "type": "number",
+ "description": "Number of sample row for tables to load for info.",
+ "placeholder": "3",
+ "additionalParams": true,
+ "optional": true,
+ "id": "sqlDatabaseChain_0-input-sampleRowsInTableInfo-number"
+ },
+ {
+ "label": "Top Keys",
+ "name": "topK",
+ "type": "number",
+ "description": "If you are querying for several rows of a table you can select the maximum number of results you want to get by using the top_k parameter (default is 10). This is useful for avoiding query results that exceed the prompt max length or consume tokens unnecessarily.",
+ "placeholder": "10",
+ "additionalParams": true,
+ "optional": true,
+ "id": "sqlDatabaseChain_0-input-topK-number"
+ },
{
"label": "Custom Prompt",
"name": "customPrompt",
diff --git a/packages/server/package.json b/packages/server/package.json
index 46ef7ef9c..ffd6b111f 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise",
- "version": "1.3.5",
+ "version": "1.3.6",
"description": "Flowiseai Server",
"main": "dist/index",
"types": "dist/index.d.ts",
diff --git a/packages/server/src/commands/start.ts b/packages/server/src/commands/start.ts
index b9ea970d5..6bf7d6993 100644
--- a/packages/server/src/commands/start.ts
+++ b/packages/server/src/commands/start.ts
@@ -27,6 +27,7 @@ export default class Start extends Command {
LOG_LEVEL: Flags.string(),
TOOL_FUNCTION_BUILTIN_DEP: Flags.string(),
TOOL_FUNCTION_EXTERNAL_DEP: Flags.string(),
+ NUMBER_OF_PROXIES: Flags.string(),
DATABASE_TYPE: Flags.string(),
DATABASE_PATH: Flags.string(),
DATABASE_PORT: Flags.string(),
@@ -72,6 +73,7 @@ export default class Start extends Command {
if (flags.PORT) process.env.PORT = flags.PORT
if (flags.DEBUG) process.env.DEBUG = flags.DEBUG
+ if (flags.NUMBER_OF_PROXIES) process.env.NUMBER_OF_PROXIES = flags.NUMBER_OF_PROXIES
// Authorization
if (flags.FLOWISE_USERNAME) process.env.FLOWISE_USERNAME = flags.FLOWISE_USERNAME
diff --git a/packages/server/src/utils/rateLimit.ts b/packages/server/src/utils/rateLimit.ts
index b1cd1819d..68b5b693b 100644
--- a/packages/server/src/utils/rateLimit.ts
+++ b/packages/server/src/utils/rateLimit.ts
@@ -12,7 +12,7 @@ async function addRateLimiter(id: string, duration: number, limit: number, messa
rateLimiters[id] = rateLimit({
windowMs: duration * 1000,
max: limit,
- handler: (req, res) => {
+ handler: (_, res) => {
res.status(429).send(message)
}
})
@@ -33,15 +33,19 @@ export function getRateLimiter(req: Request, res: Response, next: NextFunction)
export async function createRateLimiter(chatFlow: IChatFlow) {
if (!chatFlow.apiConfig) return
- const apiConfig: any = JSON.parse(chatFlow.apiConfig)
+ const apiConfig = JSON.parse(chatFlow.apiConfig)
+
const rateLimit: { limitDuration: number; limitMax: number; limitMsg: string } = apiConfig.rateLimit
if (!rateLimit) return
+
const { limitDuration, limitMax, limitMsg } = rateLimit
if (limitMax && limitDuration && limitMsg) await addRateLimiter(chatFlow.id, limitDuration, limitMax, limitMsg)
}
export async function initializeRateLimiter(chatFlowPool: IChatFlow[]) {
- await chatFlowPool.map(async (chatFlow) => {
- await createRateLimiter(chatFlow)
- })
+ await Promise.all(
+ chatFlowPool.map(async (chatFlow) => {
+ await createRateLimiter(chatFlow)
+ })
+ )
}
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 71a8dccad..f0101d2ce 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise-ui",
- "version": "1.3.3",
+ "version": "1.3.4",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://flowiseai.com",
"author": {
diff --git a/packages/ui/src/assets/images/llmonitor.png b/packages/ui/src/assets/images/llmonitor.png
new file mode 100644
index 000000000..d50a70443
Binary files /dev/null and b/packages/ui/src/assets/images/llmonitor.png differ
diff --git a/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js b/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js
index 1ed68fb58..2d9a7d91f 100644
--- a/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js
+++ b/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js
@@ -31,6 +31,7 @@ import { Input } from 'ui-component/input/Input'
import { StyledButton } from 'ui-component/button/StyledButton'
import langsmithPNG from 'assets/images/langchain.png'
import langfusePNG from 'assets/images/langfuse.png'
+import llmonitorPNG from 'assets/images/llmonitor.png'
// store
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
@@ -115,6 +116,26 @@ const analyticProviders = [
optional: true
}
]
+ },
+ {
+ label: 'LLMonitor',
+ name: 'llmonitor',
+ icon: llmonitorPNG,
+ url: 'https://llmonitor.com',
+ inputs: [
+ {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['llmonitorApi']
+ },
+ {
+ label: 'On/Off',
+ name: 'status',
+ type: 'boolean',
+ optional: true
+ }
+ ]
}
]
diff --git a/packages/ui/src/views/chatflows/Configuration.js b/packages/ui/src/views/chatflows/Configuration.js
index 51b8d61c8..d569020b4 100644
--- a/packages/ui/src/views/chatflows/Configuration.js
+++ b/packages/ui/src/views/chatflows/Configuration.js
@@ -136,7 +136,7 @@ const Configuration = () => {
Rate Limit Setup Guide to set up Rate Limit correctly in your hosting environment.'
+ 'Visit Rate Limit Setup Guide to set up Rate Limit correctly in your hosting environment.'
}
/>