diff --git a/.gitignore b/.gitignore
index 9f5ef2e5..533f68a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
**/yarn.lock
## logs
+**/logs
**/*.log
## build
@@ -42,4 +43,4 @@
**/uploads
## compressed
-**/*.tgz
\ No newline at end of file
+**/*.tgz
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 03211d51..524db215 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -114,9 +114,42 @@ Flowise has 3 different modules in a single mono repository.
11. Commit code and submit Pull Request from forked branch pointing to [Flowise master](https://github.com/FlowiseAI/Flowise/tree/master).
+## π± 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. 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 from components | Boolean | |
+| 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` |
+| 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 | |
+| OVERRIDE_DATABASE | Override current database with default | Enum String: `true`, `false` | `true` |
+| DATABASE_TYPE | Type of database to store the flowise data | Enum String: `sqlite`, `mysql`, `postgres` | `sqlite` |
+| DATABASE_PATH | Location where database is saved (When DATABASE_TYPE is sqlite) | String | `your-home-dir/.flowise` |
+| DATABASE_HOST | Host URL or IP address (When DATABASE_TYPE is not sqlite) | String | |
+| DATABASE_PORT | Database port (When DATABASE_TYPE is not sqlite) | String | |
+| 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 | |
+| PASSPHRASE | Passphrase used to create encryption key | String | `MYPASSPHRASE` |
+| SECRETKEY_PATH | Location where encryption key (used to encrypt/decrypt credentials) is saved | String | `your-path/Flowise/packages/server` |
+
+You can also specify the env variables when using `npx`. For example:
+
+```
+npx flowise start --PORT=3000 --DEBUG=true
+```
+
## π Contribute to Docs
-In-Progress
+[Flowise Docs](https://github.com/FlowiseAI/FlowiseDocs)
## π·οΈ Pull Request process
diff --git a/Dockerfile b/Dockerfile
index fe01ed8d..e485cd3e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,7 +8,12 @@ FROM node:18-alpine
RUN apk add --update libc6-compat python3 make g++
# needed for pdfjs-dist
RUN apk add --no-cache build-base cairo-dev pango-dev
+
+# Install Chromium
+RUN apk add --no-cache chromium
+
ENV PUPPETEER_SKIP_DOWNLOAD=true
+ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
WORKDIR /usr/src/packages
diff --git a/README.md b/README.md
index dbce8f3b..65249147 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,19 @@
-# Flowise - LangchainJS UI
+
+# Flowise - Build LLM Apps Easily
+
+[](https://github.com/FlowiseAI/Flowise/releases)
+[](https://discord.gg/jbaHfsRVBW)
+[](https://twitter.com/FlowiseAI)
+[](https://star-history.com/#FlowiseAI/Flowise)
+[](https://github.com/FlowiseAI/Flowise/fork)
+
+
Drag & drop UI to build your customized LLM flow
-Drag & drop UI to build your customized LLM flow using [LangchainJS](https://github.com/hwchase17/langchainjs)
-
## β‘Quick Start
Download and Install [NodeJS](https://nodejs.org/en/download) >= 18.15.0
@@ -34,7 +41,7 @@ Download and Install [NodeJS](https://nodejs.org/en/download) >= 18.15.0
### Docker Compose
1. Go to `docker` folder at the root of the project
-2. Create `.env` file and specify the `PORT` (refer to `.env.example`)
+2. Copy `.env.example` file, paste it into the same location, and rename to `.env`
3. `docker-compose up -d`
4. Open [http://localhost:3000](http://localhost:3000)
5. You can bring the containers down by `docker-compose stop`
@@ -126,6 +133,10 @@ FLOWISE_USERNAME=user
FLOWISE_PASSWORD=1234
```
+## π± 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. Read [more](https://github.com/FlowiseAI/Flowise/blob/main/CONTRIBUTING.md#-env-variables)
+
## π Documentation
[Flowise Docs](https://docs.flowiseai.com/)
@@ -134,7 +145,7 @@ FLOWISE_PASSWORD=1234
### [Railway](https://docs.flowiseai.com/deployment/railway)
-[](https://railway.app/template/YK7J0v)
+[](https://railway.app/template/pn4G8S?referralCode=WVNPD9)
### [Render](https://docs.flowiseai.com/deployment/render)
@@ -158,6 +169,12 @@ Feel free to ask any questions, raise problems, and request new features in [dis
## π Contributing
+Thanks go to these awesome contributors
+
+
+
+
+
See [contributing guide](CONTRIBUTING.md). Reach out to us at [Discord](https://discord.gg/jbaHfsRVBW) if you have any questions or issues.
[](https://star-history.com/#FlowiseAI/Flowise&Date)
diff --git a/artillery-load-test.yml b/artillery-load-test.yml
new file mode 100644
index 00000000..6b1c8140
--- /dev/null
+++ b/artillery-load-test.yml
@@ -0,0 +1,36 @@
+# npm install -g artillery@latest
+# artillery run artillery-load-test.yml
+# Refer https://www.artillery.io/docs
+
+config:
+ target: http://128.128.128.128:3000 # replace with your url
+ phases:
+ - duration: 1
+ arrivalRate: 1
+ rampTo: 2
+ name: Warm up phase
+ - duration: 1
+ arrivalRate: 2
+ rampTo: 3
+ name: Ramp up load
+ - duration: 1
+ arrivalRate: 3
+ name: Sustained peak load
+scenarios:
+ - flow:
+ - loop:
+ - post:
+ url: '/api/v1/prediction/chatflow-id' # replace with your chatflowid
+ json:
+ question: 'hello' # replace with your question
+ count: 1 # how many request each user make
+
+# User __
+# 3 /
+# 2 /
+# 1 _/
+# 1 2 3
+# Seconds
+# Total Users = 2 + 3 + 3 = 8
+# Each making 1 HTTP call
+# Over a duration of 3 seconds
diff --git a/docker/.env.example b/docker/.env.example
index e313316d..dd3b00fb 100644
--- a/docker/.env.example
+++ b/docker/.env.example
@@ -1,5 +1,22 @@
PORT=3000
+PASSPHRASE=MYPASSPHRASE # Passphrase used to create encryption key
+DATABASE_PATH=/root/.flowise
+APIKEY_PATH=/root/.flowise
+SECRETKEY_PATH=/root/.flowise
+LOG_PATH=/root/.flowise/logs
+
+# DATABASE_TYPE=postgres
+# DATABASE_PORT=""
+# DATABASE_HOST=""
+# DATABASE_NAME="flowise"
+# DATABASE_USER=""
+# DATABASE_PASSWORD=""
+# OVERRIDE_DATABASE=true
+
# FLOWISE_USERNAME=user
# FLOWISE_PASSWORD=1234
-# DATABASE_PATH=/your_database_path/.flowise
-# EXECUTION_MODE=child or main
\ No newline at end of file
+# DEBUG=true
+# LOG_LEVEL=debug (error | warn | info | verbose | debug)
+# EXECUTION_MODE=main (child | main)
+# TOOL_FUNCTION_BUILTIN_DEP=crypto,fs
+# TOOL_FUNCTION_EXTERNAL_DEP=moment,lodash
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 2203af11..1ad1bf5e 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -6,7 +6,12 @@ RUN apk add --no-cache git
RUN apk add --no-cache python3 py3-pip make g++
# needed for pdfjs-dist
RUN apk add --no-cache build-base cairo-dev pango-dev
+
+# Install Chromium
+RUN apk add --no-cache chromium
+
ENV PUPPETEER_SKIP_DOWNLOAD=true
+ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
# You can install a specific version like: flowise@1.0.0
RUN npm install -g flowise
diff --git a/docker/README.md b/docker/README.md
index 7f991a04..d3ad1c19 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -9,7 +9,7 @@ Starts Flowise from [DockerHub Image](https://hub.docker.com/repository/docker/f
3. Open [http://localhost:3000](http://localhost:3000)
4. You can bring the containers down by `docker-compose stop`
-## With Authrorization
+## π Authentication
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:
@@ -22,3 +22,14 @@ Starts Flowise from [DockerHub Image](https://hub.docker.com/repository/docker/f
3. `docker-compose up -d`
4. Open [http://localhost:3000](http://localhost:3000)
5. You can bring the containers down by `docker-compose stop`
+
+## π± Env Variables
+
+If you like to persist your data (flows, logs, apikeys, credentials), set these variables in the `.env` file inside `docker` folder:
+
+- DATABASE_PATH=/root/.flowise
+- APIKEY_PATH=/root/.flowise
+- LOG_PATH=/root/.flowise/logs
+- SECRETKEY_PATH=/root/.flowise
+
+Flowise also support different environment variables to configure your instance. Read [more](https://docs.flowiseai.com/environment-variables)
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 0bb68097..e9b2824d 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -6,9 +6,15 @@ services:
restart: always
environment:
- PORT=${PORT}
+ - PASSPHRASE=${PASSPHRASE}
- FLOWISE_USERNAME=${FLOWISE_USERNAME}
- FLOWISE_PASSWORD=${FLOWISE_PASSWORD}
+ - DEBUG=${DEBUG}
- DATABASE_PATH=${DATABASE_PATH}
+ - APIKEY_PATH=${APIKEY_PATH}
+ - SECRETKEY_PATH=${SECRETKEY_PATH}
+ - LOG_LEVEL=${LOG_LEVEL}
+ - LOG_PATH=${LOG_PATH}
- EXECUTION_MODE=${EXECUTION_MODE}
ports:
- '${PORT}:${PORT}'
diff --git a/images/flowise.png b/images/flowise.png
new file mode 100644
index 00000000..09c71fde
Binary files /dev/null and b/images/flowise.png differ
diff --git a/package.json b/package.json
index 0ff76284..650671f7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise",
- "version": "1.2.13",
+ "version": "1.3.2",
"private": true,
"homepage": "https://flowiseai.com",
"workspaces": [
@@ -28,7 +28,6 @@
"*.{js,jsx,ts,tsx,json,md}": "eslint --fix"
},
"devDependencies": {
- "turbo": "1.7.4",
"@babel/preset-env": "^7.19.4",
"@babel/preset-typescript": "7.18.6",
"@types/express": "^4.17.13",
@@ -48,6 +47,7 @@
"pretty-quick": "^3.1.3",
"rimraf": "^3.0.2",
"run-script-os": "^1.1.6",
+ "turbo": "1.7.4",
"typescript": "^4.8.4"
},
"engines": {
diff --git a/packages/components/.env.example b/packages/components/.env.example
deleted file mode 100644
index 352bc6cb..00000000
--- a/packages/components/.env.example
+++ /dev/null
@@ -1 +0,0 @@
-DEBUG=true
\ No newline at end of file
diff --git a/packages/components/README.md b/packages/components/README.md
index 8014661e..5b564bec 100644
--- a/packages/components/README.md
+++ b/packages/components/README.md
@@ -12,14 +12,6 @@ Install:
npm i flowise-components
```
-## Debug
-
-To view all the logs, create an `.env` file and add:
-
-```
-DEBUG=true
-```
-
## License
Source code in this repository is made available under the [MIT License](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
diff --git a/packages/components/credentials/AirtableApi.credential.ts b/packages/components/credentials/AirtableApi.credential.ts
new file mode 100644
index 00000000..323b308f
--- /dev/null
+++ b/packages/components/credentials/AirtableApi.credential.ts
@@ -0,0 +1,27 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class AirtableApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Airtable API'
+ this.name = 'airtableApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide on how to get accessToken on Airtable'
+ this.inputs = [
+ {
+ label: 'Access Token',
+ name: 'accessToken',
+ type: 'password',
+ placeholder: ''
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: AirtableApi }
diff --git a/packages/components/credentials/AnthropicApi.credential.ts b/packages/components/credentials/AnthropicApi.credential.ts
new file mode 100644
index 00000000..955196c9
--- /dev/null
+++ b/packages/components/credentials/AnthropicApi.credential.ts
@@ -0,0 +1,23 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class AnthropicApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Anthropic API'
+ this.name = 'anthropicApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Anthropic Api Key',
+ name: 'anthropicApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: AnthropicApi }
diff --git a/packages/components/credentials/AzureOpenAIApi.credential.ts b/packages/components/credentials/AzureOpenAIApi.credential.ts
new file mode 100644
index 00000000..65f63f37
--- /dev/null
+++ b/packages/components/credentials/AzureOpenAIApi.credential.ts
@@ -0,0 +1,47 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class AzureOpenAIApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Azure OpenAI API'
+ this.name = 'azureOpenAIApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide of how to use Azure OpenAI service'
+ this.inputs = [
+ {
+ label: 'Azure OpenAI Api Key',
+ name: 'azureOpenAIApiKey',
+ type: 'password',
+ description: `Refer to official guide on how to create API key on Azure OpenAI`
+ },
+ {
+ label: 'Azure OpenAI Api Instance Name',
+ name: 'azureOpenAIApiInstanceName',
+ type: 'string',
+ placeholder: 'YOUR-INSTANCE-NAME'
+ },
+ {
+ label: 'Azure OpenAI Api Deployment Name',
+ name: 'azureOpenAIApiDeploymentName',
+ type: 'string',
+ placeholder: 'YOUR-DEPLOYMENT-NAME'
+ },
+ {
+ label: 'Azure OpenAI Api Version',
+ name: 'azureOpenAIApiVersion',
+ type: 'string',
+ placeholder: '2023-06-01-preview',
+ description:
+ 'Description of Supported API Versions. Please refer examples'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: AzureOpenAIApi }
diff --git a/packages/components/credentials/BraveSearchApi.credential.ts b/packages/components/credentials/BraveSearchApi.credential.ts
new file mode 100644
index 00000000..fdacf82c
--- /dev/null
+++ b/packages/components/credentials/BraveSearchApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class BraveSearchApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Brave Search API'
+ this.name = 'braveSearchApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'BraveSearch Api Key',
+ name: 'braveApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: BraveSearchApi }
diff --git a/packages/components/credentials/CohereApi.credential.ts b/packages/components/credentials/CohereApi.credential.ts
new file mode 100644
index 00000000..b171090e
--- /dev/null
+++ b/packages/components/credentials/CohereApi.credential.ts
@@ -0,0 +1,23 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class CohereApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Cohere API'
+ this.name = 'cohereApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Cohere Api Key',
+ name: 'cohereApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: CohereApi }
diff --git a/packages/components/credentials/ConfluenceApi.credential.ts b/packages/components/credentials/ConfluenceApi.credential.ts
new file mode 100644
index 00000000..a1d32e9c
--- /dev/null
+++ b/packages/components/credentials/ConfluenceApi.credential.ts
@@ -0,0 +1,33 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class ConfluenceApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Confluence API'
+ this.name = 'confluenceApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide on how to get accessToken on Confluence'
+ this.inputs = [
+ {
+ label: 'Access Token',
+ name: 'accessToken',
+ type: 'password',
+ placeholder: ''
+ },
+ {
+ label: 'Username',
+ name: 'username',
+ type: 'string',
+ placeholder: ''
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: ConfluenceApi }
diff --git a/packages/components/credentials/DynamodbMemoryApi.credential.ts b/packages/components/credentials/DynamodbMemoryApi.credential.ts
new file mode 100644
index 00000000..2f5ffa64
--- /dev/null
+++ b/packages/components/credentials/DynamodbMemoryApi.credential.ts
@@ -0,0 +1,29 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class DynamodbMemoryApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'DynamodbMemory API'
+ this.name = 'dynamodbMemoryApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Access Key',
+ name: 'accessKey',
+ type: 'password'
+ },
+ {
+ label: 'Secret Access Key',
+ name: 'secretAccessKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: DynamodbMemoryApi }
diff --git a/packages/components/credentials/FigmaApi.credential.ts b/packages/components/credentials/FigmaApi.credential.ts
new file mode 100644
index 00000000..aed49359
--- /dev/null
+++ b/packages/components/credentials/FigmaApi.credential.ts
@@ -0,0 +1,27 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class FigmaApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Figma API'
+ this.name = 'figmaApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide on how to get accessToken on Figma'
+ this.inputs = [
+ {
+ label: 'Access Token',
+ name: 'accessToken',
+ type: 'password',
+ placeholder: ''
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: FigmaApi }
diff --git a/packages/components/credentials/GithubApi.credential.ts b/packages/components/credentials/GithubApi.credential.ts
new file mode 100644
index 00000000..34c5074e
--- /dev/null
+++ b/packages/components/credentials/GithubApi.credential.ts
@@ -0,0 +1,27 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class GithubApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Github API'
+ this.name = 'githubApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide on how to get accessToken on Github'
+ this.inputs = [
+ {
+ label: 'Access Token',
+ name: 'accessToken',
+ type: 'password',
+ placeholder: ''
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: GithubApi }
diff --git a/packages/components/credentials/GoogleSearchApi.credential.ts b/packages/components/credentials/GoogleSearchApi.credential.ts
new file mode 100644
index 00000000..cb82b25a
--- /dev/null
+++ b/packages/components/credentials/GoogleSearchApi.credential.ts
@@ -0,0 +1,31 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class GoogleSearchApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Google Custom Search API'
+ this.name = 'googleCustomSearchApi'
+ this.version = 1.0
+ this.description =
+ 'Please refer to the Google Cloud Console for instructions on how to create an API key, and visit the Search Engine Creation page to learn how to generate your Search Engine ID.'
+ this.inputs = [
+ {
+ label: 'Google Custom Search Api Key',
+ name: 'googleCustomSearchApiKey',
+ type: 'password'
+ },
+ {
+ label: 'Programmable Search Engine ID',
+ name: 'googleCustomSearchApiId',
+ type: 'string'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: GoogleSearchApi }
diff --git a/packages/components/credentials/HuggingFaceApi.credential.ts b/packages/components/credentials/HuggingFaceApi.credential.ts
new file mode 100644
index 00000000..1b922194
--- /dev/null
+++ b/packages/components/credentials/HuggingFaceApi.credential.ts
@@ -0,0 +1,23 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class HuggingFaceApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'HuggingFace API'
+ this.name = 'huggingFaceApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'HuggingFace Api Key',
+ name: 'huggingFaceApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: HuggingFaceApi }
diff --git a/packages/components/credentials/MotorheadMemoryApi.credential.ts b/packages/components/credentials/MotorheadMemoryApi.credential.ts
new file mode 100644
index 00000000..68a18ec1
--- /dev/null
+++ b/packages/components/credentials/MotorheadMemoryApi.credential.ts
@@ -0,0 +1,31 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class MotorheadMemoryApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Motorhead Memory API'
+ this.name = 'motorheadMemoryApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide on how to create API key and Client ID on Motorhead Memory'
+ this.inputs = [
+ {
+ label: 'Client ID',
+ name: 'clientId',
+ type: 'string'
+ },
+ {
+ label: 'API Key',
+ name: 'apiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: MotorheadMemoryApi }
diff --git a/packages/components/credentials/NotionApi.credential.ts b/packages/components/credentials/NotionApi.credential.ts
new file mode 100644
index 00000000..ebe4bf99
--- /dev/null
+++ b/packages/components/credentials/NotionApi.credential.ts
@@ -0,0 +1,26 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class NotionApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Notion API'
+ this.name = 'notionApi'
+ this.version = 1.0
+ this.description =
+ 'You can find integration token here'
+ this.inputs = [
+ {
+ label: 'Notion Integration Token',
+ name: 'notionIntegrationToken',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: NotionApi }
diff --git a/packages/components/credentials/OpenAIApi.credential.ts b/packages/components/credentials/OpenAIApi.credential.ts
new file mode 100644
index 00000000..836da7e9
--- /dev/null
+++ b/packages/components/credentials/OpenAIApi.credential.ts
@@ -0,0 +1,23 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class OpenAIApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'OpenAI API'
+ this.name = 'openAIApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'OpenAI Api Key',
+ name: 'openAIApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: OpenAIApi }
diff --git a/packages/components/credentials/OpenAPIAuth.credential.ts b/packages/components/credentials/OpenAPIAuth.credential.ts
new file mode 100644
index 00000000..3f0ef907
--- /dev/null
+++ b/packages/components/credentials/OpenAPIAuth.credential.ts
@@ -0,0 +1,25 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class OpenAPIAuth implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'OpenAPI Auth Token'
+ this.name = 'openAPIAuth'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'OpenAPI Token',
+ name: 'openAPIToken',
+ type: 'password',
+ description: 'Auth Token. For example: Bearer '
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: OpenAPIAuth }
diff --git a/packages/components/credentials/PineconeApi.credential.ts b/packages/components/credentials/PineconeApi.credential.ts
new file mode 100644
index 00000000..4c5f62fe
--- /dev/null
+++ b/packages/components/credentials/PineconeApi.credential.ts
@@ -0,0 +1,29 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class PineconeApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Pinecone API'
+ this.name = 'pineconeApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Pinecone Api Key',
+ name: 'pineconeApiKey',
+ type: 'password'
+ },
+ {
+ label: 'Pinecone Environment',
+ name: 'pineconeEnv',
+ type: 'string'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: PineconeApi }
diff --git a/packages/components/credentials/QdrantApi.credential.ts b/packages/components/credentials/QdrantApi.credential.ts
new file mode 100644
index 00000000..fffebccc
--- /dev/null
+++ b/packages/components/credentials/QdrantApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class QdrantApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Qdrant API'
+ this.name = 'qdrantApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Qdrant API Key',
+ name: 'qdrantApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: QdrantApi }
diff --git a/packages/components/credentials/ReplicateApi.credential.ts b/packages/components/credentials/ReplicateApi.credential.ts
new file mode 100644
index 00000000..e638826b
--- /dev/null
+++ b/packages/components/credentials/ReplicateApi.credential.ts
@@ -0,0 +1,23 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class ReplicateApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Replicate API'
+ this.name = 'replicateApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Replicate Api Key',
+ name: 'replicateApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: ReplicateApi }
diff --git a/packages/components/credentials/SerpApi.credential.ts b/packages/components/credentials/SerpApi.credential.ts
new file mode 100644
index 00000000..20cf6ab5
--- /dev/null
+++ b/packages/components/credentials/SerpApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class SerpApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Serp API'
+ this.name = 'serpApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Serp Api Key',
+ name: 'serpApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: SerpApi }
diff --git a/packages/components/credentials/SerperApi.credential.ts b/packages/components/credentials/SerperApi.credential.ts
new file mode 100644
index 00000000..9a8fee1e
--- /dev/null
+++ b/packages/components/credentials/SerperApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class SerperApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Serper API'
+ this.name = 'serperApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Serper Api Key',
+ name: 'serperApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: SerperApi }
diff --git a/packages/components/credentials/SingleStoreApi.credential.ts b/packages/components/credentials/SingleStoreApi.credential.ts
new file mode 100644
index 00000000..fee9853b
--- /dev/null
+++ b/packages/components/credentials/SingleStoreApi.credential.ts
@@ -0,0 +1,31 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class SingleStoreApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'SingleStore API'
+ this.name = 'singleStoreApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'User',
+ name: 'user',
+ type: 'string',
+ placeholder: ''
+ },
+ {
+ label: 'Password',
+ name: 'password',
+ type: 'password',
+ placeholder: ''
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: SingleStoreApi }
diff --git a/packages/components/credentials/SupabaseApi.credential.ts b/packages/components/credentials/SupabaseApi.credential.ts
new file mode 100644
index 00000000..beb2a422
--- /dev/null
+++ b/packages/components/credentials/SupabaseApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class SupabaseApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Supabase API'
+ this.name = 'supabaseApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Supabase API Key',
+ name: 'supabaseApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: SupabaseApi }
diff --git a/packages/components/credentials/VectaraApi.credential.ts b/packages/components/credentials/VectaraApi.credential.ts
new file mode 100644
index 00000000..96ad29a6
--- /dev/null
+++ b/packages/components/credentials/VectaraApi.credential.ts
@@ -0,0 +1,34 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class VectaraAPI implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Vectara API'
+ this.name = 'vectaraApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Vectara Customer ID',
+ name: 'customerID',
+ type: 'string'
+ },
+ {
+ label: 'Vectara Corpus ID',
+ name: 'corpusID',
+ type: 'string'
+ },
+ {
+ label: 'Vectara API Key',
+ name: 'apiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: VectaraAPI }
diff --git a/packages/components/credentials/WeaviateApi.credential.ts b/packages/components/credentials/WeaviateApi.credential.ts
new file mode 100644
index 00000000..041b41ea
--- /dev/null
+++ b/packages/components/credentials/WeaviateApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class WeaviateApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Weaviate API'
+ this.name = 'weaviateApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Weaviate API Key',
+ name: 'weaviateApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: WeaviateApi }
diff --git a/packages/components/credentials/ZapierNLAApi.credential.ts b/packages/components/credentials/ZapierNLAApi.credential.ts
new file mode 100644
index 00000000..72035660
--- /dev/null
+++ b/packages/components/credentials/ZapierNLAApi.credential.ts
@@ -0,0 +1,24 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class ZapierNLAApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Zapier NLA API'
+ this.name = 'zapierNLAApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'Zapier NLA Api Key',
+ name: 'zapierNLAApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: ZapierNLAApi }
diff --git a/packages/components/credentials/ZepMemoryApi.credential.ts b/packages/components/credentials/ZepMemoryApi.credential.ts
new file mode 100644
index 00000000..a78ad6d6
--- /dev/null
+++ b/packages/components/credentials/ZepMemoryApi.credential.ts
@@ -0,0 +1,26 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class ZepMemoryApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Zep Memory API'
+ this.name = 'zepMemoryApi'
+ this.version = 1.0
+ this.description =
+ 'Refer to official guide on how to create API key on Zep'
+ this.inputs = [
+ {
+ label: 'API Key',
+ name: 'apiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: ZepMemoryApi }
diff --git a/packages/components/nodes/agents/AirtableAgent/AirtableAgent.ts b/packages/components/nodes/agents/AirtableAgent/AirtableAgent.ts
new file mode 100644
index 00000000..074f39c1
--- /dev/null
+++ b/packages/components/nodes/agents/AirtableAgent/AirtableAgent.ts
@@ -0,0 +1,232 @@
+import { ICommonObject, INode, INodeData, INodeParams, PromptTemplate } from '../../../src/Interface'
+import { AgentExecutor } from 'langchain/agents'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { LoadPyodide, finalSystemPrompt, systemPrompt } from './core'
+import { LLMChain } from 'langchain/chains'
+import { BaseLanguageModel } from 'langchain/base_language'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
+import axios from 'axios'
+
+class Airtable_Agents implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Airtable Agent'
+ this.name = 'airtableAgent'
+ this.version = 1.0
+ this.type = 'AgentExecutor'
+ this.category = 'Agents'
+ this.icon = 'airtable.svg'
+ this.description = 'Agent used to to answer queries on Airtable table'
+ this.baseClasses = [this.type, ...getBaseClasses(AgentExecutor)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['airtableApi']
+ }
+ this.inputs = [
+ {
+ label: 'Language Model',
+ name: 'model',
+ type: 'BaseLanguageModel'
+ },
+ {
+ label: 'Base Id',
+ name: 'baseId',
+ type: 'string',
+ placeholder: 'app11RobdGoX0YNsC',
+ description:
+ 'If your table URL looks like: https://airtable.com/app11RobdGoX0YNsC/tblJdmvbrgizbYICO/viw9UrP77Id0CE4ee, app11RovdGoX0YNsC is the base id'
+ },
+ {
+ label: 'Table Id',
+ name: 'tableId',
+ type: 'string',
+ placeholder: 'tblJdmvbrgizbYICO',
+ description:
+ 'If your table URL looks like: https://airtable.com/app11RobdGoX0YNsC/tblJdmvbrgizbYICO/viw9UrP77Id0CE4ee, tblJdmvbrgizbYICO is the table id'
+ },
+ {
+ label: 'Return All',
+ name: 'returnAll',
+ type: 'boolean',
+ default: true,
+ additionalParams: true,
+ description: 'If all results should be returned or only up to a given limit'
+ },
+ {
+ label: 'Limit',
+ name: 'limit',
+ type: 'number',
+ default: 100,
+ additionalParams: true,
+ description: 'Number of results to return'
+ }
+ ]
+ }
+
+ async init(): Promise {
+ // Not used
+ return undefined
+ }
+
+ async run(nodeData: INodeData, input: string, options: ICommonObject): Promise {
+ const model = nodeData.inputs?.model as BaseLanguageModel
+ const baseId = nodeData.inputs?.baseId as string
+ const tableId = nodeData.inputs?.tableId as string
+ const returnAll = nodeData.inputs?.returnAll as boolean
+ const limit = nodeData.inputs?.limit as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
+
+ let airtableData: ICommonObject[] = []
+
+ if (returnAll) {
+ airtableData = await loadAll(baseId, tableId, accessToken)
+ } else {
+ airtableData = await loadLimit(limit ? parseInt(limit, 10) : 100, baseId, tableId, accessToken)
+ }
+
+ let base64String = Buffer.from(JSON.stringify(airtableData)).toString('base64')
+
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+ const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
+
+ const pyodide = await LoadPyodide()
+
+ // First load the csv file and get the dataframe dictionary of column types
+ // For example using titanic.csv: {'PassengerId': 'int64', 'Survived': 'int64', 'Pclass': 'int64', 'Name': 'object', 'Sex': 'object', 'Age': 'float64', 'SibSp': 'int64', 'Parch': 'int64', 'Ticket': 'object', 'Fare': 'float64', 'Cabin': 'object', 'Embarked': 'object'}
+ let dataframeColDict = ''
+ try {
+ const code = `import pandas as pd
+import base64
+import json
+
+base64_string = "${base64String}"
+
+decoded_data = base64.b64decode(base64_string)
+
+json_data = json.loads(decoded_data)
+
+df = pd.DataFrame(json_data)
+my_dict = df.dtypes.astype(str).to_dict()
+print(my_dict)
+json.dumps(my_dict)`
+ dataframeColDict = await pyodide.runPythonAsync(code)
+ } catch (error) {
+ throw new Error(error)
+ }
+
+ // Then tell GPT to come out with ONLY python code
+ // For example: len(df), df[df['SibSp'] > 3]['PassengerId'].count()
+ let pythonCode = ''
+ if (dataframeColDict) {
+ const chain = new LLMChain({
+ llm: model,
+ prompt: PromptTemplate.fromTemplate(systemPrompt),
+ verbose: process.env.DEBUG === 'true' ? true : false
+ })
+ const inputs = {
+ dict: dataframeColDict,
+ question: input
+ }
+ const res = await chain.call(inputs, [loggerHandler])
+ pythonCode = res?.text
+ }
+
+ // Then run the code using Pyodide
+ let finalResult = ''
+ if (pythonCode) {
+ try {
+ const code = `import pandas as pd\n${pythonCode}`
+ finalResult = await pyodide.runPythonAsync(code)
+ } catch (error) {
+ throw new Error(`Sorry, I'm unable to find answer for question: "${input}" using follwoing code: "${pythonCode}"`)
+ }
+ }
+
+ // Finally, return a complete answer
+ if (finalResult) {
+ const chain = new LLMChain({
+ llm: model,
+ prompt: PromptTemplate.fromTemplate(finalSystemPrompt),
+ verbose: process.env.DEBUG === 'true' ? true : false
+ })
+ const inputs = {
+ question: input,
+ answer: finalResult
+ }
+
+ if (options.socketIO && options.socketIOClientId) {
+ const result = await chain.call(inputs, [loggerHandler, handler])
+ return result?.text
+ } else {
+ const result = await chain.call(inputs, [loggerHandler])
+ return result?.text
+ }
+ }
+
+ return pythonCode
+ }
+}
+
+interface AirtableLoaderResponse {
+ records: AirtableLoaderPage[]
+ offset?: string
+}
+
+interface AirtableLoaderPage {
+ id: string
+ createdTime: string
+ fields: ICommonObject
+}
+
+const fetchAirtableData = async (url: string, params: ICommonObject, accessToken: string): Promise => {
+ try {
+ const headers = {
+ Authorization: `Bearer ${accessToken}`,
+ 'Content-Type': 'application/json',
+ Accept: 'application/json'
+ }
+ const response = await axios.get(url, { params, headers })
+ return response.data
+ } catch (error) {
+ throw new Error(`Failed to fetch ${url} from Airtable: ${error}`)
+ }
+}
+
+const loadAll = async (baseId: string, tableId: string, accessToken: string): Promise => {
+ const params: ICommonObject = { pageSize: 100 }
+ let data: AirtableLoaderResponse
+ let returnPages: AirtableLoaderPage[] = []
+
+ do {
+ data = await fetchAirtableData(`https://api.airtable.com/v0/${baseId}/${tableId}`, params, accessToken)
+ returnPages.push.apply(returnPages, data.records)
+ params.offset = data.offset
+ } while (data.offset !== undefined)
+
+ return data.records.map((page) => page.fields)
+}
+
+const loadLimit = async (limit: number, baseId: string, tableId: string, accessToken: string): Promise => {
+ const params = { maxRecords: limit }
+ const data = await fetchAirtableData(`https://api.airtable.com/v0/${baseId}/${tableId}`, params, accessToken)
+ if (data.records.length === 0) {
+ return []
+ }
+ return data.records.map((page) => page.fields)
+}
+
+module.exports = { nodeClass: Airtable_Agents }
diff --git a/packages/components/nodes/agents/AirtableAgent/airtable.svg b/packages/components/nodes/agents/AirtableAgent/airtable.svg
new file mode 100644
index 00000000..867c3b5a
--- /dev/null
+++ b/packages/components/nodes/agents/AirtableAgent/airtable.svg
@@ -0,0 +1,9 @@
+
+
diff --git a/packages/components/nodes/agents/AirtableAgent/core.ts b/packages/components/nodes/agents/AirtableAgent/core.ts
new file mode 100644
index 00000000..450bf5ea
--- /dev/null
+++ b/packages/components/nodes/agents/AirtableAgent/core.ts
@@ -0,0 +1,29 @@
+import type { PyodideInterface } from 'pyodide'
+import * as path from 'path'
+import { getUserHome } from '../../../src/utils'
+
+let pyodideInstance: PyodideInterface | undefined
+
+export async function LoadPyodide(): Promise {
+ if (pyodideInstance === undefined) {
+ const { loadPyodide } = await import('pyodide')
+ const obj: any = { packageCacheDir: path.join(getUserHome(), '.flowise', 'pyodideCacheDir') }
+ pyodideInstance = await loadPyodide(obj)
+ await pyodideInstance.loadPackage(['pandas', 'numpy'])
+ }
+
+ return pyodideInstance
+}
+
+export const systemPrompt = `You are working with a pandas dataframe in Python. The name of the dataframe is df.
+
+The columns and data types of a dataframe are given below as a Python dictionary with keys showing column names and values showing the data types.
+{dict}
+
+I will ask question, and you will output the Python code using pandas dataframe to answer my question. Do not provide any explanations. Do not respond with anything except the output of the code.
+
+Question: {question}
+Output Code:`
+
+export const finalSystemPrompt = `You are given the question: {question}. You have an answer to the question: {answer}. Rephrase the answer into a standalone answer.
+Standalone Answer:`
diff --git a/packages/components/nodes/agents/AutoGPT/AutoGPT.ts b/packages/components/nodes/agents/AutoGPT/AutoGPT.ts
index ca118500..69e9b9ed 100644
--- a/packages/components/nodes/agents/AutoGPT/AutoGPT.ts
+++ b/packages/components/nodes/agents/AutoGPT/AutoGPT.ts
@@ -8,6 +8,7 @@ import { flatten } from 'lodash'
class AutoGPT_Agents implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -18,6 +19,7 @@ class AutoGPT_Agents implements INode {
constructor() {
this.label = 'AutoGPT'
this.name = 'autoGPT'
+ this.version = 1.0
this.type = 'AutoGPT'
this.category = 'Agents'
this.icon = 'autogpt.png'
@@ -90,7 +92,6 @@ class AutoGPT_Agents implements INode {
const res = await executor.run([input])
return res || 'I have completed all my tasks.'
} catch (e) {
- console.error(e)
throw new Error(e)
}
}
diff --git a/packages/components/nodes/agents/BabyAGI/BabyAGI.ts b/packages/components/nodes/agents/BabyAGI/BabyAGI.ts
index 91af1469..303c231e 100644
--- a/packages/components/nodes/agents/BabyAGI/BabyAGI.ts
+++ b/packages/components/nodes/agents/BabyAGI/BabyAGI.ts
@@ -6,6 +6,7 @@ import { VectorStore } from 'langchain/vectorstores'
class BabyAGI_Agents implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -16,6 +17,7 @@ class BabyAGI_Agents implements INode {
constructor() {
this.label = 'BabyAGI'
this.name = 'babyAGI'
+ this.version = 1.0
this.type = 'BabyAGI'
this.category = 'Agents'
this.icon = 'babyagi.jpg'
diff --git a/packages/components/nodes/agents/CSVAgent/CSVAgent.ts b/packages/components/nodes/agents/CSVAgent/CSVAgent.ts
new file mode 100644
index 00000000..9224a4c1
--- /dev/null
+++ b/packages/components/nodes/agents/CSVAgent/CSVAgent.ts
@@ -0,0 +1,151 @@
+import { ICommonObject, INode, INodeData, INodeParams, PromptTemplate } from '../../../src/Interface'
+import { AgentExecutor } from 'langchain/agents'
+import { getBaseClasses } from '../../../src/utils'
+import { LoadPyodide, finalSystemPrompt, systemPrompt } from './core'
+import { LLMChain } from 'langchain/chains'
+import { BaseLanguageModel } from 'langchain/base_language'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
+
+class CSV_Agents implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'CSV Agent'
+ this.name = 'csvAgent'
+ this.version = 1.0
+ this.type = 'AgentExecutor'
+ this.category = 'Agents'
+ this.icon = 'csvagent.png'
+ this.description = 'Agent used to to answer queries on CSV data'
+ this.baseClasses = [this.type, ...getBaseClasses(AgentExecutor)]
+ this.inputs = [
+ {
+ label: 'Csv File',
+ name: 'csvFile',
+ type: 'file',
+ fileType: '.csv'
+ },
+ {
+ label: 'Language Model',
+ name: 'model',
+ type: 'BaseLanguageModel'
+ }
+ ]
+ }
+
+ async init(): Promise {
+ // Not used
+ return undefined
+ }
+
+ async run(nodeData: INodeData, input: string, options: ICommonObject): Promise {
+ const csvFileBase64 = nodeData.inputs?.csvFile as string
+ const model = nodeData.inputs?.model as BaseLanguageModel
+
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+ const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
+
+ let files: string[] = []
+
+ if (csvFileBase64.startsWith('[') && csvFileBase64.endsWith(']')) {
+ files = JSON.parse(csvFileBase64)
+ } else {
+ files = [csvFileBase64]
+ }
+
+ let base64String = ''
+
+ for (const file of files) {
+ const splitDataURI = file.split(',')
+ splitDataURI.pop()
+ base64String = splitDataURI.pop() ?? ''
+ }
+
+ const pyodide = await LoadPyodide()
+
+ // First load the csv file and get the dataframe dictionary of column types
+ // For example using titanic.csv: {'PassengerId': 'int64', 'Survived': 'int64', 'Pclass': 'int64', 'Name': 'object', 'Sex': 'object', 'Age': 'float64', 'SibSp': 'int64', 'Parch': 'int64', 'Ticket': 'object', 'Fare': 'float64', 'Cabin': 'object', 'Embarked': 'object'}
+ let dataframeColDict = ''
+ try {
+ const code = `import pandas as pd
+import base64
+from io import StringIO
+import json
+
+base64_string = "${base64String}"
+
+decoded_data = base64.b64decode(base64_string)
+
+csv_data = StringIO(decoded_data.decode('utf-8'))
+
+df = pd.read_csv(csv_data)
+my_dict = df.dtypes.astype(str).to_dict()
+print(my_dict)
+json.dumps(my_dict)`
+ dataframeColDict = await pyodide.runPythonAsync(code)
+ } catch (error) {
+ throw new Error(error)
+ }
+
+ // Then tell GPT to come out with ONLY python code
+ // For example: len(df), df[df['SibSp'] > 3]['PassengerId'].count()
+ let pythonCode = ''
+ if (dataframeColDict) {
+ const chain = new LLMChain({
+ llm: model,
+ prompt: PromptTemplate.fromTemplate(systemPrompt),
+ verbose: process.env.DEBUG === 'true' ? true : false
+ })
+ const inputs = {
+ dict: dataframeColDict,
+ question: input
+ }
+ const res = await chain.call(inputs, [loggerHandler])
+ pythonCode = res?.text
+ }
+
+ // Then run the code using Pyodide
+ let finalResult = ''
+ if (pythonCode) {
+ try {
+ const code = `import pandas as pd\n${pythonCode}`
+ finalResult = await pyodide.runPythonAsync(code)
+ } catch (error) {
+ throw new Error(`Sorry, I'm unable to find answer for question: "${input}" using follwoing code: "${pythonCode}"`)
+ }
+ }
+
+ // Finally, return a complete answer
+ if (finalResult) {
+ const chain = new LLMChain({
+ llm: model,
+ prompt: PromptTemplate.fromTemplate(finalSystemPrompt),
+ verbose: process.env.DEBUG === 'true' ? true : false
+ })
+ const inputs = {
+ question: input,
+ answer: finalResult
+ }
+
+ if (options.socketIO && options.socketIOClientId) {
+ const result = await chain.call(inputs, [loggerHandler, handler])
+ return result?.text
+ } else {
+ const result = await chain.call(inputs, [loggerHandler])
+ return result?.text
+ }
+ }
+
+ return pythonCode
+ }
+}
+
+module.exports = { nodeClass: CSV_Agents }
diff --git a/packages/components/nodes/agents/CSVAgent/core.ts b/packages/components/nodes/agents/CSVAgent/core.ts
new file mode 100644
index 00000000..450bf5ea
--- /dev/null
+++ b/packages/components/nodes/agents/CSVAgent/core.ts
@@ -0,0 +1,29 @@
+import type { PyodideInterface } from 'pyodide'
+import * as path from 'path'
+import { getUserHome } from '../../../src/utils'
+
+let pyodideInstance: PyodideInterface | undefined
+
+export async function LoadPyodide(): Promise {
+ if (pyodideInstance === undefined) {
+ const { loadPyodide } = await import('pyodide')
+ const obj: any = { packageCacheDir: path.join(getUserHome(), '.flowise', 'pyodideCacheDir') }
+ pyodideInstance = await loadPyodide(obj)
+ await pyodideInstance.loadPackage(['pandas', 'numpy'])
+ }
+
+ return pyodideInstance
+}
+
+export const systemPrompt = `You are working with a pandas dataframe in Python. The name of the dataframe is df.
+
+The columns and data types of a dataframe are given below as a Python dictionary with keys showing column names and values showing the data types.
+{dict}
+
+I will ask question, and you will output the Python code using pandas dataframe to answer my question. Do not provide any explanations. Do not respond with anything except the output of the code.
+
+Question: {question}
+Output Code:`
+
+export const finalSystemPrompt = `You are given the question: {question}. You have an answer to the question: {answer}. Rephrase the answer into a standalone answer.
+Standalone Answer:`
diff --git a/packages/components/nodes/agents/CSVAgent/csvagent.png b/packages/components/nodes/agents/CSVAgent/csvagent.png
new file mode 100644
index 00000000..3ed16bb2
Binary files /dev/null and b/packages/components/nodes/agents/CSVAgent/csvagent.png differ
diff --git a/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts b/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts
index 363b3907..005429d6 100644
--- a/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts
+++ b/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts
@@ -3,13 +3,22 @@ import { initializeAgentExecutorWithOptions, AgentExecutor, InitializeAgentExecu
import { Tool } from 'langchain/tools'
import { BaseChatMemory, ChatMessageHistory } from 'langchain/memory'
import { getBaseClasses } from '../../../src/utils'
-import { AIChatMessage, HumanChatMessage } from 'langchain/schema'
+import { AIMessage, HumanMessage } from 'langchain/schema'
import { BaseLanguageModel } from 'langchain/base_language'
import { flatten } from 'lodash'
+const DEFAULT_PREFIX = `Assistant is a large language model trained by OpenAI.
+
+Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.
+
+Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.
+
+Overall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.`
+
class ConversationalAgent_Agents implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -20,6 +29,7 @@ class ConversationalAgent_Agents implements INode {
constructor() {
this.label = 'Conversational Agent'
this.name = 'conversationalAgent'
+ this.version = 1.0
this.type = 'AgentExecutor'
this.category = 'Agents'
this.icon = 'agent.svg'
@@ -47,14 +57,7 @@ class ConversationalAgent_Agents implements INode {
name: 'systemMessage',
type: 'string',
rows: 4,
- optional: true,
- additionalParams: true
- },
- {
- label: 'Human Message',
- name: 'humanMessage',
- type: 'string',
- rows: 4,
+ default: DEFAULT_PREFIX,
optional: true,
additionalParams: true
}
@@ -66,7 +69,6 @@ class ConversationalAgent_Agents implements INode {
let tools = nodeData.inputs?.tools as Tool[]
tools = flatten(tools)
const memory = nodeData.inputs?.memory as BaseChatMemory
- const humanMessage = nodeData.inputs?.humanMessage as string
const systemMessage = nodeData.inputs?.systemMessage as string
const obj: InitializeAgentExecutorOptions = {
@@ -75,9 +77,6 @@ class ConversationalAgent_Agents implements INode {
}
const agentArgs: any = {}
- if (humanMessage) {
- agentArgs.humanMessage = humanMessage
- }
if (systemMessage) {
agentArgs.systemMessage = systemMessage
}
@@ -99,9 +98,9 @@ class ConversationalAgent_Agents implements INode {
for (const message of histories) {
if (message.type === 'apiMessage') {
- chatHistory.push(new AIChatMessage(message.message))
+ chatHistory.push(new AIMessage(message.message))
} else if (message.type === 'userMessage') {
- chatHistory.push(new HumanChatMessage(message.message))
+ chatHistory.push(new HumanMessage(message.message))
}
}
memory.chatHistory = new ChatMessageHistory(chatHistory)
diff --git a/packages/components/nodes/agents/MRKLAgentChat/MRKLAgentChat.ts b/packages/components/nodes/agents/MRKLAgentChat/MRKLAgentChat.ts
index d2a52d6c..0a9e744c 100644
--- a/packages/components/nodes/agents/MRKLAgentChat/MRKLAgentChat.ts
+++ b/packages/components/nodes/agents/MRKLAgentChat/MRKLAgentChat.ts
@@ -8,6 +8,7 @@ import { flatten } from 'lodash'
class MRKLAgentChat_Agents implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -18,6 +19,7 @@ class MRKLAgentChat_Agents implements INode {
constructor() {
this.label = 'MRKL Agent for Chat Models'
this.name = 'mrklAgentChat'
+ this.version = 1.0
this.type = 'AgentExecutor'
this.category = 'Agents'
this.icon = 'agent.svg'
diff --git a/packages/components/nodes/agents/MRKLAgentLLM/MRKLAgentLLM.ts b/packages/components/nodes/agents/MRKLAgentLLM/MRKLAgentLLM.ts
index eb685531..d7af586b 100644
--- a/packages/components/nodes/agents/MRKLAgentLLM/MRKLAgentLLM.ts
+++ b/packages/components/nodes/agents/MRKLAgentLLM/MRKLAgentLLM.ts
@@ -8,6 +8,7 @@ import { flatten } from 'lodash'
class MRKLAgentLLM_Agents implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -18,6 +19,7 @@ class MRKLAgentLLM_Agents implements INode {
constructor() {
this.label = 'MRKL Agent for LLMs'
this.name = 'mrklAgentLLM'
+ this.version = 1.0
this.type = 'AgentExecutor'
this.category = 'Agents'
this.icon = 'agent.svg'
diff --git a/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts b/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts
index 1cbcb547..f3751f1f 100644
--- a/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts
+++ b/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts
@@ -1,14 +1,16 @@
import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
import { initializeAgentExecutorWithOptions, AgentExecutor } from 'langchain/agents'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { BaseLanguageModel } from 'langchain/base_language'
import { flatten } from 'lodash'
import { BaseChatMemory, ChatMessageHistory } from 'langchain/memory'
-import { AIChatMessage, HumanChatMessage } from 'langchain/schema'
+import { AIMessage, HumanMessage } from 'langchain/schema'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class OpenAIFunctionAgent_Agents implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -19,6 +21,7 @@ class OpenAIFunctionAgent_Agents implements INode {
constructor() {
this.label = 'OpenAI Function Agent'
this.name = 'openAIFunctionAgent'
+ this.version = 1.0
this.type = 'AgentExecutor'
this.category = 'Agents'
this.icon = 'openai.png'
@@ -84,21 +87,23 @@ class OpenAIFunctionAgent_Agents implements INode {
for (const message of histories) {
if (message.type === 'apiMessage') {
- chatHistory.push(new AIChatMessage(message.message))
+ chatHistory.push(new AIMessage(message.message))
} else if (message.type === 'userMessage') {
- chatHistory.push(new HumanChatMessage(message.message))
+ chatHistory.push(new HumanMessage(message.message))
}
}
memory.chatHistory = new ChatMessageHistory(chatHistory)
executor.memory = memory
}
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
- const result = await executor.run(input, [handler])
+ const result = await executor.run(input, [loggerHandler, handler])
return result
} else {
- const result = await executor.run(input)
+ const result = await executor.run(input, [loggerHandler])
return result
}
}
diff --git a/packages/components/nodes/chains/ApiChain/GETApiChain.ts b/packages/components/nodes/chains/ApiChain/GETApiChain.ts
index 8e657749..bd4f3bc0 100644
--- a/packages/components/nodes/chains/ApiChain/GETApiChain.ts
+++ b/packages/components/nodes/chains/ApiChain/GETApiChain.ts
@@ -1,8 +1,9 @@
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { APIChain } from 'langchain/chains'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { BaseLanguageModel } from 'langchain/base_language'
import { PromptTemplate } from 'langchain/prompts'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
export const API_URL_RAW_PROMPT_TEMPLATE = `You are given the below API Documentation:
{api_docs}
@@ -18,6 +19,7 @@ export const API_RESPONSE_RAW_PROMPT_TEMPLATE =
class GETApiChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -28,6 +30,7 @@ class GETApiChain_Chains implements INode {
constructor() {
this.label = 'GET API Chain'
this.name = 'getApiChain'
+ this.version = 1.0
this.type = 'GETApiChain'
this.icon = 'apichain.svg'
this.category = 'Chains'
@@ -95,12 +98,14 @@ class GETApiChain_Chains implements INode {
const ansPrompt = nodeData.inputs?.ansPrompt as string
const chain = await getAPIChain(apiDocs, model, headers, urlPrompt, ansPrompt)
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2)
- const res = await chain.run(input, [handler])
+ const res = await chain.run(input, [loggerHandler, handler])
return res
} else {
- const res = await chain.run(input)
+ const res = await chain.run(input, [loggerHandler])
return res
}
}
diff --git a/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts
new file mode 100644
index 00000000..9f6c79e4
--- /dev/null
+++ b/packages/components/nodes/chains/ApiChain/OpenAPIChain.ts
@@ -0,0 +1,100 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { APIChain, createOpenAPIChain } from 'langchain/chains'
+import { getBaseClasses } from '../../../src/utils'
+import { ChatOpenAI } from 'langchain/chat_models/openai'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
+
+class OpenApiChain_Chains implements INode {
+ label: string
+ name: string
+ version: number
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ description: string
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'OpenAPI Chain'
+ this.name = 'openApiChain'
+ this.version = 1.0
+ this.type = 'OpenAPIChain'
+ this.icon = 'openapi.png'
+ this.category = 'Chains'
+ this.description = 'Chain that automatically select and call APIs based only on an OpenAPI spec'
+ this.baseClasses = [this.type, ...getBaseClasses(APIChain)]
+ this.inputs = [
+ {
+ label: 'ChatOpenAI Model',
+ name: 'model',
+ type: 'ChatOpenAI'
+ },
+ {
+ label: 'YAML Link',
+ name: 'yamlLink',
+ type: 'string',
+ placeholder: 'https://api.speak.com/openapi.yaml',
+ description: 'If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead'
+ },
+ {
+ label: 'YAML File',
+ name: 'yamlFile',
+ type: 'file',
+ fileType: '.yaml',
+ description: 'If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead'
+ },
+ {
+ label: 'Headers',
+ name: 'headers',
+ type: 'json',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData): Promise {
+ return await initChain(nodeData)
+ }
+
+ async run(nodeData: INodeData, input: string, options: ICommonObject): Promise {
+ const chain = await initChain(nodeData)
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
+ if (options.socketIO && options.socketIOClientId) {
+ const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
+ const res = await chain.run(input, [loggerHandler, handler])
+ return res
+ } else {
+ const res = await chain.run(input, [loggerHandler])
+ return res
+ }
+ }
+}
+
+const initChain = async (nodeData: INodeData) => {
+ const model = nodeData.inputs?.model as ChatOpenAI
+ const headers = nodeData.inputs?.headers as string
+ const yamlLink = nodeData.inputs?.yamlLink as string
+ const yamlFileBase64 = nodeData.inputs?.yamlFile as string
+
+ let yamlString = ''
+
+ if (yamlLink) {
+ yamlString = yamlLink
+ } else {
+ const splitDataURI = yamlFileBase64.split(',')
+ splitDataURI.pop()
+ const bf = Buffer.from(splitDataURI.pop() || '', 'base64')
+ yamlString = bf.toString('utf-8')
+ }
+
+ return await createOpenAPIChain(yamlString, {
+ llm: model,
+ headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {},
+ verbose: process.env.DEBUG === 'true' ? true : false
+ })
+}
+
+module.exports = { nodeClass: OpenApiChain_Chains }
diff --git a/packages/components/nodes/chains/ApiChain/POSTApiChain.ts b/packages/components/nodes/chains/ApiChain/POSTApiChain.ts
index 3c6ea677..cba4a297 100644
--- a/packages/components/nodes/chains/ApiChain/POSTApiChain.ts
+++ b/packages/components/nodes/chains/ApiChain/POSTApiChain.ts
@@ -1,12 +1,14 @@
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { BaseLanguageModel } from 'langchain/base_language'
import { PromptTemplate } from 'langchain/prompts'
import { API_RESPONSE_RAW_PROMPT_TEMPLATE, API_URL_RAW_PROMPT_TEMPLATE, APIChain } from './postCore'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class POSTApiChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -17,6 +19,7 @@ class POSTApiChain_Chains implements INode {
constructor() {
this.label = 'POST API Chain'
this.name = 'postApiChain'
+ this.version = 1.0
this.type = 'POSTApiChain'
this.icon = 'apichain.svg'
this.category = 'Chains'
@@ -84,12 +87,14 @@ class POSTApiChain_Chains implements INode {
const ansPrompt = nodeData.inputs?.ansPrompt as string
const chain = await getAPIChain(apiDocs, model, headers, urlPrompt, ansPrompt)
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2)
- const res = await chain.run(input, [handler])
+ const res = await chain.run(input, [loggerHandler, handler])
return res
} else {
- const res = await chain.run(input)
+ const res = await chain.run(input, [loggerHandler])
return res
}
}
diff --git a/packages/components/nodes/chains/ApiChain/openapi.png b/packages/components/nodes/chains/ApiChain/openapi.png
new file mode 100644
index 00000000..457c2e40
Binary files /dev/null and b/packages/components/nodes/chains/ApiChain/openapi.png differ
diff --git a/packages/components/nodes/chains/ConversationChain/ConversationChain.ts b/packages/components/nodes/chains/ConversationChain/ConversationChain.ts
index 843e05fc..f08d430c 100644
--- a/packages/components/nodes/chains/ConversationChain/ConversationChain.ts
+++ b/packages/components/nodes/chains/ConversationChain/ConversationChain.ts
@@ -1,16 +1,20 @@
import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
import { ConversationChain } from 'langchain/chains'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate } from 'langchain/prompts'
import { BufferMemory, ChatMessageHistory } from 'langchain/memory'
import { BaseChatModel } from 'langchain/chat_models/base'
-import { AIChatMessage, HumanChatMessage } from 'langchain/schema'
+import { AIMessage, HumanMessage } from 'langchain/schema'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
+import { flatten } from 'lodash'
+import { Document } from 'langchain/document'
-const 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.`
+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.`
class ConversationChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -21,6 +25,7 @@ class ConversationChain_Chains implements INode {
constructor() {
this.label = 'Conversation Chain'
this.name = 'conversationChain'
+ this.version = 1.0
this.type = 'ConversationChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -37,6 +42,14 @@ class ConversationChain_Chains implements INode {
name: 'memory',
type: 'BaseMemory'
},
+ {
+ label: 'Document',
+ name: 'document',
+ type: 'Document',
+ description: 'Include whole document into the context window',
+ optional: true,
+ list: true
+ },
{
label: 'System Message',
name: 'systemMessagePrompt',
@@ -53,6 +66,23 @@ class ConversationChain_Chains implements INode {
const model = nodeData.inputs?.model as BaseChatModel
const memory = nodeData.inputs?.memory as BufferMemory
const prompt = nodeData.inputs?.systemMessagePrompt as string
+ const docs = nodeData.inputs?.document as Document[]
+
+ const flattenDocs = docs && docs.length ? flatten(docs) : []
+ const finalDocs = []
+ for (let i = 0; i < flattenDocs.length; i += 1) {
+ finalDocs.push(new Document(flattenDocs[i]))
+ }
+
+ let finalText = ''
+ for (let i = 0; i < finalDocs.length; i += 1) {
+ finalText += finalDocs[i].pageContent
+ }
+
+ const replaceChar: string[] = ['{', '}']
+ for (const char of replaceChar) finalText = finalText.replaceAll(char, '')
+
+ if (finalText) systemMessage = `${systemMessage}\nThe AI has the following context:\n${finalText}`
const obj: any = {
llm: model,
@@ -81,21 +111,23 @@ class ConversationChain_Chains implements INode {
for (const message of histories) {
if (message.type === 'apiMessage') {
- chatHistory.push(new AIChatMessage(message.message))
+ chatHistory.push(new AIMessage(message.message))
} else if (message.type === 'userMessage') {
- chatHistory.push(new HumanChatMessage(message.message))
+ chatHistory.push(new HumanMessage(message.message))
}
}
memory.chatHistory = new ChatMessageHistory(chatHistory)
chain.memory = memory
}
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
- const res = await chain.call({ input }, [handler])
+ const res = await chain.call({ input }, [loggerHandler, handler])
return res?.response
} else {
- const res = await chain.call({ input })
+ const res = await chain.call({ input }, [loggerHandler])
return res?.response
}
}
diff --git a/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts b/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts
index 3b7e1413..e7f6e826 100644
--- a/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts
+++ b/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts
@@ -1,28 +1,26 @@
import { BaseLanguageModel } from 'langchain/base_language'
import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
-import { ConversationalRetrievalQAChain } from 'langchain/chains'
-import { AIChatMessage, BaseRetriever, HumanChatMessage } from 'langchain/schema'
-import { BaseChatMemory, BufferMemory, ChatMessageHistory } from 'langchain/memory'
+import { getBaseClasses } from '../../../src/utils'
+import { ConversationalRetrievalQAChain, QAChainParams } from 'langchain/chains'
+import { AIMessage, HumanMessage } from 'langchain/schema'
+import { BaseRetriever } from 'langchain/schema/retriever'
+import { BaseChatMemory, BufferMemory, ChatMessageHistory, BufferMemoryInput } from 'langchain/memory'
import { PromptTemplate } from 'langchain/prompts'
-
-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}
-
-Question: {question}
-Helpful Answer:`
-
-const qa_template = `Use the following pieces of context to answer the question at the end.
-
-{context}
-
-Question: {question}
-Helpful Answer:`
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
+import {
+ default_map_reduce_template,
+ default_qa_template,
+ qa_template,
+ map_reduce_template,
+ CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT,
+ refine_question_template,
+ refine_template
+} from './prompts'
class ConversationalRetrievalQAChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -33,6 +31,7 @@ class ConversationalRetrievalQAChain_Chains implements INode {
constructor() {
this.label = 'Conversational Retrieval QA Chain'
this.name = 'conversationalRetrievalQAChain'
+ this.version = 1.0
this.type = 'ConversationalRetrievalQAChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -49,6 +48,13 @@ class ConversationalRetrievalQAChain_Chains implements INode {
name: 'vectorStoreRetriever',
type: 'BaseRetriever'
},
+ {
+ label: 'Memory',
+ name: 'memory',
+ type: 'BaseMemory',
+ optional: true,
+ description: 'If left empty, a default BufferMemory will be used'
+ },
{
label: 'Return Source Documents',
name: 'returnSourceDocuments',
@@ -99,22 +105,59 @@ class ConversationalRetrievalQAChain_Chains implements INode {
const systemMessagePrompt = nodeData.inputs?.systemMessagePrompt as string
const returnSourceDocuments = nodeData.inputs?.returnSourceDocuments as boolean
const chainOption = nodeData.inputs?.chainOption as string
+ const memory = nodeData.inputs?.memory
const obj: any = {
verbose: process.env.DEBUG === 'true' ? true : false,
- qaChainOptions: {
- type: 'stuff',
- prompt: PromptTemplate.fromTemplate(systemMessagePrompt ? `${systemMessagePrompt}\n${qa_template}` : default_qa_template)
- },
- memory: new BufferMemory({
- memoryKey: 'chat_history',
- inputKey: 'question',
- outputKey: 'text',
- returnMessages: true
- })
+ questionGeneratorChainOptions: {
+ template: CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT
+ }
}
if (returnSourceDocuments) obj.returnSourceDocuments = returnSourceDocuments
- if (chainOption) obj.qaChainOptions = { ...obj.qaChainOptions, type: chainOption }
+ if (chainOption === 'map_reduce') {
+ obj.qaChainOptions = {
+ type: 'map_reduce',
+ combinePrompt: PromptTemplate.fromTemplate(
+ systemMessagePrompt ? `${systemMessagePrompt}\n${map_reduce_template}` : default_map_reduce_template
+ )
+ } as QAChainParams
+ } else if (chainOption === 'refine') {
+ const qprompt = new PromptTemplate({
+ inputVariables: ['context', 'question'],
+ template: refine_question_template(systemMessagePrompt)
+ })
+ const rprompt = new PromptTemplate({
+ inputVariables: ['context', 'question', 'existing_answer'],
+ template: refine_template
+ })
+ obj.qaChainOptions = {
+ type: 'refine',
+ questionPrompt: qprompt,
+ refinePrompt: rprompt
+ } as QAChainParams
+ } else {
+ obj.qaChainOptions = {
+ type: 'stuff',
+ prompt: PromptTemplate.fromTemplate(systemMessagePrompt ? `${systemMessagePrompt}\n${qa_template}` : default_qa_template)
+ } as QAChainParams
+ }
+
+ if (memory) {
+ memory.inputKey = 'question'
+ memory.memoryKey = 'chat_history'
+ if (chainOption === 'refine') memory.outputKey = 'output_text'
+ else memory.outputKey = 'text'
+ obj.memory = memory
+ } else {
+ const fields: BufferMemoryInput = {
+ memoryKey: 'chat_history',
+ inputKey: 'question',
+ returnMessages: true
+ }
+ if (chainOption === 'refine') fields.outputKey = 'output_text'
+ else fields.outputKey = 'text'
+ obj.memory = new BufferMemory(fields)
+ }
const chain = ConversationalRetrievalQAChain.fromLLM(model, vectorStoreRetriever, obj)
return chain
@@ -123,6 +166,9 @@ class ConversationalRetrievalQAChain_Chains implements INode {
async run(nodeData: INodeData, input: string, options: ICommonObject): Promise {
const chain = nodeData.instance as ConversationalRetrievalQAChain
const returnSourceDocuments = nodeData.inputs?.returnSourceDocuments as boolean
+ const memory = nodeData.inputs?.memory
+ const chainOption = nodeData.inputs?.chainOption as string
+
let model = nodeData.inputs?.model
// Temporary fix: https://github.com/hwchase17/langchainjs/issues/754
@@ -131,29 +177,46 @@ class ConversationalRetrievalQAChain_Chains implements INode {
const obj = { question: input }
- if (chain.memory && options && options.chatHistory) {
+ // If external memory like Zep, Redis is being used, ignore below
+ if (!memory && chain.memory && options && options.chatHistory) {
const chatHistory = []
const histories: IMessage[] = options.chatHistory
const memory = chain.memory as BaseChatMemory
for (const message of histories) {
if (message.type === 'apiMessage') {
- chatHistory.push(new AIChatMessage(message.message))
+ chatHistory.push(new AIMessage(message.message))
} else if (message.type === 'userMessage') {
- chatHistory.push(new HumanChatMessage(message.message))
+ chatHistory.push(new HumanMessage(message.message))
}
}
memory.chatHistory = new ChatMessageHistory(chatHistory)
chain.memory = memory
}
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
- const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, undefined, returnSourceDocuments)
- const res = await chain.call(obj, [handler])
+ const handler = new CustomChainHandler(
+ options.socketIO,
+ options.socketIOClientId,
+ chainOption === 'refine' ? 4 : undefined,
+ returnSourceDocuments
+ )
+ const res = await chain.call(obj, [loggerHandler, handler])
+ if (chainOption === 'refine') {
+ if (res.output_text && res.sourceDocuments) {
+ return {
+ text: res.output_text,
+ sourceDocuments: res.sourceDocuments
+ }
+ }
+ return res?.output_text
+ }
if (res.text && res.sourceDocuments) return res
return res?.text
} else {
- const res = await chain.call(obj)
+ const res = await chain.call(obj, [loggerHandler])
if (res.text && res.sourceDocuments) return res
return res?.text
}
diff --git a/packages/components/nodes/chains/ConversationalRetrievalQAChain/prompts.ts b/packages/components/nodes/chains/ConversationalRetrievalQAChain/prompts.ts
new file mode 100644
index 00000000..132e3a97
--- /dev/null
+++ b/packages/components/nodes/chains/ConversationalRetrievalQAChain/prompts.ts
@@ -0,0 +1,64 @@
+export 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}
+
+Question: {question}
+Helpful Answer:`
+
+export const qa_template = `Use the following pieces of context to answer the question at the end.
+
+{context}
+
+Question: {question}
+Helpful Answer:`
+
+export const default_map_reduce_template = `Given the following extracted parts of a long document and a question, create a final answer.
+If you don't know the answer, just say that you don't know. Don't try to make up an answer.
+
+{summaries}
+
+Question: {question}
+Helpful Answer:`
+
+export const map_reduce_template = `Given the following extracted parts of a long document and a question, create a final answer.
+
+{summaries}
+
+Question: {question}
+Helpful Answer:`
+
+export const refine_question_template = (sysPrompt?: string) => {
+ let returnPrompt = ''
+ if (sysPrompt)
+ returnPrompt = `Context information is below.
+---------------------
+{context}
+---------------------
+Given the context information and not prior knowledge, ${sysPrompt}
+Answer the question: {question}.
+Answer:`
+ if (!sysPrompt)
+ returnPrompt = `Context information is below.
+---------------------
+{context}
+---------------------
+Given the context information and not prior knowledge, answer the question: {question}.
+Answer:`
+ return returnPrompt
+}
+
+export const refine_template = `The original question is as follows: {question}
+We have provided an existing answer: {existing_answer}
+We have the opportunity to refine the existing answer (only if needed) with some more context below.
+------------
+{context}
+------------
+Given the new context, refine the original answer to better answer the question.
+If you can't find answer from the context, return the original answer.`
+
+export const CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, answer in the same language as the follow up question. include it in the standalone question.
+
+Chat History:
+{chat_history}
+Follow Up Input: {question}
+Standalone question:`
diff --git a/packages/components/nodes/chains/LLMChain/LLMChain.ts b/packages/components/nodes/chains/LLMChain/LLMChain.ts
index 9cd08d35..5088b34d 100644
--- a/packages/components/nodes/chains/LLMChain/LLMChain.ts
+++ b/packages/components/nodes/chains/LLMChain/LLMChain.ts
@@ -1,11 +1,13 @@
import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, handleEscapeCharacters } from '../../../src/utils'
import { LLMChain } from 'langchain/chains'
import { BaseLanguageModel } from 'langchain/base_language'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class LLMChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -17,6 +19,7 @@ class LLMChain_Chains implements INode {
constructor() {
this.label = 'LLM Chain'
this.name = 'llmChain'
+ this.version = 1.0
this.type = 'LLMChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -50,12 +53,12 @@ class LLMChain_Chains implements INode {
{
label: 'Output Prediction',
name: 'outputPrediction',
- baseClasses: ['string']
+ baseClasses: ['string', 'json']
}
]
}
- async init(nodeData: INodeData, input: string): Promise {
+ async init(nodeData: INodeData, input: string, options: ICommonObject): Promise {
const model = nodeData.inputs?.model as BaseLanguageModel
const prompt = nodeData.inputs?.prompt
const output = nodeData.outputs?.output as string
@@ -67,12 +70,17 @@ class LLMChain_Chains implements INode {
} else if (output === 'outputPrediction') {
const chain = new LLMChain({ llm: model, prompt, verbose: process.env.DEBUG === 'true' ? true : false })
const inputVariables = chain.prompt.inputVariables as string[] // ["product"]
- const res = await runPrediction(inputVariables, chain, input, promptValues)
+ const res = await runPrediction(inputVariables, chain, input, promptValues, options)
// eslint-disable-next-line no-console
console.log('\x1b[92m\x1b[1m\n*****OUTPUT PREDICTION*****\n\x1b[0m\x1b[0m')
// eslint-disable-next-line no-console
console.log(res)
- return res
+ /**
+ * Apply string transformation to convert special chars:
+ * FROM: hello i am ben\n\n\thow are you?
+ * TO: hello i am benFLOWISE_NEWLINEFLOWISE_NEWLINEFLOWISE_TABhow are you?
+ */
+ return handleEscapeCharacters(res, false)
}
}
@@ -80,10 +88,7 @@ class LLMChain_Chains implements INode {
const inputVariables = nodeData.instance.prompt.inputVariables as string[] // ["product"]
const chain = nodeData.instance as LLMChain
const promptValues = nodeData.inputs?.prompt.promptValues as ICommonObject
-
- const res = options.socketIO
- ? await runPrediction(inputVariables, chain, input, promptValues, true, options.socketIO, options.socketIOClientId)
- : await runPrediction(inputVariables, chain, input, promptValues)
+ const res = await runPrediction(inputVariables, chain, input, promptValues, options)
// eslint-disable-next-line no-console
console.log('\x1b[93m\x1b[1m\n*****FINAL RESULT*****\n\x1b[0m\x1b[0m')
// eslint-disable-next-line no-console
@@ -96,21 +101,22 @@ const runPrediction = async (
inputVariables: string[],
chain: LLMChain,
input: string,
- promptValues: ICommonObject,
- isStreaming?: boolean,
- socketIO?: any,
- socketIOClientId = ''
+ promptValuesRaw: ICommonObject,
+ options: ICommonObject
) => {
- if (inputVariables.length === 1) {
- if (isStreaming) {
- const handler = new CustomChainHandler(socketIO, socketIOClientId)
- const res = await chain.run(input, [handler])
- return res
- } else {
- const res = await chain.run(input)
- return res
- }
- } else if (inputVariables.length > 1) {
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+ const isStreaming = options.socketIO && options.socketIOClientId
+ const socketIO = isStreaming ? options.socketIO : undefined
+ const socketIOClientId = isStreaming ? options.socketIOClientId : ''
+
+ /**
+ * Apply string transformation to reverse converted special chars:
+ * FROM: { "value": "hello i am benFLOWISE_NEWLINEFLOWISE_NEWLINEFLOWISE_TABhow are you?" }
+ * TO: { "value": "hello i am ben\n\n\thow are you?" }
+ */
+ const promptValues = handleEscapeCharacters(promptValuesRaw, true)
+
+ if (promptValues && inputVariables.length > 0) {
let seen: string[] = []
for (const variable of inputVariables) {
@@ -122,15 +128,13 @@ const runPrediction = async (
if (seen.length === 0) {
// All inputVariables have fixed values specified
- const options = {
- ...promptValues
- }
+ const options = { ...promptValues }
if (isStreaming) {
const handler = new CustomChainHandler(socketIO, socketIOClientId)
- const res = await chain.call(options, [handler])
+ const res = await chain.call(options, [loggerHandler, handler])
return res?.text
} else {
- const res = await chain.call(options)
+ const res = await chain.call(options, [loggerHandler])
return res?.text
}
} else if (seen.length === 1) {
@@ -143,10 +147,10 @@ const runPrediction = async (
}
if (isStreaming) {
const handler = new CustomChainHandler(socketIO, socketIOClientId)
- const res = await chain.call(options, [handler])
+ const res = await chain.call(options, [loggerHandler, handler])
return res?.text
} else {
- const res = await chain.call(options)
+ const res = await chain.call(options, [loggerHandler])
return res?.text
}
} else {
@@ -155,10 +159,10 @@ const runPrediction = async (
} else {
if (isStreaming) {
const handler = new CustomChainHandler(socketIO, socketIOClientId)
- const res = await chain.run(input, [handler])
+ const res = await chain.run(input, [loggerHandler, handler])
return res
} else {
- const res = await chain.run(input)
+ const res = await chain.run(input, [loggerHandler])
return res
}
}
diff --git a/packages/components/nodes/chains/MultiPromptChain/MultiPromptChain.ts b/packages/components/nodes/chains/MultiPromptChain/MultiPromptChain.ts
index 189f41f7..0d137714 100644
--- a/packages/components/nodes/chains/MultiPromptChain/MultiPromptChain.ts
+++ b/packages/components/nodes/chains/MultiPromptChain/MultiPromptChain.ts
@@ -1,11 +1,13 @@
import { BaseLanguageModel } from 'langchain/base_language'
import { ICommonObject, INode, INodeData, INodeParams, PromptRetriever } from '../../../src/Interface'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { MultiPromptChain } from 'langchain/chains'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class MultiPromptChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -16,6 +18,7 @@ class MultiPromptChain_Chains implements INode {
constructor() {
this.label = 'Multi Prompt Chain'
this.name = 'multiPromptChain'
+ this.version = 1.0
this.type = 'MultiPromptChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -63,12 +66,14 @@ class MultiPromptChain_Chains implements INode {
const chain = nodeData.instance as MultiPromptChain
const obj = { input }
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2)
- const res = await chain.call(obj, [handler])
+ const res = await chain.call(obj, [loggerHandler, handler])
return res?.text
} else {
- const res = await chain.call(obj)
+ const res = await chain.call(obj, [loggerHandler])
return res?.text
}
}
diff --git a/packages/components/nodes/chains/MultiRetrievalQAChain/MultiRetrievalQAChain.ts b/packages/components/nodes/chains/MultiRetrievalQAChain/MultiRetrievalQAChain.ts
index b3575a93..6d150647 100644
--- a/packages/components/nodes/chains/MultiRetrievalQAChain/MultiRetrievalQAChain.ts
+++ b/packages/components/nodes/chains/MultiRetrievalQAChain/MultiRetrievalQAChain.ts
@@ -1,11 +1,13 @@
import { BaseLanguageModel } from 'langchain/base_language'
import { ICommonObject, INode, INodeData, INodeParams, VectorStoreRetriever } from '../../../src/Interface'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { MultiRetrievalQAChain } from 'langchain/chains'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class MultiRetrievalQAChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -16,6 +18,7 @@ class MultiRetrievalQAChain_Chains implements INode {
constructor() {
this.label = 'Multi Retrieval QA Chain'
this.name = 'multiRetrievalQAChain'
+ this.version = 1.0
this.type = 'MultiRetrievalQAChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -71,14 +74,15 @@ class MultiRetrievalQAChain_Chains implements INode {
const returnSourceDocuments = nodeData.inputs?.returnSourceDocuments as boolean
const obj = { input }
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2, returnSourceDocuments)
- const res = await chain.call(obj, [handler])
+ const res = await chain.call(obj, [loggerHandler, handler])
if (res.text && res.sourceDocuments) return res
return res?.text
} else {
- const res = await chain.call(obj)
+ const res = await chain.call(obj, [loggerHandler])
if (res.text && res.sourceDocuments) return res
return res?.text
}
diff --git a/packages/components/nodes/chains/RetrievalQAChain/RetrievalQAChain.ts b/packages/components/nodes/chains/RetrievalQAChain/RetrievalQAChain.ts
index 97fa51a1..935866ca 100644
--- a/packages/components/nodes/chains/RetrievalQAChain/RetrievalQAChain.ts
+++ b/packages/components/nodes/chains/RetrievalQAChain/RetrievalQAChain.ts
@@ -1,12 +1,14 @@
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { RetrievalQAChain } from 'langchain/chains'
-import { BaseRetriever } from 'langchain/schema'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { BaseRetriever } from 'langchain/schema/retriever'
+import { getBaseClasses } from '../../../src/utils'
import { BaseLanguageModel } from 'langchain/base_language'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class RetrievalQAChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -17,6 +19,7 @@ class RetrievalQAChain_Chains implements INode {
constructor() {
this.label = 'Retrieval QA Chain'
this.name = 'retrievalQAChain'
+ this.version = 1.0
this.type = 'RetrievalQAChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -49,13 +52,14 @@ class RetrievalQAChain_Chains implements INode {
const obj = {
query: input
}
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
- const res = await chain.call(obj, [handler])
+ const res = await chain.call(obj, [loggerHandler, handler])
return res?.text
} else {
- const res = await chain.call(obj)
+ const res = await chain.call(obj, [loggerHandler])
return res?.text
}
}
diff --git a/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts b/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts
index 27a245e1..9416371b 100644
--- a/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts
+++ b/packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts
@@ -1,13 +1,15 @@
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
-import { SqlDatabaseChain, SqlDatabaseChainInput } from 'langchain/chains'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { SqlDatabaseChain, SqlDatabaseChainInput } from 'langchain/chains/sql_db'
+import { getBaseClasses } from '../../../src/utils'
import { DataSource } from 'typeorm'
import { SqlDatabase } from 'langchain/sql_db'
import { BaseLanguageModel } from 'langchain/base_language'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class SqlDatabaseChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -18,6 +20,7 @@ class SqlDatabaseChain_Chains implements INode {
constructor() {
this.label = 'Sql Database Chain'
this.name = 'sqlDatabaseChain'
+ this.version = 1.0
this.type = 'SqlDatabaseChain'
this.icon = 'sqlchain.svg'
this.category = 'Chains'
@@ -65,12 +68,14 @@ class SqlDatabaseChain_Chains implements INode {
const dbFilePath = nodeData.inputs?.dbFilePath
const chain = await getSQLDBChain(databaseType, dbFilePath, model)
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
- const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
- const res = await chain.run(input, [handler])
+ const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId, 2)
+ const res = await chain.run(input, [loggerHandler, handler])
return res
} else {
- const res = await chain.run(input)
+ const res = await chain.run(input, [loggerHandler])
return res
}
}
diff --git a/packages/components/nodes/chains/VectorDBQAChain/VectorDBQAChain.ts b/packages/components/nodes/chains/VectorDBQAChain/VectorDBQAChain.ts
index 5850ed7b..03811682 100644
--- a/packages/components/nodes/chains/VectorDBQAChain/VectorDBQAChain.ts
+++ b/packages/components/nodes/chains/VectorDBQAChain/VectorDBQAChain.ts
@@ -1,12 +1,14 @@
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
-import { CustomChainHandler, getBaseClasses } from '../../../src/utils'
+import { getBaseClasses } from '../../../src/utils'
import { VectorDBQAChain } from 'langchain/chains'
import { BaseLanguageModel } from 'langchain/base_language'
import { VectorStore } from 'langchain/vectorstores'
+import { ConsoleCallbackHandler, CustomChainHandler } from '../../../src/handler'
class VectorDBQAChain_Chains implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -17,6 +19,7 @@ class VectorDBQAChain_Chains implements INode {
constructor() {
this.label = 'VectorDB QA Chain'
this.name = 'vectorDBQAChain'
+ this.version = 1.0
this.type = 'VectorDBQAChain'
this.icon = 'chain.svg'
this.category = 'Chains'
@@ -53,12 +56,14 @@ class VectorDBQAChain_Chains implements INode {
query: input
}
+ const loggerHandler = new ConsoleCallbackHandler(options.logger)
+
if (options.socketIO && options.socketIOClientId) {
const handler = new CustomChainHandler(options.socketIO, options.socketIOClientId)
- const res = await chain.call(obj, [handler])
+ const res = await chain.call(obj, [loggerHandler, handler])
return res?.text
} else {
- const res = await chain.call(obj)
+ const res = await chain.call(obj, [loggerHandler])
return res?.text
}
}
diff --git a/packages/components/nodes/chatmodels/AzureChatOpenAI/Azure.svg b/packages/components/nodes/chatmodels/AzureChatOpenAI/Azure.svg
index 51eb6253..47ad8c44 100644
--- a/packages/components/nodes/chatmodels/AzureChatOpenAI/Azure.svg
+++ b/packages/components/nodes/chatmodels/AzureChatOpenAI/Azure.svg
@@ -1,5 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/packages/components/nodes/chatmodels/AzureChatOpenAI/AzureChatOpenAI.ts b/packages/components/nodes/chatmodels/AzureChatOpenAI/AzureChatOpenAI.ts
index 7857bfdf..90f430f0 100644
--- a/packages/components/nodes/chatmodels/AzureChatOpenAI/AzureChatOpenAI.ts
+++ b/packages/components/nodes/chatmodels/AzureChatOpenAI/AzureChatOpenAI.ts
@@ -1,32 +1,36 @@
import { OpenAIBaseInput } from 'langchain/dist/types/openai-types'
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { AzureOpenAIInput, ChatOpenAI } from 'langchain/chat_models/openai'
class AzureChatOpenAI_ChatModels implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Azure ChatOpenAI'
this.name = 'azureChatOpenAI'
+ this.version = 1.0
this.type = 'AzureChatOpenAI'
this.icon = 'Azure.svg'
this.category = 'Chat Models'
this.description = 'Wrapper around Azure OpenAI large language models that use the Chat endpoint'
this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['azureOpenAIApi']
+ }
this.inputs = [
- {
- label: 'Azure OpenAI Api Key',
- name: 'azureOpenAIApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
@@ -43,6 +47,10 @@ class AzureChatOpenAI_ChatModels implements INode {
{
label: 'gpt-35-turbo',
name: 'gpt-35-turbo'
+ },
+ {
+ label: 'gpt-35-turbo-16k',
+ name: 'gpt-35-turbo-16k'
}
],
default: 'gpt-35-turbo',
@@ -52,37 +60,15 @@ class AzureChatOpenAI_ChatModels implements INode {
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.9,
optional: true
},
- {
- label: 'Azure OpenAI Api Instance Name',
- name: 'azureOpenAIApiInstanceName',
- type: 'string',
- placeholder: 'YOUR-INSTANCE-NAME'
- },
- {
- label: 'Azure OpenAI Api Deployment Name',
- name: 'azureOpenAIApiDeploymentName',
- type: 'string',
- placeholder: 'YOUR-DEPLOYMENT-NAME'
- },
- {
- label: 'Azure OpenAI Api Version',
- name: 'azureOpenAIApiVersion',
- type: 'options',
- options: [
- {
- label: '2023-03-15-preview',
- name: '2023-03-15-preview'
- }
- ],
- default: '2023-03-15-preview'
- },
{
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -90,6 +76,7 @@ class AzureChatOpenAI_ChatModels implements INode {
label: 'Frequency Penalty',
name: 'frequencyPenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -97,6 +84,7 @@ class AzureChatOpenAI_ChatModels implements INode {
label: 'Presence Penalty',
name: 'presencePenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -104,27 +92,30 @@ class AzureChatOpenAI_ChatModels implements INode {
label: 'Timeout',
name: 'timeout',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
}
]
}
- async init(nodeData: INodeData): Promise {
- const azureOpenAIApiKey = nodeData.inputs?.azureOpenAIApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const modelName = nodeData.inputs?.modelName as string
const temperature = nodeData.inputs?.temperature as string
- const azureOpenAIApiInstanceName = nodeData.inputs?.azureOpenAIApiInstanceName as string
- const azureOpenAIApiDeploymentName = nodeData.inputs?.azureOpenAIApiDeploymentName as string
- const azureOpenAIApiVersion = nodeData.inputs?.azureOpenAIApiVersion as string
const maxTokens = nodeData.inputs?.maxTokens as string
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
const presencePenalty = nodeData.inputs?.presencePenalty as string
const timeout = nodeData.inputs?.timeout as string
const streaming = nodeData.inputs?.streaming as boolean
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData)
+ const azureOpenAIApiInstanceName = getCredentialParam('azureOpenAIApiInstanceName', credentialData, nodeData)
+ const azureOpenAIApiDeploymentName = getCredentialParam('azureOpenAIApiDeploymentName', credentialData, nodeData)
+ const azureOpenAIApiVersion = getCredentialParam('azureOpenAIApiVersion', credentialData, nodeData)
+
const obj: Partial & Partial = {
- temperature: parseInt(temperature, 10),
+ temperature: parseFloat(temperature),
modelName,
azureOpenAIApiKey,
azureOpenAIApiInstanceName,
@@ -134,8 +125,8 @@ class AzureChatOpenAI_ChatModels implements INode {
}
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
- if (presencePenalty) obj.presencePenalty = parseInt(presencePenalty, 10)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty)
if (timeout) obj.timeout = parseInt(timeout, 10)
const model = new ChatOpenAI(obj)
diff --git a/packages/components/nodes/chatmodels/ChatAnthropic/ChatAnthropic.ts b/packages/components/nodes/chatmodels/ChatAnthropic/ChatAnthropic.ts
index 708849e5..12a33d99 100644
--- a/packages/components/nodes/chatmodels/ChatAnthropic/ChatAnthropic.ts
+++ b/packages/components/nodes/chatmodels/ChatAnthropic/ChatAnthropic.ts
@@ -1,36 +1,50 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { AnthropicInput, ChatAnthropic } from 'langchain/chat_models/anthropic'
class ChatAnthropic_ChatModels implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'ChatAnthropic'
this.name = 'chatAnthropic'
+ this.version = 1.0
this.type = 'ChatAnthropic'
this.icon = 'chatAnthropic.png'
this.category = 'Chat Models'
this.description = 'Wrapper around ChatAnthropic large language models that use the Chat endpoint'
this.baseClasses = [this.type, ...getBaseClasses(ChatAnthropic)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['anthropicApi']
+ }
this.inputs = [
- {
- label: 'ChatAnthropic Api Key',
- name: 'anthropicApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
type: 'options',
options: [
+ {
+ label: 'claude-2',
+ name: 'claude-2',
+ description: 'Claude 2 latest major version, automatically get updates to the model as they are released'
+ },
+ {
+ label: 'claude-instant-1',
+ name: 'claude-instant-1',
+ description: 'Claude Instant latest major version, automatically get updates to the model as they are released'
+ },
{
label: 'claude-v1',
name: 'claude-v1'
@@ -76,13 +90,14 @@ class ChatAnthropic_ChatModels implements INode {
name: 'claude-instant-v1.1-100k'
}
],
- default: 'claude-v1',
+ default: 'claude-2',
optional: true
},
{
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.9,
optional: true
},
@@ -90,6 +105,7 @@ class ChatAnthropic_ChatModels implements INode {
label: 'Max Tokens',
name: 'maxTokensToSample',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -97,6 +113,7 @@ class ChatAnthropic_ChatModels implements INode {
label: 'Top P',
name: 'topP',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -104,31 +121,34 @@ class ChatAnthropic_ChatModels implements INode {
label: 'Top K',
name: 'topK',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
}
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const temperature = nodeData.inputs?.temperature as string
const modelName = nodeData.inputs?.modelName as string
- const anthropicApiKey = nodeData.inputs?.anthropicApiKey as string
const maxTokensToSample = nodeData.inputs?.maxTokensToSample as string
const topP = nodeData.inputs?.topP as string
const topK = nodeData.inputs?.topK as string
const streaming = nodeData.inputs?.streaming as boolean
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const anthropicApiKey = getCredentialParam('anthropicApiKey', credentialData, nodeData)
+
const obj: Partial & { anthropicApiKey?: string } = {
- temperature: parseInt(temperature, 10),
+ temperature: parseFloat(temperature),
modelName,
anthropicApiKey,
streaming: streaming ?? true
}
if (maxTokensToSample) obj.maxTokensToSample = parseInt(maxTokensToSample, 10)
- if (topP) obj.topP = parseInt(topP, 10)
- if (topK) obj.topK = parseInt(topK, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (topK) obj.topK = parseFloat(topK)
const model = new ChatAnthropic(obj)
return model
diff --git a/packages/components/nodes/chatmodels/ChatHuggingFace/ChatHuggingFace.ts b/packages/components/nodes/chatmodels/ChatHuggingFace/ChatHuggingFace.ts
index 3252a61a..ee55c7bb 100644
--- a/packages/components/nodes/chatmodels/ChatHuggingFace/ChatHuggingFace.ts
+++ b/packages/components/nodes/chatmodels/ChatHuggingFace/ChatHuggingFace.ts
@@ -1,41 +1,56 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
-import { HFInput, HuggingFaceInference } from 'langchain/llms/hf'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { HFInput, HuggingFaceInference } from './core'
class ChatHuggingFace_ChatModels implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'ChatHuggingFace'
this.name = 'chatHuggingFace'
+ this.version = 1.0
this.type = 'ChatHuggingFace'
this.icon = 'huggingface.png'
this.category = 'Chat Models'
this.description = 'Wrapper around HuggingFace large language models'
this.baseClasses = [this.type, 'BaseChatModel', ...getBaseClasses(HuggingFaceInference)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['huggingFaceApi']
+ }
this.inputs = [
{
label: 'Model',
name: 'model',
type: 'string',
- placeholder: 'gpt2'
+ description: 'If using own inference endpoint, leave this blank',
+ placeholder: 'gpt2',
+ optional: true
},
{
- label: 'HuggingFace Api Key',
- name: 'apiKey',
- type: 'password'
+ label: 'Endpoint',
+ name: 'endpoint',
+ type: 'string',
+ placeholder: 'https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2',
+ description: 'Using your own inference endpoint',
+ optional: true
},
{
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
description: 'Temperature parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -44,6 +59,7 @@ class ChatHuggingFace_ChatModels implements INode {
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
description: 'Max Tokens parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -52,6 +68,7 @@ class ChatHuggingFace_ChatModels implements INode {
label: 'Top Probability',
name: 'topP',
type: 'number',
+ step: 0.1,
description: 'Top Probability parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -60,6 +77,7 @@ class ChatHuggingFace_ChatModels implements INode {
label: 'Top K',
name: 'hfTopK',
type: 'number',
+ step: 0.1,
description: 'Top K parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -68,6 +86,7 @@ class ChatHuggingFace_ChatModels implements INode {
label: 'Frequency Penalty',
name: 'frequencyPenalty',
type: 'number',
+ step: 0.1,
description: 'Frequency Penalty parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -75,25 +94,29 @@ class ChatHuggingFace_ChatModels implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const model = nodeData.inputs?.model as string
- const apiKey = nodeData.inputs?.apiKey as string
const temperature = nodeData.inputs?.temperature as string
const maxTokens = nodeData.inputs?.maxTokens as string
const topP = nodeData.inputs?.topP as string
const hfTopK = nodeData.inputs?.hfTopK as string
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
+ const endpoint = nodeData.inputs?.endpoint as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const huggingFaceApiKey = getCredentialParam('huggingFaceApiKey', credentialData, nodeData)
const obj: Partial = {
model,
- apiKey
+ apiKey: huggingFaceApiKey
}
- if (temperature) obj.temperature = parseInt(temperature, 10)
+ if (temperature) obj.temperature = parseFloat(temperature)
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (topP) obj.topP = parseInt(topP, 10)
- if (hfTopK) obj.topK = parseInt(hfTopK, 10)
- if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (hfTopK) obj.topK = parseFloat(hfTopK)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (endpoint) obj.endpoint = endpoint
const huggingFace = new HuggingFaceInference(obj)
return huggingFace
diff --git a/packages/components/nodes/chatmodels/ChatHuggingFace/core.ts b/packages/components/nodes/chatmodels/ChatHuggingFace/core.ts
new file mode 100644
index 00000000..416567f0
--- /dev/null
+++ b/packages/components/nodes/chatmodels/ChatHuggingFace/core.ts
@@ -0,0 +1,113 @@
+import { getEnvironmentVariable } from '../../../src/utils'
+import { LLM, BaseLLMParams } from 'langchain/llms/base'
+
+export interface HFInput {
+ /** Model to use */
+ model: string
+
+ /** Sampling temperature to use */
+ temperature?: number
+
+ /**
+ * Maximum number of tokens to generate in the completion.
+ */
+ maxTokens?: number
+
+ /** Total probability mass of tokens to consider at each step */
+ topP?: number
+
+ /** Integer to define the top tokens considered within the sample operation to create new text. */
+ topK?: number
+
+ /** Penalizes repeated tokens according to frequency */
+ frequencyPenalty?: number
+
+ /** API key to use. */
+ apiKey?: string
+
+ /** Private endpoint to use. */
+ endpoint?: string
+}
+
+export class HuggingFaceInference extends LLM implements HFInput {
+ get lc_secrets(): { [key: string]: string } | undefined {
+ return {
+ apiKey: 'HUGGINGFACEHUB_API_KEY'
+ }
+ }
+
+ model = 'gpt2'
+
+ temperature: number | undefined = undefined
+
+ maxTokens: number | undefined = undefined
+
+ topP: number | undefined = undefined
+
+ topK: number | undefined = undefined
+
+ frequencyPenalty: number | undefined = undefined
+
+ apiKey: string | undefined = undefined
+
+ endpoint: string | undefined = undefined
+
+ constructor(fields?: Partial & BaseLLMParams) {
+ super(fields ?? {})
+
+ this.model = fields?.model ?? this.model
+ this.temperature = fields?.temperature ?? this.temperature
+ this.maxTokens = fields?.maxTokens ?? this.maxTokens
+ this.topP = fields?.topP ?? this.topP
+ this.topK = fields?.topK ?? this.topK
+ this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty
+ this.endpoint = fields?.endpoint ?? ''
+ this.apiKey = fields?.apiKey ?? getEnvironmentVariable('HUGGINGFACEHUB_API_KEY')
+ if (!this.apiKey) {
+ throw new Error(
+ 'Please set an API key for HuggingFace Hub in the environment variable HUGGINGFACEHUB_API_KEY or in the apiKey field of the HuggingFaceInference constructor.'
+ )
+ }
+ }
+
+ _llmType() {
+ return 'hf'
+ }
+
+ /** @ignore */
+ async _call(prompt: string, options: this['ParsedCallOptions']): Promise {
+ const { HfInference } = await HuggingFaceInference.imports()
+ const hf = new HfInference(this.apiKey)
+ const obj: any = {
+ parameters: {
+ // make it behave similar to openai, returning only the generated text
+ return_full_text: false,
+ temperature: this.temperature,
+ max_new_tokens: this.maxTokens,
+ top_p: this.topP,
+ top_k: this.topK,
+ repetition_penalty: this.frequencyPenalty
+ },
+ inputs: prompt
+ }
+ if (this.endpoint) {
+ hf.endpoint(this.endpoint)
+ } else {
+ obj.model = this.model
+ }
+ const res = await this.caller.callWithOptions({ signal: options.signal }, hf.textGeneration.bind(hf), obj)
+ return res.generated_text
+ }
+
+ /** @ignore */
+ static async imports(): Promise<{
+ HfInference: typeof import('@huggingface/inference').HfInference
+ }> {
+ try {
+ const { HfInference } = await import('@huggingface/inference')
+ return { HfInference }
+ } catch (e) {
+ throw new Error('Please install huggingface as a dependency with, e.g. `yarn add @huggingface/inference`')
+ }
+ }
+}
diff --git a/packages/components/nodes/chatmodels/ChatLocalAI/ChatLocalAI.ts b/packages/components/nodes/chatmodels/ChatLocalAI/ChatLocalAI.ts
index bd25a9fa..a6ddfae4 100644
--- a/packages/components/nodes/chatmodels/ChatLocalAI/ChatLocalAI.ts
+++ b/packages/components/nodes/chatmodels/ChatLocalAI/ChatLocalAI.ts
@@ -6,6 +6,7 @@ import { OpenAIChatInput } from 'langchain/chat_models/openai'
class ChatLocalAI_ChatModels implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -16,6 +17,7 @@ class ChatLocalAI_ChatModels implements INode {
constructor() {
this.label = 'ChatLocalAI'
this.name = 'chatLocalAI'
+ this.version = 1.0
this.type = 'ChatLocalAI'
this.icon = 'localai.png'
this.category = 'Chat Models'
@@ -38,6 +40,7 @@ class ChatLocalAI_ChatModels implements INode {
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.9,
optional: true
},
@@ -45,6 +48,7 @@ class ChatLocalAI_ChatModels implements INode {
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -52,6 +56,7 @@ class ChatLocalAI_ChatModels implements INode {
label: 'Top Probability',
name: 'topP',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -59,6 +64,7 @@ class ChatLocalAI_ChatModels implements INode {
label: 'Timeout',
name: 'timeout',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
}
@@ -74,13 +80,13 @@ class ChatLocalAI_ChatModels implements INode {
const basePath = nodeData.inputs?.basePath as string
const obj: Partial & { openAIApiKey?: string } = {
- temperature: parseInt(temperature, 10),
+ temperature: parseFloat(temperature),
modelName,
openAIApiKey: 'sk-'
}
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (topP) obj.topP = parseInt(topP, 10)
+ if (topP) obj.topP = parseFloat(topP)
if (timeout) obj.timeout = parseInt(timeout, 10)
const model = new OpenAIChat(obj, { basePath })
diff --git a/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts b/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts
index 26f54db8..9512da66 100644
--- a/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts
+++ b/packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts
@@ -1,31 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { ChatOpenAI, OpenAIChatInput } from 'langchain/chat_models/openai'
class ChatOpenAI_ChatModels implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'ChatOpenAI'
this.name = 'chatOpenAI'
+ this.version = 1.0
this.type = 'ChatOpenAI'
this.icon = 'openai.png'
this.category = 'Chat Models'
this.description = 'Wrapper around OpenAI large language models that use the Chat endpoint'
this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['openAIApi']
+ }
this.inputs = [
- {
- label: 'OpenAI Api Key',
- name: 'openAIApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
@@ -71,6 +75,7 @@ class ChatOpenAI_ChatModels implements INode {
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.9,
optional: true
},
@@ -78,6 +83,7 @@ class ChatOpenAI_ChatModels implements INode {
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -85,6 +91,7 @@ class ChatOpenAI_ChatModels implements INode {
label: 'Top Probability',
name: 'topP',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -92,6 +99,7 @@ class ChatOpenAI_ChatModels implements INode {
label: 'Frequency Penalty',
name: 'frequencyPenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -99,6 +107,7 @@ class ChatOpenAI_ChatModels implements INode {
label: 'Presence Penalty',
name: 'presencePenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -106,6 +115,7 @@ class ChatOpenAI_ChatModels implements INode {
label: 'Timeout',
name: 'timeout',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -119,10 +129,9 @@ class ChatOpenAI_ChatModels implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const temperature = nodeData.inputs?.temperature as string
const modelName = nodeData.inputs?.modelName as string
- const openAIApiKey = nodeData.inputs?.openAIApiKey as string
const maxTokens = nodeData.inputs?.maxTokens as string
const topP = nodeData.inputs?.topP as string
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
@@ -131,17 +140,20 @@ class ChatOpenAI_ChatModels implements INode {
const streaming = nodeData.inputs?.streaming as boolean
const basePath = nodeData.inputs?.basepath as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData)
+
const obj: Partial & { openAIApiKey?: string } = {
- temperature: parseInt(temperature, 10),
+ temperature: parseFloat(temperature),
modelName,
openAIApiKey,
streaming: streaming ?? true
}
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (topP) obj.topP = parseInt(topP, 10)
- if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
- if (presencePenalty) obj.presencePenalty = parseInt(presencePenalty, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty)
if (timeout) obj.timeout = parseInt(timeout, 10)
const model = new ChatOpenAI(obj, {
diff --git a/packages/components/nodes/documentloaders/API/APILoader.ts b/packages/components/nodes/documentloaders/API/APILoader.ts
new file mode 100644
index 00000000..3de6d636
--- /dev/null
+++ b/packages/components/nodes/documentloaders/API/APILoader.ts
@@ -0,0 +1,200 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { TextSplitter } from 'langchain/text_splitter'
+import { BaseDocumentLoader } from 'langchain/document_loaders/base'
+import { Document } from 'langchain/document'
+import axios, { AxiosRequestConfig } from 'axios'
+
+class API_DocumentLoaders implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs?: INodeParams[]
+
+ constructor() {
+ this.label = 'API Loader'
+ this.name = 'apiLoader'
+ this.version = 1.0
+ this.type = 'Document'
+ this.icon = 'api-loader.png'
+ this.category = 'Document Loaders'
+ this.description = `Load data from an API`
+ this.baseClasses = [this.type]
+ this.inputs = [
+ {
+ label: 'Text Splitter',
+ name: 'textSplitter',
+ type: 'TextSplitter',
+ optional: true
+ },
+ {
+ label: 'Method',
+ name: 'method',
+ type: 'options',
+ options: [
+ {
+ label: 'GET',
+ name: 'GET'
+ },
+ {
+ label: 'POST',
+ name: 'POST'
+ }
+ ]
+ },
+ {
+ label: 'URL',
+ name: 'url',
+ type: 'string'
+ },
+ {
+ label: 'Headers',
+ name: 'headers',
+ type: 'json',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Body',
+ name: 'body',
+ type: 'json',
+ description:
+ 'JSON body for the POST request. If not specified, agent will try to figure out itself from AIPlugin if provided',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ }
+ async init(nodeData: INodeData): Promise {
+ const headers = nodeData.inputs?.headers as string
+ const url = nodeData.inputs?.url as string
+ const body = nodeData.inputs?.body as string
+ const method = nodeData.inputs?.method as string
+ const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
+ const metadata = nodeData.inputs?.metadata
+
+ const options: ApiLoaderParams = {
+ url,
+ method
+ }
+
+ if (headers) {
+ const parsedHeaders = typeof headers === 'object' ? headers : JSON.parse(headers)
+ options.headers = parsedHeaders
+ }
+
+ if (body) {
+ const parsedBody = typeof body === 'object' ? body : JSON.parse(body)
+ options.body = parsedBody
+ }
+
+ const loader = new ApiLoader(options)
+
+ let docs = []
+
+ if (textSplitter) {
+ docs = await loader.loadAndSplit(textSplitter)
+ } else {
+ docs = await loader.load()
+ }
+
+ if (metadata) {
+ const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata)
+ let finaldocs = []
+ for (const doc of docs) {
+ const newdoc = {
+ ...doc,
+ metadata: {
+ ...doc.metadata,
+ ...parsedMetadata
+ }
+ }
+ finaldocs.push(newdoc)
+ }
+ return finaldocs
+ }
+
+ return docs
+ }
+}
+
+interface ApiLoaderParams {
+ url: string
+ method: string
+ headers?: ICommonObject
+ body?: ICommonObject
+}
+
+class ApiLoader extends BaseDocumentLoader {
+ public readonly url: string
+
+ public readonly headers?: ICommonObject
+
+ public readonly body?: ICommonObject
+
+ public readonly method: string
+
+ constructor({ url, headers, body, method }: ApiLoaderParams) {
+ super()
+ this.url = url
+ this.headers = headers
+ this.body = body
+ this.method = method
+ }
+
+ public async load(): Promise {
+ if (this.method === 'POST') {
+ return this.executePostRequest(this.url, this.headers, this.body)
+ } else {
+ return this.executeGetRequest(this.url, this.headers)
+ }
+ }
+
+ protected async executeGetRequest(url: string, headers?: ICommonObject): Promise {
+ try {
+ const config: AxiosRequestConfig = {}
+ if (headers) {
+ config.headers = headers
+ }
+ const response = await axios.get(url, config)
+ const responseJsonString = JSON.stringify(response.data, null, 2)
+ const doc = new Document({
+ pageContent: responseJsonString,
+ metadata: {
+ url
+ }
+ })
+ return [doc]
+ } catch (error) {
+ throw new Error(`Failed to fetch ${url}: ${error}`)
+ }
+ }
+
+ protected async executePostRequest(url: string, headers?: ICommonObject, body?: ICommonObject): Promise {
+ try {
+ const config: AxiosRequestConfig = {}
+ if (headers) {
+ config.headers = headers
+ }
+ const response = await axios.post(url, body ?? {}, config)
+ const responseJsonString = JSON.stringify(response.data, null, 2)
+ const doc = new Document({
+ pageContent: responseJsonString,
+ metadata: {
+ url
+ }
+ })
+ return [doc]
+ } catch (error) {
+ throw new Error(`Failed to post ${url}: ${error}`)
+ }
+ }
+}
+
+module.exports = {
+ nodeClass: API_DocumentLoaders
+}
diff --git a/packages/components/nodes/documentloaders/API/api-loader.png b/packages/components/nodes/documentloaders/API/api-loader.png
new file mode 100644
index 00000000..93668c4c
Binary files /dev/null and b/packages/components/nodes/documentloaders/API/api-loader.png differ
diff --git a/packages/components/nodes/documentloaders/Airtable/Airtable.ts b/packages/components/nodes/documentloaders/Airtable/Airtable.ts
new file mode 100644
index 00000000..70d0c674
--- /dev/null
+++ b/packages/components/nodes/documentloaders/Airtable/Airtable.ts
@@ -0,0 +1,230 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { TextSplitter } from 'langchain/text_splitter'
+import { BaseDocumentLoader } from 'langchain/document_loaders/base'
+import { Document } from 'langchain/document'
+import axios from 'axios'
+import { getCredentialData, getCredentialParam } from '../../../src/utils'
+
+class Airtable_DocumentLoaders implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs?: INodeParams[]
+
+ constructor() {
+ this.label = 'Airtable'
+ this.name = 'airtable'
+ this.version = 1.0
+ this.type = 'Document'
+ this.icon = 'airtable.svg'
+ this.category = 'Document Loaders'
+ this.description = `Load data from Airtable table`
+ this.baseClasses = [this.type]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['airtableApi']
+ }
+ this.inputs = [
+ {
+ label: 'Text Splitter',
+ name: 'textSplitter',
+ type: 'TextSplitter',
+ optional: true
+ },
+ {
+ label: 'Base Id',
+ name: 'baseId',
+ type: 'string',
+ placeholder: 'app11RobdGoX0YNsC',
+ description:
+ 'If your table URL looks like: https://airtable.com/app11RobdGoX0YNsC/tblJdmvbrgizbYICO/viw9UrP77Id0CE4ee, app11RovdGoX0YNsC is the base id'
+ },
+ {
+ label: 'Table Id',
+ name: 'tableId',
+ type: 'string',
+ placeholder: 'tblJdmvbrgizbYICO',
+ description:
+ 'If your table URL looks like: https://airtable.com/app11RobdGoX0YNsC/tblJdmvbrgizbYICO/viw9UrP77Id0CE4ee, tblJdmvbrgizbYICO is the table id'
+ },
+ {
+ label: 'Return All',
+ name: 'returnAll',
+ type: 'boolean',
+ default: true,
+ additionalParams: true,
+ description: 'If all results should be returned or only up to a given limit'
+ },
+ {
+ label: 'Limit',
+ name: 'limit',
+ type: 'number',
+ default: 100,
+ additionalParams: true,
+ description: 'Number of results to return'
+ },
+ {
+ label: 'Metadata',
+ name: 'metadata',
+ type: 'json',
+ optional: true,
+ additionalParams: true
+ }
+ ]
+ }
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const baseId = nodeData.inputs?.baseId as string
+ const tableId = nodeData.inputs?.tableId as string
+ const returnAll = nodeData.inputs?.returnAll as boolean
+ const limit = nodeData.inputs?.limit as string
+ const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
+ const metadata = nodeData.inputs?.metadata
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
+
+ const airtableOptions: AirtableLoaderParams = {
+ baseId,
+ tableId,
+ returnAll,
+ accessToken,
+ limit: limit ? parseInt(limit, 10) : 100
+ }
+
+ const loader = new AirtableLoader(airtableOptions)
+
+ let docs = []
+
+ if (textSplitter) {
+ docs = await loader.loadAndSplit(textSplitter)
+ } else {
+ docs = await loader.load()
+ }
+
+ if (metadata) {
+ const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata)
+ let finaldocs = []
+ for (const doc of docs) {
+ const newdoc = {
+ ...doc,
+ metadata: {
+ ...doc.metadata,
+ ...parsedMetadata
+ }
+ }
+ finaldocs.push(newdoc)
+ }
+ return finaldocs
+ }
+
+ return docs
+ }
+}
+
+interface AirtableLoaderParams {
+ baseId: string
+ tableId: string
+ accessToken: string
+ limit?: number
+ returnAll?: boolean
+}
+
+interface AirtableLoaderResponse {
+ records: AirtableLoaderPage[]
+ offset?: string
+}
+
+interface AirtableLoaderPage {
+ id: string
+ createdTime: string
+ fields: ICommonObject
+}
+
+class AirtableLoader extends BaseDocumentLoader {
+ public readonly baseId: string
+
+ public readonly tableId: string
+
+ public readonly accessToken: string
+
+ public readonly limit: number
+
+ public readonly returnAll: boolean
+
+ constructor({ baseId, tableId, accessToken, limit = 100, returnAll = false }: AirtableLoaderParams) {
+ super()
+ this.baseId = baseId
+ this.tableId = tableId
+ this.accessToken = accessToken
+ this.limit = limit
+ this.returnAll = returnAll
+ }
+
+ public async load(): Promise {
+ if (this.returnAll) {
+ return this.loadAll()
+ }
+ return this.loadLimit()
+ }
+
+ protected async fetchAirtableData(url: string, params: ICommonObject): Promise {
+ try {
+ const headers = {
+ Authorization: `Bearer ${this.accessToken}`,
+ 'Content-Type': 'application/json',
+ Accept: 'application/json'
+ }
+ const response = await axios.get(url, { params, headers })
+ return response.data
+ } catch (error) {
+ throw new Error(`Failed to fetch ${url} from Airtable: ${error}`)
+ }
+ }
+
+ private createDocumentFromPage(page: AirtableLoaderPage): Document {
+ // Generate the URL
+ const pageUrl = `https://api.airtable.com/v0/${this.baseId}/${this.tableId}/${page.id}`
+
+ // Return a langchain document
+ return new Document({
+ pageContent: JSON.stringify(page.fields, null, 2),
+ metadata: {
+ url: pageUrl
+ }
+ })
+ }
+
+ private async loadLimit(): Promise {
+ const params = { maxRecords: this.limit }
+ const data = await this.fetchAirtableData(`https://api.airtable.com/v0/${this.baseId}/${this.tableId}`, params)
+ if (data.records.length === 0) {
+ return []
+ }
+ return data.records.map((page) => this.createDocumentFromPage(page))
+ }
+
+ private async loadAll(): Promise {
+ const params: ICommonObject = { pageSize: 100 }
+ let data: 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)
+ return returnPages.map((page) => this.createDocumentFromPage(page))
+ }
+}
+
+module.exports = {
+ nodeClass: Airtable_DocumentLoaders
+}
diff --git a/packages/components/nodes/documentloaders/Airtable/airtable.svg b/packages/components/nodes/documentloaders/Airtable/airtable.svg
new file mode 100644
index 00000000..867c3b5a
--- /dev/null
+++ b/packages/components/nodes/documentloaders/Airtable/airtable.svg
@@ -0,0 +1,9 @@
+
+
diff --git a/packages/components/nodes/documentloaders/Cheerio/Cheerio.ts b/packages/components/nodes/documentloaders/Cheerio/Cheerio.ts
index 9e113505..310aa9e6 100644
--- a/packages/components/nodes/documentloaders/Cheerio/Cheerio.ts
+++ b/packages/components/nodes/documentloaders/Cheerio/Cheerio.ts
@@ -2,11 +2,12 @@ import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
import { CheerioWebBaseLoader } from 'langchain/document_loaders/web/cheerio'
import { test } from 'linkifyjs'
-import { getAvailableURLs } from '../../../src'
+import { webCrawl, xmlScrape } from '../../../src'
class Cheerio_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class Cheerio_DocumentLoaders implements INode {
constructor() {
this.label = 'Cheerio Web Scraper'
this.name = 'cheerioWebScraper'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'cheerio.svg'
this.category = 'Document Loaders'
@@ -35,19 +37,34 @@ class Cheerio_DocumentLoaders implements INode {
optional: true
},
{
- label: 'Web Scrap for Relative Links',
- name: 'webScrap',
- type: 'boolean',
+ label: 'Get Relative Links Method',
+ name: 'relativeLinksMethod',
+ type: 'options',
+ description: 'Select a method to retrieve relative links',
+ options: [
+ {
+ label: 'Web Crawl',
+ name: 'webCrawl',
+ description: 'Crawl relative links from HTML URL'
+ },
+ {
+ label: 'Scrape XML Sitemap',
+ name: 'scrapeXMLSitemap',
+ description: 'Scrape relative links from XML sitemap URL'
+ }
+ ],
optional: true,
additionalParams: true
},
{
- label: 'Web Scrap Links Limit',
+ label: 'Get Relative Links Limit',
name: 'limit',
type: 'number',
- default: 10,
optional: true,
- additionalParams: true
+ additionalParams: true,
+ description:
+ 'Only used when "Get Relative Links Method" is selected. Set 0 to retrieve all relative links, default limit is 10.',
+ warning: `Retreiving all links might take long time, and all links will be upserted again if the flow's state changed (eg: different URL, chunk size, etc)`
},
{
label: 'Metadata',
@@ -62,7 +79,7 @@ class Cheerio_DocumentLoaders implements INode {
async init(nodeData: INodeData): Promise {
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const metadata = nodeData.inputs?.metadata
- const webScrap = nodeData.inputs?.webScrap as boolean
+ const relativeLinksMethod = nodeData.inputs?.relativeLinksMethod as string
let limit = nodeData.inputs?.limit as string
let url = nodeData.inputs?.url as string
@@ -71,25 +88,34 @@ class Cheerio_DocumentLoaders implements INode {
throw new Error('Invalid URL')
}
- const cheerioLoader = async (url: string): Promise => {
- let docs = []
- const loader = new CheerioWebBaseLoader(url)
- if (textSplitter) {
- docs = await loader.loadAndSplit(textSplitter)
- } else {
- docs = await loader.load()
+ async function cheerioLoader(url: string): Promise {
+ try {
+ let docs = []
+ const loader = new CheerioWebBaseLoader(url)
+ if (textSplitter) {
+ docs = await loader.loadAndSplit(textSplitter)
+ } else {
+ docs = await loader.load()
+ }
+ return docs
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error in CheerioWebBaseLoader: ${err.message}, on page: ${url}`)
}
- return docs
}
- let availableUrls: string[]
let docs = []
- if (webScrap) {
+ if (relativeLinksMethod) {
+ if (process.env.DEBUG === 'true') console.info(`Start ${relativeLinksMethod}`)
if (!limit) limit = '10'
- availableUrls = await getAvailableURLs(url, parseInt(limit))
- for (let i = 0; i < availableUrls.length; i++) {
- docs.push(...(await cheerioLoader(availableUrls[i])))
+ else if (parseInt(limit) < 0) throw new Error('Limit cannot be less than 0')
+ const pages: string[] =
+ relativeLinksMethod === 'webCrawl' ? await webCrawl(url, parseInt(limit)) : await xmlScrape(url, parseInt(limit))
+ if (process.env.DEBUG === 'true') console.info(`pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
+ if (!pages || pages.length === 0) throw new Error('No relative links found')
+ for (const page of pages) {
+ docs.push(...(await cheerioLoader(page)))
}
+ if (process.env.DEBUG === 'true') console.info(`Finish ${relativeLinksMethod}`)
} else {
docs = await cheerioLoader(url)
}
diff --git a/packages/components/nodes/documentloaders/Confluence/Confluence.ts b/packages/components/nodes/documentloaders/Confluence/Confluence.ts
index 9a69be14..a17c41b9 100644
--- a/packages/components/nodes/documentloaders/Confluence/Confluence.ts
+++ b/packages/components/nodes/documentloaders/Confluence/Confluence.ts
@@ -1,25 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
import { ConfluencePagesLoader, ConfluencePagesLoaderParams } from 'langchain/document_loaders/web/confluence'
+import { getCredentialData, getCredentialParam } from '../../../src'
class Confluence_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Confluence'
this.name = 'confluence'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'confluence.png'
this.category = 'Document Loaders'
this.description = `Load data from a Confluence Document`
this.baseClasses = [this.type]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['confluenceApi']
+ }
this.inputs = [
{
label: 'Text Splitter',
@@ -27,18 +37,6 @@ class Confluence_DocumentLoaders implements INode {
type: 'TextSplitter',
optional: true
},
- {
- label: 'Username',
- name: 'username',
- type: 'string',
- placeholder: ''
- },
- {
- label: 'Access Token',
- name: 'accessToken',
- type: 'password',
- placeholder: ''
- },
{
label: 'Base URL',
name: 'baseUrl',
@@ -49,7 +47,9 @@ class Confluence_DocumentLoaders implements INode {
label: 'Space Key',
name: 'spaceKey',
type: 'string',
- placeholder: '~EXAMPLE362906de5d343d49dcdbae5dEXAMPLE'
+ placeholder: '~EXAMPLE362906de5d343d49dcdbae5dEXAMPLE',
+ description:
+ 'Refer to official guide on how to get Confluence Space Key'
},
{
label: 'Limit',
@@ -68,16 +68,18 @@ class Confluence_DocumentLoaders implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const username = nodeData.inputs?.username as string
- const accessToken = nodeData.inputs?.accessToken as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const spaceKey = nodeData.inputs?.spaceKey as string
const baseUrl = nodeData.inputs?.baseUrl as string
const limit = nodeData.inputs?.limit as number
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const metadata = nodeData.inputs?.metadata
- const options: ConfluencePagesLoaderParams = {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
+ const username = getCredentialParam('username', credentialData, nodeData)
+
+ const confluenceOptions: ConfluencePagesLoaderParams = {
username,
accessToken,
baseUrl,
@@ -85,7 +87,7 @@ class Confluence_DocumentLoaders implements INode {
limit
}
- const loader = new ConfluencePagesLoader(options)
+ const loader = new ConfluencePagesLoader(confluenceOptions)
let docs = []
diff --git a/packages/components/nodes/documentloaders/Csv/Csv.ts b/packages/components/nodes/documentloaders/Csv/Csv.ts
index f4b36ad0..750490b7 100644
--- a/packages/components/nodes/documentloaders/Csv/Csv.ts
+++ b/packages/components/nodes/documentloaders/Csv/Csv.ts
@@ -5,6 +5,7 @@ import { CSVLoader } from 'langchain/document_loaders/fs/csv'
class Csv_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Csv_DocumentLoaders implements INode {
constructor() {
this.label = 'Csv File'
this.name = 'csvFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'Csv.png'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Docx/Docx.ts b/packages/components/nodes/documentloaders/Docx/Docx.ts
index e27991a5..41922775 100644
--- a/packages/components/nodes/documentloaders/Docx/Docx.ts
+++ b/packages/components/nodes/documentloaders/Docx/Docx.ts
@@ -5,6 +5,7 @@ import { DocxLoader } from 'langchain/document_loaders/fs/docx'
class Docx_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Docx_DocumentLoaders implements INode {
constructor() {
this.label = 'Docx File'
this.name = 'docxFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'Docx.png'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Figma/Figma.ts b/packages/components/nodes/documentloaders/Figma/Figma.ts
index 388c4ee0..3d313044 100644
--- a/packages/components/nodes/documentloaders/Figma/Figma.ts
+++ b/packages/components/nodes/documentloaders/Figma/Figma.ts
@@ -1,42 +1,50 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getCredentialData, getCredentialParam } from '../../../src'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { FigmaFileLoader, FigmaLoaderParams } from 'langchain/document_loaders/web/figma'
class Figma_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Figma'
this.name = 'figma'
+ this.version = 1.0
this.type = 'Document'
- this.icon = 'figma.png'
+ this.icon = 'figma.svg'
this.category = 'Document Loaders'
this.description = 'Load data from a Figma file'
this.baseClasses = [this.type]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['figmaApi']
+ }
this.inputs = [
- {
- label: 'Access Token',
- name: 'accessToken',
- type: 'password',
- placeholder: ''
- },
{
label: 'File Key',
name: 'fileKey',
type: 'string',
- placeholder: 'key'
+ placeholder: 'key',
+ description:
+ 'The file key can be read from any Figma file URL: https://www.figma.com/file/:key/:title. For example, in https://www.figma.com/file/12345/Website, the file key is 12345'
},
{
label: 'Node IDs',
name: 'nodeIds',
type: 'string',
- placeholder: '0, 1, 2'
+ placeholder: '0, 1, 2',
+ description:
+ 'A list of Node IDs, seperated by comma. Refer to official guide on how to get Node IDs'
},
{
label: 'Recursive',
@@ -60,18 +68,20 @@ class Figma_DocumentLoaders implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const accessToken = nodeData.inputs?.accessToken as string
- const nodeIds = (nodeData.inputs?.nodeIds as string)?.split(',') || []
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const nodeIds = (nodeData.inputs?.nodeIds as string)?.trim().split(',') || []
const fileKey = nodeData.inputs?.fileKey as string
- const options: FigmaLoaderParams = {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
+
+ const figmaOptions: FigmaLoaderParams = {
accessToken,
nodeIds,
fileKey
}
- const loader = new FigmaFileLoader(options)
+ const loader = new FigmaFileLoader(figmaOptions)
const docs = await loader.load()
return docs
diff --git a/packages/components/nodes/documentloaders/Figma/figma.png b/packages/components/nodes/documentloaders/Figma/figma.png
deleted file mode 100644
index 72372ddf..00000000
Binary files a/packages/components/nodes/documentloaders/Figma/figma.png and /dev/null differ
diff --git a/packages/components/nodes/documentloaders/Figma/figma.svg b/packages/components/nodes/documentloaders/Figma/figma.svg
new file mode 100644
index 00000000..c4f85674
--- /dev/null
+++ b/packages/components/nodes/documentloaders/Figma/figma.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/documentloaders/Folder/Folder.ts b/packages/components/nodes/documentloaders/Folder/Folder.ts
index 2290133e..83bffd18 100644
--- a/packages/components/nodes/documentloaders/Folder/Folder.ts
+++ b/packages/components/nodes/documentloaders/Folder/Folder.ts
@@ -10,6 +10,7 @@ import { DocxLoader } from 'langchain/document_loaders/fs/docx'
class Folder_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -20,6 +21,7 @@ class Folder_DocumentLoaders implements INode {
constructor() {
this.label = 'Folder with Files'
this.name = 'folderFiles'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'folder.svg'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Gitbook/Gitbook.ts b/packages/components/nodes/documentloaders/Gitbook/Gitbook.ts
new file mode 100644
index 00000000..181fa48d
--- /dev/null
+++ b/packages/components/nodes/documentloaders/Gitbook/Gitbook.ts
@@ -0,0 +1,84 @@
+import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { TextSplitter } from 'langchain/text_splitter'
+import { GitbookLoader } from 'langchain/document_loaders/web/gitbook'
+
+class Gitbook_DocumentLoaders implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs?: INodeParams[]
+
+ constructor() {
+ this.label = 'GitBook'
+ this.name = 'gitbook'
+ this.version = 1.0
+ this.type = 'Document'
+ this.icon = 'gitbook.svg'
+ this.category = 'Document Loaders'
+ this.description = `Load data from GitBook`
+ this.baseClasses = [this.type]
+ this.inputs = [
+ {
+ label: 'Web Path',
+ name: 'webPath',
+ type: 'string',
+ placeholder: 'https://docs.gitbook.com/product-tour/navigation',
+ description: 'If want to load all paths from the GitBook provide only root path e.g.https://docs.gitbook.com/ '
+ },
+ {
+ label: 'Should Load All Paths',
+ name: 'shouldLoadAllPaths',
+ type: 'boolean',
+ description: 'Load from all paths in a given GitBook',
+ optional: true
+ },
+ {
+ label: 'Text Splitter',
+ name: 'textSplitter',
+ type: 'TextSplitter',
+ optional: true
+ },
+ {
+ label: 'Metadata',
+ name: 'metadata',
+ type: 'json',
+ optional: true,
+ additionalParams: true
+ }
+ ]
+ }
+ async init(nodeData: INodeData): Promise {
+ const webPath = nodeData.inputs?.webPath as string
+ const shouldLoadAllPaths = nodeData.inputs?.shouldLoadAllPaths as boolean
+ const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
+ const metadata = nodeData.inputs?.metadata
+
+ const loader = shouldLoadAllPaths ? new GitbookLoader(webPath, { shouldLoadAllPaths }) : new GitbookLoader(webPath)
+
+ const docs = textSplitter ? await loader.loadAndSplit() : await loader.load()
+
+ if (metadata) {
+ const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata)
+ return docs.map((doc) => {
+ return {
+ ...doc,
+ metadata: {
+ ...doc.metadata,
+ ...parsedMetadata
+ }
+ }
+ })
+ }
+
+ return docs
+ }
+}
+
+module.exports = {
+ nodeClass: Gitbook_DocumentLoaders
+}
diff --git a/packages/components/nodes/documentloaders/Gitbook/gitbook.svg b/packages/components/nodes/documentloaders/Gitbook/gitbook.svg
new file mode 100644
index 00000000..df16237a
--- /dev/null
+++ b/packages/components/nodes/documentloaders/Gitbook/gitbook.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/documentloaders/Github/Github.ts b/packages/components/nodes/documentloaders/Github/Github.ts
index bbaad3cb..079bffb0 100644
--- a/packages/components/nodes/documentloaders/Github/Github.ts
+++ b/packages/components/nodes/documentloaders/Github/Github.ts
@@ -1,25 +1,37 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
import { GithubRepoLoader, GithubRepoLoaderParams } from 'langchain/document_loaders/web/github'
+import { getCredentialData, getCredentialParam } from '../../../src'
class Github_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Github'
this.name = 'github'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'github.png'
this.category = 'Document Loaders'
this.description = `Load data from a GitHub repository`
this.baseClasses = [this.type]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Only needed when accessing private repo',
+ optional: true,
+ credentialNames: ['githubApi']
+ }
this.inputs = [
{
label: 'Repo Link',
@@ -33,13 +45,6 @@ class Github_DocumentLoaders implements INode {
type: 'string',
default: 'main'
},
- {
- label: 'Access Token',
- name: 'accessToken',
- type: 'password',
- placeholder: '',
- optional: true
- },
{
label: 'Recursive',
name: 'recursive',
@@ -62,23 +67,25 @@ class Github_DocumentLoaders implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const repoLink = nodeData.inputs?.repoLink as string
const branch = nodeData.inputs?.branch as string
const recursive = nodeData.inputs?.recursive as boolean
- const accessToken = nodeData.inputs?.accessToken as string
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const metadata = nodeData.inputs?.metadata
- const options: GithubRepoLoaderParams = {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
+
+ const githubOptions: GithubRepoLoaderParams = {
branch,
recursive,
unknown: 'warn'
}
- if (accessToken) options.accessToken = accessToken
+ if (accessToken) githubOptions.accessToken = accessToken
- const loader = new GithubRepoLoader(repoLink, options)
+ const loader = new GithubRepoLoader(repoLink, githubOptions)
const docs = textSplitter ? await loader.loadAndSplit(textSplitter) : await loader.load()
if (metadata) {
diff --git a/packages/components/nodes/documentloaders/Json/Json.ts b/packages/components/nodes/documentloaders/Json/Json.ts
index 9177df5c..43051251 100644
--- a/packages/components/nodes/documentloaders/Json/Json.ts
+++ b/packages/components/nodes/documentloaders/Json/Json.ts
@@ -5,6 +5,7 @@ import { JSONLoader } from 'langchain/document_loaders/fs/json'
class Json_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Json_DocumentLoaders implements INode {
constructor() {
this.label = 'Json File'
this.name = 'jsonFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'json.svg'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Jsonlines/Jsonlines.ts b/packages/components/nodes/documentloaders/Jsonlines/Jsonlines.ts
index 4af8c2ce..fcc2fae9 100644
--- a/packages/components/nodes/documentloaders/Jsonlines/Jsonlines.ts
+++ b/packages/components/nodes/documentloaders/Jsonlines/Jsonlines.ts
@@ -5,6 +5,7 @@ import { JSONLinesLoader } from 'langchain/document_loaders/fs/json'
class Jsonlines_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Jsonlines_DocumentLoaders implements INode {
constructor() {
this.label = 'Json Lines File'
this.name = 'jsonlinesFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'jsonlines.svg'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/NotionDB/NotionDB.ts b/packages/components/nodes/documentloaders/Notion/NotionDB.ts
similarity index 60%
rename from packages/components/nodes/documentloaders/NotionDB/NotionDB.ts
rename to packages/components/nodes/documentloaders/Notion/NotionDB.ts
index 71e5e507..74879dd2 100644
--- a/packages/components/nodes/documentloaders/NotionDB/NotionDB.ts
+++ b/packages/components/nodes/documentloaders/Notion/NotionDB.ts
@@ -1,25 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
-import { NotionDBLoader, NotionDBLoaderParams } from 'langchain/document_loaders/web/notiondb'
+import { NotionAPILoader, NotionAPILoaderOptions } from 'langchain/document_loaders/web/notionapi'
+import { getCredentialData, getCredentialParam } from '../../../src'
class NotionDB_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Notion Database'
this.name = 'notionDB'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'notion.png'
this.category = 'Document Loaders'
- this.description = 'Load data from Notion Database ID'
+ this.description = 'Load data from Notion Database (each row is a separate document with all properties as metadata)'
this.baseClasses = [this.type]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['notionApi']
+ }
this.inputs = [
{
label: 'Text Splitter',
@@ -31,21 +41,7 @@ class NotionDB_DocumentLoaders implements INode {
label: 'Notion Database Id',
name: 'databaseId',
type: 'string',
- description:
- 'If your URL looks like - https://www.notion.so/?v=, then is the database ID'
- },
- {
- label: 'Notion Integration Token',
- name: 'notionIntegrationToken',
- type: 'password',
- description:
- 'You can find integration token here'
- },
- {
- label: 'Page Size Limit',
- name: 'pageSizeLimit',
- type: 'number',
- default: 10
+ description: 'If your URL looks like - https://www.notion.so/abcdefh?v=long_hash_2, then abcdefh is the database ID'
},
{
label: 'Metadata',
@@ -57,19 +53,22 @@ class NotionDB_DocumentLoaders implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const databaseId = nodeData.inputs?.databaseId as string
- const notionIntegrationToken = nodeData.inputs?.notionIntegrationToken as string
- const pageSizeLimit = nodeData.inputs?.pageSizeLimit as string
const metadata = nodeData.inputs?.metadata
- const obj: NotionDBLoaderParams = {
- pageSizeLimit: pageSizeLimit ? parseInt(pageSizeLimit, 10) : 10,
- databaseId,
- notionIntegrationToken
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const notionIntegrationToken = getCredentialParam('notionIntegrationToken', credentialData, nodeData)
+
+ const obj: NotionAPILoaderOptions = {
+ clientOptions: {
+ auth: notionIntegrationToken
+ },
+ id: databaseId,
+ type: 'database'
}
- const loader = new NotionDBLoader(obj)
+ const loader = new NotionAPILoader(obj)
let docs = []
if (textSplitter) {
diff --git a/packages/components/nodes/documentloaders/NotionFolder/NotionFolder.ts b/packages/components/nodes/documentloaders/Notion/NotionFolder.ts
similarity index 98%
rename from packages/components/nodes/documentloaders/NotionFolder/NotionFolder.ts
rename to packages/components/nodes/documentloaders/Notion/NotionFolder.ts
index 11b8165b..8b8254a4 100644
--- a/packages/components/nodes/documentloaders/NotionFolder/NotionFolder.ts
+++ b/packages/components/nodes/documentloaders/Notion/NotionFolder.ts
@@ -5,6 +5,7 @@ import { NotionLoader } from 'langchain/document_loaders/fs/notion'
class NotionFolder_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class NotionFolder_DocumentLoaders implements INode {
constructor() {
this.label = 'Notion Folder'
this.name = 'notionFolder'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'notion.png'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Notion/NotionPage.ts b/packages/components/nodes/documentloaders/Notion/NotionPage.ts
new file mode 100644
index 00000000..b45067ab
--- /dev/null
+++ b/packages/components/nodes/documentloaders/Notion/NotionPage.ts
@@ -0,0 +1,101 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { TextSplitter } from 'langchain/text_splitter'
+import { NotionAPILoader, NotionAPILoaderOptions } from 'langchain/document_loaders/web/notionapi'
+import { getCredentialData, getCredentialParam } from '../../../src'
+
+class NotionPage_DocumentLoaders implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Notion Page'
+ this.name = 'notionPage'
+ this.version = 1.0
+ this.type = 'Document'
+ this.icon = 'notion.png'
+ this.category = 'Document Loaders'
+ this.description = 'Load data from Notion Page (including child pages all as separate documents)'
+ this.baseClasses = [this.type]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['notionApi']
+ }
+ this.inputs = [
+ {
+ label: 'Text Splitter',
+ name: 'textSplitter',
+ type: 'TextSplitter',
+ optional: true
+ },
+ {
+ label: 'Notion Page Id',
+ name: 'pageId',
+ type: 'string',
+ description:
+ 'The last The 32 char hex in the url path. For example: https://www.notion.so/skarard/LangChain-Notion-API-b34ca03f219c4420a6046fc4bdfdf7b4, b34ca03f219c4420a6046fc4bdfdf7b4 is the Page ID'
+ },
+ {
+ label: 'Metadata',
+ name: 'metadata',
+ type: 'json',
+ optional: true,
+ additionalParams: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
+ const pageId = nodeData.inputs?.pageId as string
+ const metadata = nodeData.inputs?.metadata
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const notionIntegrationToken = getCredentialParam('notionIntegrationToken', credentialData, nodeData)
+
+ const obj: NotionAPILoaderOptions = {
+ clientOptions: {
+ auth: notionIntegrationToken
+ },
+ id: pageId,
+ type: 'page'
+ }
+ const loader = new NotionAPILoader(obj)
+
+ let docs = []
+ if (textSplitter) {
+ docs = await loader.loadAndSplit(textSplitter)
+ } else {
+ docs = await loader.load()
+ }
+
+ if (metadata) {
+ const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata)
+ let finaldocs = []
+ for (const doc of docs) {
+ const newdoc = {
+ ...doc,
+ metadata: {
+ ...doc.metadata,
+ ...parsedMetadata
+ }
+ }
+ finaldocs.push(newdoc)
+ }
+ return finaldocs
+ }
+
+ return docs
+ }
+}
+
+module.exports = { nodeClass: NotionPage_DocumentLoaders }
diff --git a/packages/components/nodes/documentloaders/NotionDB/notion.png b/packages/components/nodes/documentloaders/Notion/notion.png
similarity index 100%
rename from packages/components/nodes/documentloaders/NotionDB/notion.png
rename to packages/components/nodes/documentloaders/Notion/notion.png
diff --git a/packages/components/nodes/documentloaders/NotionFolder/notion.png b/packages/components/nodes/documentloaders/NotionFolder/notion.png
deleted file mode 100644
index 39105167..00000000
Binary files a/packages/components/nodes/documentloaders/NotionFolder/notion.png and /dev/null differ
diff --git a/packages/components/nodes/documentloaders/Pdf/Pdf.ts b/packages/components/nodes/documentloaders/Pdf/Pdf.ts
index ddb7edb8..a9f6ab23 100644
--- a/packages/components/nodes/documentloaders/Pdf/Pdf.ts
+++ b/packages/components/nodes/documentloaders/Pdf/Pdf.ts
@@ -5,6 +5,7 @@ import { PDFLoader } from 'langchain/document_loaders/fs/pdf'
class Pdf_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Pdf_DocumentLoaders implements INode {
constructor() {
this.label = 'Pdf File'
this.name = 'pdfFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'pdf.svg'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Playwright/Playwright.ts b/packages/components/nodes/documentloaders/Playwright/Playwright.ts
index 6b7790af..3399574d 100644
--- a/packages/components/nodes/documentloaders/Playwright/Playwright.ts
+++ b/packages/components/nodes/documentloaders/Playwright/Playwright.ts
@@ -2,11 +2,12 @@ import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
import { PlaywrightWebBaseLoader } from 'langchain/document_loaders/web/playwright'
import { test } from 'linkifyjs'
-import { getAvailableURLs } from '../../../src'
+import { webCrawl, xmlScrape } from '../../../src'
class Playwright_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class Playwright_DocumentLoaders implements INode {
constructor() {
this.label = 'Playwright Web Scraper'
this.name = 'playwrightWebScraper'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'playwright.svg'
this.category = 'Document Loaders'
@@ -35,19 +37,34 @@ class Playwright_DocumentLoaders implements INode {
optional: true
},
{
- label: 'Web Scrap for Relative Links',
- name: 'webScrap',
- type: 'boolean',
+ label: 'Get Relative Links Method',
+ name: 'relativeLinksMethod',
+ type: 'options',
+ description: 'Select a method to retrieve relative links',
+ options: [
+ {
+ label: 'Web Crawl',
+ name: 'webCrawl',
+ description: 'Crawl relative links from HTML URL'
+ },
+ {
+ label: 'Scrape XML Sitemap',
+ name: 'scrapeXMLSitemap',
+ description: 'Scrape relative links from XML sitemap URL'
+ }
+ ],
optional: true,
additionalParams: true
},
{
- label: 'Web Scrap Links Limit',
+ label: 'Get Relative Links Limit',
name: 'limit',
type: 'number',
- default: 10,
optional: true,
- additionalParams: true
+ additionalParams: true,
+ description:
+ 'Only used when "Get Relative Links Method" is selected. Set 0 to retrieve all relative links, default limit is 10.',
+ warning: `Retreiving all links might take long time, and all links will be upserted again if the flow's state changed (eg: different URL, chunk size, etc)`
},
{
label: 'Metadata',
@@ -62,7 +79,7 @@ class Playwright_DocumentLoaders implements INode {
async init(nodeData: INodeData): Promise {
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const metadata = nodeData.inputs?.metadata
- const webScrap = nodeData.inputs?.webScrap as boolean
+ const relativeLinksMethod = nodeData.inputs?.relativeLinksMethod as string
let limit = nodeData.inputs?.limit as string
let url = nodeData.inputs?.url as string
@@ -71,25 +88,34 @@ class Playwright_DocumentLoaders implements INode {
throw new Error('Invalid URL')
}
- const playwrightLoader = async (url: string): Promise => {
- let docs = []
- const loader = new PlaywrightWebBaseLoader(url)
- if (textSplitter) {
- docs = await loader.loadAndSplit(textSplitter)
- } else {
- docs = await loader.load()
+ async function playwrightLoader(url: string): Promise {
+ try {
+ let docs = []
+ const loader = new PlaywrightWebBaseLoader(url)
+ if (textSplitter) {
+ docs = await loader.loadAndSplit(textSplitter)
+ } else {
+ docs = await loader.load()
+ }
+ return docs
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error in PlaywrightWebBaseLoader: ${err.message}, on page: ${url}`)
}
- return docs
}
- let availableUrls: string[]
let docs = []
- if (webScrap) {
+ if (relativeLinksMethod) {
+ if (process.env.DEBUG === 'true') console.info(`Start ${relativeLinksMethod}`)
if (!limit) limit = '10'
- availableUrls = await getAvailableURLs(url, parseInt(limit))
- for (let i = 0; i < availableUrls.length; i++) {
- docs.push(...(await playwrightLoader(availableUrls[i])))
+ else if (parseInt(limit) < 0) throw new Error('Limit cannot be less than 0')
+ const pages: string[] =
+ relativeLinksMethod === 'webCrawl' ? await webCrawl(url, parseInt(limit)) : await xmlScrape(url, parseInt(limit))
+ if (process.env.DEBUG === 'true') console.info(`pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
+ if (!pages || pages.length === 0) throw new Error('No relative links found')
+ for (const page of pages) {
+ docs.push(...(await playwrightLoader(page)))
}
+ if (process.env.DEBUG === 'true') console.info(`Finish ${relativeLinksMethod}`)
} else {
docs = await playwrightLoader(url)
}
diff --git a/packages/components/nodes/documentloaders/Puppeteer/Puppeteer.ts b/packages/components/nodes/documentloaders/Puppeteer/Puppeteer.ts
index 1331c736..ea6280db 100644
--- a/packages/components/nodes/documentloaders/Puppeteer/Puppeteer.ts
+++ b/packages/components/nodes/documentloaders/Puppeteer/Puppeteer.ts
@@ -2,11 +2,12 @@ import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { TextSplitter } from 'langchain/text_splitter'
import { PuppeteerWebBaseLoader } from 'langchain/document_loaders/web/puppeteer'
import { test } from 'linkifyjs'
-import { getAvailableURLs } from '../../../src'
+import { webCrawl, xmlScrape } from '../../../src'
class Puppeteer_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class Puppeteer_DocumentLoaders implements INode {
constructor() {
this.label = 'Puppeteer Web Scraper'
this.name = 'puppeteerWebScraper'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'puppeteer.svg'
this.category = 'Document Loaders'
@@ -35,19 +37,34 @@ class Puppeteer_DocumentLoaders implements INode {
optional: true
},
{
- label: 'Web Scrape for Relative Links',
- name: 'webScrape',
- type: 'boolean',
+ label: 'Get Relative Links Method',
+ name: 'relativeLinksMethod',
+ type: 'options',
+ description: 'Select a method to retrieve relative links',
+ options: [
+ {
+ label: 'Web Crawl',
+ name: 'webCrawl',
+ description: 'Crawl relative links from HTML URL'
+ },
+ {
+ label: 'Scrape XML Sitemap',
+ name: 'scrapeXMLSitemap',
+ description: 'Scrape relative links from XML sitemap URL'
+ }
+ ],
optional: true,
additionalParams: true
},
{
- label: 'Web Scrape Links Limit',
+ label: 'Get Relative Links Limit',
name: 'limit',
type: 'number',
- default: 10,
optional: true,
- additionalParams: true
+ additionalParams: true,
+ description:
+ 'Only used when "Get Relative Links Method" is selected. Set 0 to retrieve all relative links, default limit is 10.',
+ warning: `Retreiving all links might take long time, and all links will be upserted again if the flow's state changed (eg: different URL, chunk size, etc)`
},
{
label: 'Metadata',
@@ -62,7 +79,7 @@ class Puppeteer_DocumentLoaders implements INode {
async init(nodeData: INodeData): Promise {
const textSplitter = nodeData.inputs?.textSplitter as TextSplitter
const metadata = nodeData.inputs?.metadata
- const webScrape = nodeData.inputs?.webScrape as boolean
+ const relativeLinksMethod = nodeData.inputs?.relativeLinksMethod as string
let limit = nodeData.inputs?.limit as string
let url = nodeData.inputs?.url as string
@@ -71,30 +88,39 @@ class Puppeteer_DocumentLoaders implements INode {
throw new Error('Invalid URL')
}
- const puppeteerLoader = async (url: string): Promise => {
- let docs = []
- const loader = new PuppeteerWebBaseLoader(url)
- if (textSplitter) {
- docs = await loader.loadAndSplit(textSplitter)
- } else {
- docs = await loader.load()
+ async function puppeteerLoader(url: string): Promise {
+ try {
+ let docs = []
+ const loader = new PuppeteerWebBaseLoader(url, {
+ launchOptions: {
+ args: ['--no-sandbox'],
+ headless: 'new'
+ }
+ })
+ if (textSplitter) {
+ docs = await loader.loadAndSplit(textSplitter)
+ } else {
+ docs = await loader.load()
+ }
+ return docs
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error in PuppeteerWebBaseLoader: ${err.message}, on page: ${url}`)
}
- return docs
}
- let availableUrls: string[]
let docs = []
- if (webScrape) {
+ if (relativeLinksMethod) {
+ if (process.env.DEBUG === 'true') console.info(`Start ${relativeLinksMethod}`)
if (!limit) limit = '10'
- availableUrls = await getAvailableURLs(url, parseInt(limit))
- for (let i = 0; i < availableUrls.length; i++) {
- try {
- docs.push(...(await puppeteerLoader(availableUrls[i])))
- } catch (error) {
- console.error('Error loading url with puppeteer. URL: ', availableUrls[i], 'Error: ', error)
- continue
- }
+ else if (parseInt(limit) < 0) throw new Error('Limit cannot be less than 0')
+ const pages: string[] =
+ relativeLinksMethod === 'webCrawl' ? await webCrawl(url, parseInt(limit)) : await xmlScrape(url, parseInt(limit))
+ if (process.env.DEBUG === 'true') console.info(`pages: ${JSON.stringify(pages)}, length: ${pages.length}`)
+ if (!pages || pages.length === 0) throw new Error('No relative links found')
+ for (const page of pages) {
+ docs.push(...(await puppeteerLoader(page)))
}
+ if (process.env.DEBUG === 'true') console.info(`Finish ${relativeLinksMethod}`)
} else {
docs = await puppeteerLoader(url)
}
diff --git a/packages/components/nodes/documentloaders/Subtitles/Subtitles.ts b/packages/components/nodes/documentloaders/Subtitles/Subtitles.ts
index 0f60e151..f85898b3 100644
--- a/packages/components/nodes/documentloaders/Subtitles/Subtitles.ts
+++ b/packages/components/nodes/documentloaders/Subtitles/Subtitles.ts
@@ -5,6 +5,7 @@ import { SRTLoader } from 'langchain/document_loaders/fs/srt'
class Subtitles_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Subtitles_DocumentLoaders implements INode {
constructor() {
this.label = 'Subtitles File'
this.name = 'subtitlesFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'subtitlesFile.svg'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/documentloaders/Text/Text.ts b/packages/components/nodes/documentloaders/Text/Text.ts
index 63e7e0e2..dacf087c 100644
--- a/packages/components/nodes/documentloaders/Text/Text.ts
+++ b/packages/components/nodes/documentloaders/Text/Text.ts
@@ -5,6 +5,7 @@ import { TextLoader } from 'langchain/document_loaders/fs/text'
class Text_DocumentLoaders implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class Text_DocumentLoaders implements INode {
constructor() {
this.label = 'Text File'
this.name = 'textFile'
+ this.version = 1.0
this.type = 'Document'
this.icon = 'textFile.svg'
this.category = 'Document Loaders'
diff --git a/packages/components/nodes/embeddings/AzureOpenAIEmbedding/Azure.svg b/packages/components/nodes/embeddings/AzureOpenAIEmbedding/Azure.svg
index 51eb6253..47ad8c44 100644
--- a/packages/components/nodes/embeddings/AzureOpenAIEmbedding/Azure.svg
+++ b/packages/components/nodes/embeddings/AzureOpenAIEmbedding/Azure.svg
@@ -1,5 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts b/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts
index 2a211622..b70caa4c 100644
--- a/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts
+++ b/packages/components/nodes/embeddings/AzureOpenAIEmbedding/AzureOpenAIEmbedding.ts
@@ -1,52 +1,36 @@
import { AzureOpenAIInput } from 'langchain/chat_models/openai'
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { OpenAIEmbeddings, OpenAIEmbeddingsParams } from 'langchain/embeddings/openai'
class AzureOpenAIEmbedding_Embeddings implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Azure OpenAI Embeddings'
this.name = 'azureOpenAIEmbeddings'
+ this.version = 1.0
this.type = 'AzureOpenAIEmbeddings'
this.icon = 'Azure.svg'
this.category = 'Embeddings'
this.description = 'Azure OpenAI API to generate embeddings for a given text'
this.baseClasses = [this.type, ...getBaseClasses(OpenAIEmbeddings)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['azureOpenAIApi']
+ }
this.inputs = [
- {
- label: 'Azure OpenAI Api Key',
- name: 'azureOpenAIApiKey',
- type: 'password'
- },
- {
- label: 'Azure OpenAI Api Instance Name',
- name: 'azureOpenAIApiInstanceName',
- type: 'string',
- placeholder: 'YOUR-INSTANCE-NAME'
- },
- {
- label: 'Azure OpenAI Api Deployment Name',
- name: 'azureOpenAIApiDeploymentName',
- type: 'string',
- placeholder: 'YOUR-DEPLOYMENT-NAME'
- },
- {
- label: 'Azure OpenAI Api Version',
- name: 'azureOpenAIApiVersion',
- type: 'string',
- placeholder: 'YOUR-API-VERSION',
- description:
- 'Description of Supported API Versions. Please refer examples'
- },
{
label: 'Batch Size',
name: 'batchSize',
@@ -65,14 +49,16 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const azureOpenAIApiKey = nodeData.inputs?.azureOpenAIApiKey as string
- const azureOpenAIApiInstanceName = nodeData.inputs?.azureOpenAIApiInstanceName as string
- const azureOpenAIApiDeploymentName = nodeData.inputs?.azureOpenAIApiDeploymentName as string
- const azureOpenAIApiVersion = nodeData.inputs?.azureOpenAIApiVersion as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const batchSize = nodeData.inputs?.batchSize as string
const timeout = nodeData.inputs?.timeout as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData)
+ const azureOpenAIApiInstanceName = getCredentialParam('azureOpenAIApiInstanceName', credentialData, nodeData)
+ const azureOpenAIApiDeploymentName = getCredentialParam('azureOpenAIApiDeploymentName', credentialData, nodeData)
+ const azureOpenAIApiVersion = getCredentialParam('azureOpenAIApiVersion', credentialData, nodeData)
+
const obj: Partial & Partial = {
azureOpenAIApiKey,
azureOpenAIApiInstanceName,
diff --git a/packages/components/nodes/embeddings/CohereEmbedding/CohereEmbedding.ts b/packages/components/nodes/embeddings/CohereEmbedding/CohereEmbedding.ts
index 344713a4..b42a0357 100644
--- a/packages/components/nodes/embeddings/CohereEmbedding/CohereEmbedding.ts
+++ b/packages/components/nodes/embeddings/CohereEmbedding/CohereEmbedding.ts
@@ -1,31 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { CohereEmbeddings, CohereEmbeddingsParams } from 'langchain/embeddings/cohere'
class CohereEmbedding_Embeddings implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Cohere Embeddings'
this.name = 'cohereEmbeddings'
+ this.version = 1.0
this.type = 'CohereEmbeddings'
this.icon = 'cohere.png'
this.category = 'Embeddings'
this.description = 'Cohere API to generate embeddings for a given text'
this.baseClasses = [this.type, ...getBaseClasses(CohereEmbeddings)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['cohereApi']
+ }
this.inputs = [
- {
- label: 'Cohere API Key',
- name: 'cohereApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
@@ -50,12 +54,14 @@ class CohereEmbedding_Embeddings implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const apiKey = nodeData.inputs?.cohereApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const modelName = nodeData.inputs?.modelName as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const cohereApiKey = getCredentialParam('cohereApiKey', credentialData, nodeData)
+
const obj: Partial & { apiKey?: string } = {
- apiKey
+ apiKey: cohereApiKey
}
if (modelName) obj.modelName = modelName
diff --git a/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/HuggingFaceInferenceEmbedding.ts b/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/HuggingFaceInferenceEmbedding.ts
index 6f14325a..6d75b955 100644
--- a/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/HuggingFaceInferenceEmbedding.ts
+++ b/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/HuggingFaceInferenceEmbedding.ts
@@ -1,49 +1,67 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
-import { HuggingFaceInferenceEmbeddings, HuggingFaceInferenceEmbeddingsParams } from 'langchain/embeddings/hf'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { HuggingFaceInferenceEmbeddings, HuggingFaceInferenceEmbeddingsParams } from './core'
class HuggingFaceInferenceEmbedding_Embeddings implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'HuggingFace Inference Embeddings'
this.name = 'huggingFaceInferenceEmbeddings'
+ this.version = 1.0
this.type = 'HuggingFaceInferenceEmbeddings'
this.icon = 'huggingface.png'
this.category = 'Embeddings'
this.description = 'HuggingFace Inference API to generate embeddings for a given text'
this.baseClasses = [this.type, ...getBaseClasses(HuggingFaceInferenceEmbeddings)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['huggingFaceApi']
+ }
this.inputs = [
- {
- label: 'HuggingFace Api Key',
- name: 'apiKey',
- type: 'password'
- },
{
label: 'Model',
name: 'modelName',
type: 'string',
+ description: 'If using own inference endpoint, leave this blank',
+ placeholder: 'sentence-transformers/distilbert-base-nli-mean-tokens',
+ optional: true
+ },
+ {
+ label: 'Endpoint',
+ name: 'endpoint',
+ type: 'string',
+ placeholder: 'https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/sentence-transformers/all-MiniLM-L6-v2',
+ description: 'Using your own inference endpoint',
optional: true
}
]
}
- async init(nodeData: INodeData): Promise {
- const apiKey = nodeData.inputs?.apiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const modelName = nodeData.inputs?.modelName as string
+ const endpoint = nodeData.inputs?.endpoint as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const huggingFaceApiKey = getCredentialParam('huggingFaceApiKey', credentialData, nodeData)
const obj: Partial = {
- apiKey
+ apiKey: huggingFaceApiKey
}
if (modelName) obj.model = modelName
+ if (endpoint) obj.endpoint = endpoint
const model = new HuggingFaceInferenceEmbeddings(obj)
return model
diff --git a/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/core.ts b/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/core.ts
new file mode 100644
index 00000000..c75658d4
--- /dev/null
+++ b/packages/components/nodes/embeddings/HuggingFaceInferenceEmbedding/core.ts
@@ -0,0 +1,55 @@
+import { HfInference } from '@huggingface/inference'
+import { Embeddings, EmbeddingsParams } from 'langchain/embeddings/base'
+import { getEnvironmentVariable } from '../../../src/utils'
+
+export interface HuggingFaceInferenceEmbeddingsParams extends EmbeddingsParams {
+ apiKey?: string
+ model?: string
+ endpoint?: string
+}
+
+export class HuggingFaceInferenceEmbeddings extends Embeddings implements HuggingFaceInferenceEmbeddingsParams {
+ apiKey?: string
+
+ endpoint?: string
+
+ model: string
+
+ client: HfInference
+
+ constructor(fields?: HuggingFaceInferenceEmbeddingsParams) {
+ super(fields ?? {})
+
+ this.model = fields?.model ?? 'sentence-transformers/distilbert-base-nli-mean-tokens'
+ this.apiKey = fields?.apiKey ?? getEnvironmentVariable('HUGGINGFACEHUB_API_KEY')
+ this.endpoint = fields?.endpoint ?? ''
+ this.client = new HfInference(this.apiKey)
+ if (this.endpoint) this.client.endpoint(this.endpoint)
+ }
+
+ async _embed(texts: string[]): Promise {
+ // replace newlines, which can negatively affect performance.
+ const clean = texts.map((text) => text.replace(/\n/g, ' '))
+ const hf = new HfInference(this.apiKey)
+ const obj: any = {
+ inputs: clean
+ }
+ if (this.endpoint) {
+ hf.endpoint(this.endpoint)
+ } else {
+ obj.model = this.model
+ }
+
+ const res = await this.caller.callWithOptions({}, hf.featureExtraction.bind(hf), obj)
+ return res as number[][]
+ }
+
+ async embedQuery(document: string): Promise {
+ const res = await this._embed([document])
+ return res[0]
+ }
+
+ async embedDocuments(documents: string[]): Promise {
+ return this._embed(documents)
+ }
+}
diff --git a/packages/components/nodes/embeddings/LocalAIEmbedding/LocalAIEmbedding.ts b/packages/components/nodes/embeddings/LocalAIEmbedding/LocalAIEmbedding.ts
index 7fb2a798..557e35d6 100644
--- a/packages/components/nodes/embeddings/LocalAIEmbedding/LocalAIEmbedding.ts
+++ b/packages/components/nodes/embeddings/LocalAIEmbedding/LocalAIEmbedding.ts
@@ -4,6 +4,7 @@ import { OpenAIEmbeddings, OpenAIEmbeddingsParams } from 'langchain/embeddings/o
class LocalAIEmbedding_Embeddings implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
@@ -14,6 +15,7 @@ class LocalAIEmbedding_Embeddings implements INode {
constructor() {
this.label = 'LocalAI Embeddings'
this.name = 'localAIEmbeddings'
+ this.version = 1.0
this.type = 'LocalAI Embeddings'
this.icon = 'localai.png'
this.category = 'Embeddings'
diff --git a/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts b/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts
index 0fd08973..d21b6dca 100644
--- a/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts
+++ b/packages/components/nodes/embeddings/OpenAIEmbedding/OpenAIEmbedding.ts
@@ -1,31 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { OpenAIEmbeddings, OpenAIEmbeddingsParams } from 'langchain/embeddings/openai'
class OpenAIEmbedding_Embeddings implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'OpenAI Embeddings'
this.name = 'openAIEmbeddings'
+ this.version = 1.0
this.type = 'OpenAIEmbeddings'
this.icon = 'openai.png'
this.category = 'Embeddings'
this.description = 'OpenAI API to generate embeddings for a given text'
this.baseClasses = [this.type, ...getBaseClasses(OpenAIEmbeddings)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['openAIApi']
+ }
this.inputs = [
- {
- label: 'OpenAI Api Key',
- name: 'openAIApiKey',
- type: 'password'
- },
{
label: 'Strip New Lines',
name: 'stripNewLines',
@@ -57,13 +61,15 @@ class OpenAIEmbedding_Embeddings implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const openAIApiKey = nodeData.inputs?.openAIApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const stripNewLines = nodeData.inputs?.stripNewLines as boolean
const batchSize = nodeData.inputs?.batchSize as string
const timeout = nodeData.inputs?.timeout as string
const basePath = nodeData.inputs?.basepath as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData)
+
const obj: Partial & { openAIApiKey?: string } = {
openAIApiKey
}
diff --git a/packages/components/nodes/llms/Azure OpenAI/Azure.svg b/packages/components/nodes/llms/Azure OpenAI/Azure.svg
index 51eb6253..47ad8c44 100644
--- a/packages/components/nodes/llms/Azure OpenAI/Azure.svg
+++ b/packages/components/nodes/llms/Azure OpenAI/Azure.svg
@@ -1,5 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/packages/components/nodes/llms/Azure OpenAI/AzureOpenAI.ts b/packages/components/nodes/llms/Azure OpenAI/AzureOpenAI.ts
index c19aa83a..f48c4642 100644
--- a/packages/components/nodes/llms/Azure OpenAI/AzureOpenAI.ts
+++ b/packages/components/nodes/llms/Azure OpenAI/AzureOpenAI.ts
@@ -1,31 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { AzureOpenAIInput, OpenAI, OpenAIInput } from 'langchain/llms/openai'
class AzureOpenAI_LLMs implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Azure OpenAI'
this.name = 'azureOpenAI'
+ this.version = 1.0
this.type = 'AzureOpenAI'
this.icon = 'Azure.svg'
this.category = 'LLMs'
this.description = 'Wrapper around Azure OpenAI large language models'
this.baseClasses = [this.type, ...getBaseClasses(OpenAI)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['azureOpenAIApi']
+ }
this.inputs = [
- {
- label: 'Azure OpenAI Api Key',
- name: 'azureOpenAIApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
@@ -87,41 +91,15 @@ class AzureOpenAI_LLMs implements INode {
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.9,
optional: true
},
- {
- label: 'Azure OpenAI Api Instance Name',
- name: 'azureOpenAIApiInstanceName',
- type: 'string',
- placeholder: 'YOUR-INSTANCE-NAME'
- },
- {
- label: 'Azure OpenAI Api Deployment Name',
- name: 'azureOpenAIApiDeploymentName',
- type: 'string',
- placeholder: 'YOUR-DEPLOYMENT-NAME'
- },
- {
- label: 'Azure OpenAI Api Version',
- name: 'azureOpenAIApiVersion',
- type: 'options',
- options: [
- {
- label: '2023-03-15-preview',
- name: '2023-03-15-preview'
- },
- {
- label: '2022-12-01',
- name: '2022-12-01'
- }
- ],
- default: '2023-03-15-preview'
- },
{
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -129,6 +107,7 @@ class AzureOpenAI_LLMs implements INode {
label: 'Top Probability',
name: 'topP',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -136,6 +115,7 @@ class AzureOpenAI_LLMs implements INode {
label: 'Best Of',
name: 'bestOf',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -143,6 +123,7 @@ class AzureOpenAI_LLMs implements INode {
label: 'Frequency Penalty',
name: 'frequencyPenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -150,6 +131,7 @@ class AzureOpenAI_LLMs implements INode {
label: 'Presence Penalty',
name: 'presencePenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -157,19 +139,16 @@ class AzureOpenAI_LLMs implements INode {
label: 'Timeout',
name: 'timeout',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
}
]
}
- async init(nodeData: INodeData): Promise {
- const azureOpenAIApiKey = nodeData.inputs?.azureOpenAIApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const temperature = nodeData.inputs?.temperature as string
const modelName = nodeData.inputs?.modelName as string
- const azureOpenAIApiInstanceName = nodeData.inputs?.azureOpenAIApiInstanceName as string
- const azureOpenAIApiDeploymentName = nodeData.inputs?.azureOpenAIApiDeploymentName as string
- const azureOpenAIApiVersion = nodeData.inputs?.azureOpenAIApiVersion as string
const maxTokens = nodeData.inputs?.maxTokens as string
const topP = nodeData.inputs?.topP as string
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
@@ -178,8 +157,14 @@ class AzureOpenAI_LLMs implements INode {
const bestOf = nodeData.inputs?.bestOf as string
const streaming = nodeData.inputs?.streaming as boolean
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData)
+ const azureOpenAIApiInstanceName = getCredentialParam('azureOpenAIApiInstanceName', credentialData, nodeData)
+ const azureOpenAIApiDeploymentName = getCredentialParam('azureOpenAIApiDeploymentName', credentialData, nodeData)
+ const azureOpenAIApiVersion = getCredentialParam('azureOpenAIApiVersion', credentialData, nodeData)
+
const obj: Partial & Partial = {
- temperature: parseInt(temperature, 10),
+ temperature: parseFloat(temperature),
modelName,
azureOpenAIApiKey,
azureOpenAIApiInstanceName,
@@ -189,9 +174,9 @@ class AzureOpenAI_LLMs implements INode {
}
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (topP) obj.topP = parseInt(topP, 10)
- if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
- if (presencePenalty) obj.presencePenalty = parseInt(presencePenalty, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty)
if (timeout) obj.timeout = parseInt(timeout, 10)
if (bestOf) obj.bestOf = parseInt(bestOf, 10)
diff --git a/packages/components/nodes/llms/Cohere/Cohere.ts b/packages/components/nodes/llms/Cohere/Cohere.ts
index a7e9c696..4a3a8a80 100644
--- a/packages/components/nodes/llms/Cohere/Cohere.ts
+++ b/packages/components/nodes/llms/Cohere/Cohere.ts
@@ -1,31 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { Cohere, CohereInput } from './core'
class Cohere_LLMs implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Cohere'
this.name = 'cohere'
+ this.version = 1.0
this.type = 'Cohere'
this.icon = 'cohere.png'
this.category = 'LLMs'
this.description = 'Wrapper around Cohere large language models'
this.baseClasses = [this.type, ...getBaseClasses(Cohere)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['cohereApi']
+ }
this.inputs = [
- {
- label: 'Cohere Api Key',
- name: 'cohereApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
@@ -63,6 +67,7 @@ class Cohere_LLMs implements INode {
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.7,
optional: true
},
@@ -70,24 +75,27 @@ class Cohere_LLMs implements INode {
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
optional: true
}
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const temperature = nodeData.inputs?.temperature as string
const modelName = nodeData.inputs?.modelName as string
- const apiKey = nodeData.inputs?.cohereApiKey as string
const maxTokens = nodeData.inputs?.maxTokens as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const cohereApiKey = getCredentialParam('cohereApiKey', credentialData, nodeData)
+
const obj: CohereInput = {
- apiKey
+ apiKey: cohereApiKey
}
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
if (modelName) obj.model = modelName
- if (temperature) obj.temperature = parseInt(temperature, 10)
+ if (temperature) obj.temperature = parseFloat(temperature)
const model = new Cohere(obj)
return model
diff --git a/packages/components/nodes/llms/HuggingFaceInference/HuggingFaceInference.ts b/packages/components/nodes/llms/HuggingFaceInference/HuggingFaceInference.ts
index 88a7db07..c7f6a37e 100644
--- a/packages/components/nodes/llms/HuggingFaceInference/HuggingFaceInference.ts
+++ b/packages/components/nodes/llms/HuggingFaceInference/HuggingFaceInference.ts
@@ -1,41 +1,56 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
-import { HFInput, HuggingFaceInference } from 'langchain/llms/hf'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { HFInput, HuggingFaceInference } from './core'
class HuggingFaceInference_LLMs implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'HuggingFace Inference'
this.name = 'huggingFaceInference_LLMs'
+ this.version = 1.0
this.type = 'HuggingFaceInference'
this.icon = 'huggingface.png'
this.category = 'LLMs'
this.description = 'Wrapper around HuggingFace large language models'
this.baseClasses = [this.type, ...getBaseClasses(HuggingFaceInference)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['huggingFaceApi']
+ }
this.inputs = [
{
label: 'Model',
name: 'model',
type: 'string',
- placeholder: 'gpt2'
+ description: 'If using own inference endpoint, leave this blank',
+ placeholder: 'gpt2',
+ optional: true
},
{
- label: 'HuggingFace Api Key',
- name: 'apiKey',
- type: 'password'
+ label: 'Endpoint',
+ name: 'endpoint',
+ type: 'string',
+ placeholder: 'https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2',
+ description: 'Using your own inference endpoint',
+ optional: true
},
{
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
description: 'Temperature parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -44,6 +59,7 @@ class HuggingFaceInference_LLMs implements INode {
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
description: 'Max Tokens parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -52,6 +68,7 @@ class HuggingFaceInference_LLMs implements INode {
label: 'Top Probability',
name: 'topP',
type: 'number',
+ step: 0.1,
description: 'Top Probability parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -60,6 +77,7 @@ class HuggingFaceInference_LLMs implements INode {
label: 'Top K',
name: 'hfTopK',
type: 'number',
+ step: 0.1,
description: 'Top K parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -68,6 +86,7 @@ class HuggingFaceInference_LLMs implements INode {
label: 'Frequency Penalty',
name: 'frequencyPenalty',
type: 'number',
+ step: 0.1,
description: 'Frequency Penalty parameter may not apply to certain model. Please check available model parameters',
optional: true,
additionalParams: true
@@ -75,25 +94,29 @@ class HuggingFaceInference_LLMs implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const model = nodeData.inputs?.model as string
- const apiKey = nodeData.inputs?.apiKey as string
const temperature = nodeData.inputs?.temperature as string
const maxTokens = nodeData.inputs?.maxTokens as string
const topP = nodeData.inputs?.topP as string
const hfTopK = nodeData.inputs?.hfTopK as string
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
+ const endpoint = nodeData.inputs?.endpoint as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const huggingFaceApiKey = getCredentialParam('huggingFaceApiKey', credentialData, nodeData)
const obj: Partial = {
model,
- apiKey
+ apiKey: huggingFaceApiKey
}
- if (temperature) obj.temperature = parseInt(temperature, 10)
+ if (temperature) obj.temperature = parseFloat(temperature)
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (topP) obj.topP = parseInt(topP, 10)
- if (hfTopK) obj.topK = parseInt(hfTopK, 10)
- if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (hfTopK) obj.topK = parseFloat(hfTopK)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (endpoint) obj.endpoint = endpoint
const huggingFace = new HuggingFaceInference(obj)
return huggingFace
diff --git a/packages/components/nodes/llms/HuggingFaceInference/core.ts b/packages/components/nodes/llms/HuggingFaceInference/core.ts
new file mode 100644
index 00000000..416567f0
--- /dev/null
+++ b/packages/components/nodes/llms/HuggingFaceInference/core.ts
@@ -0,0 +1,113 @@
+import { getEnvironmentVariable } from '../../../src/utils'
+import { LLM, BaseLLMParams } from 'langchain/llms/base'
+
+export interface HFInput {
+ /** Model to use */
+ model: string
+
+ /** Sampling temperature to use */
+ temperature?: number
+
+ /**
+ * Maximum number of tokens to generate in the completion.
+ */
+ maxTokens?: number
+
+ /** Total probability mass of tokens to consider at each step */
+ topP?: number
+
+ /** Integer to define the top tokens considered within the sample operation to create new text. */
+ topK?: number
+
+ /** Penalizes repeated tokens according to frequency */
+ frequencyPenalty?: number
+
+ /** API key to use. */
+ apiKey?: string
+
+ /** Private endpoint to use. */
+ endpoint?: string
+}
+
+export class HuggingFaceInference extends LLM implements HFInput {
+ get lc_secrets(): { [key: string]: string } | undefined {
+ return {
+ apiKey: 'HUGGINGFACEHUB_API_KEY'
+ }
+ }
+
+ model = 'gpt2'
+
+ temperature: number | undefined = undefined
+
+ maxTokens: number | undefined = undefined
+
+ topP: number | undefined = undefined
+
+ topK: number | undefined = undefined
+
+ frequencyPenalty: number | undefined = undefined
+
+ apiKey: string | undefined = undefined
+
+ endpoint: string | undefined = undefined
+
+ constructor(fields?: Partial & BaseLLMParams) {
+ super(fields ?? {})
+
+ this.model = fields?.model ?? this.model
+ this.temperature = fields?.temperature ?? this.temperature
+ this.maxTokens = fields?.maxTokens ?? this.maxTokens
+ this.topP = fields?.topP ?? this.topP
+ this.topK = fields?.topK ?? this.topK
+ this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty
+ this.endpoint = fields?.endpoint ?? ''
+ this.apiKey = fields?.apiKey ?? getEnvironmentVariable('HUGGINGFACEHUB_API_KEY')
+ if (!this.apiKey) {
+ throw new Error(
+ 'Please set an API key for HuggingFace Hub in the environment variable HUGGINGFACEHUB_API_KEY or in the apiKey field of the HuggingFaceInference constructor.'
+ )
+ }
+ }
+
+ _llmType() {
+ return 'hf'
+ }
+
+ /** @ignore */
+ async _call(prompt: string, options: this['ParsedCallOptions']): Promise {
+ const { HfInference } = await HuggingFaceInference.imports()
+ const hf = new HfInference(this.apiKey)
+ const obj: any = {
+ parameters: {
+ // make it behave similar to openai, returning only the generated text
+ return_full_text: false,
+ temperature: this.temperature,
+ max_new_tokens: this.maxTokens,
+ top_p: this.topP,
+ top_k: this.topK,
+ repetition_penalty: this.frequencyPenalty
+ },
+ inputs: prompt
+ }
+ if (this.endpoint) {
+ hf.endpoint(this.endpoint)
+ } else {
+ obj.model = this.model
+ }
+ const res = await this.caller.callWithOptions({ signal: options.signal }, hf.textGeneration.bind(hf), obj)
+ return res.generated_text
+ }
+
+ /** @ignore */
+ static async imports(): Promise<{
+ HfInference: typeof import('@huggingface/inference').HfInference
+ }> {
+ try {
+ const { HfInference } = await import('@huggingface/inference')
+ return { HfInference }
+ } catch (e) {
+ throw new Error('Please install huggingface as a dependency with, e.g. `yarn add @huggingface/inference`')
+ }
+ }
+}
diff --git a/packages/components/nodes/llms/OpenAI/OpenAI.ts b/packages/components/nodes/llms/OpenAI/OpenAI.ts
index fb7e5b6b..4e35d659 100644
--- a/packages/components/nodes/llms/OpenAI/OpenAI.ts
+++ b/packages/components/nodes/llms/OpenAI/OpenAI.ts
@@ -1,31 +1,35 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { OpenAI, OpenAIInput } from 'langchain/llms/openai'
class OpenAI_LLMs implements INode {
label: string
name: string
+ version: number
type: string
icon: string
category: string
description: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'OpenAI'
this.name = 'openAI'
+ this.version = 1.0
this.type = 'OpenAI'
this.icon = 'openai.png'
this.category = 'LLMs'
this.description = 'Wrapper around OpenAI large language models'
this.baseClasses = [this.type, ...getBaseClasses(OpenAI)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['openAIApi']
+ }
this.inputs = [
- {
- label: 'OpenAI Api Key',
- name: 'openAIApiKey',
- type: 'password'
- },
{
label: 'Model Name',
name: 'modelName',
@@ -55,6 +59,7 @@ class OpenAI_LLMs implements INode {
label: 'Temperature',
name: 'temperature',
type: 'number',
+ step: 0.1,
default: 0.7,
optional: true
},
@@ -62,6 +67,7 @@ class OpenAI_LLMs implements INode {
label: 'Max Tokens',
name: 'maxTokens',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -69,6 +75,7 @@ class OpenAI_LLMs implements INode {
label: 'Top Probability',
name: 'topP',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -76,6 +83,7 @@ class OpenAI_LLMs implements INode {
label: 'Best Of',
name: 'bestOf',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -83,6 +91,7 @@ class OpenAI_LLMs implements INode {
label: 'Frequency Penalty',
name: 'frequencyPenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -90,6 +99,7 @@ class OpenAI_LLMs implements INode {
label: 'Presence Penalty',
name: 'presencePenalty',
type: 'number',
+ step: 0.1,
optional: true,
additionalParams: true
},
@@ -97,6 +107,7 @@ class OpenAI_LLMs implements INode {
label: 'Batch Size',
name: 'batchSize',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -104,6 +115,7 @@ class OpenAI_LLMs implements INode {
label: 'Timeout',
name: 'timeout',
type: 'number',
+ step: 1,
optional: true,
additionalParams: true
},
@@ -117,10 +129,9 @@ class OpenAI_LLMs implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const temperature = nodeData.inputs?.temperature as string
const modelName = nodeData.inputs?.modelName as string
- const openAIApiKey = nodeData.inputs?.openAIApiKey as string
const maxTokens = nodeData.inputs?.maxTokens as string
const topP = nodeData.inputs?.topP as string
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
@@ -131,17 +142,20 @@ class OpenAI_LLMs implements INode {
const streaming = nodeData.inputs?.streaming as boolean
const basePath = nodeData.inputs?.basepath as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData)
+
const obj: Partial & { openAIApiKey?: string } = {
- temperature: parseInt(temperature, 10),
+ temperature: parseFloat(temperature),
modelName,
openAIApiKey,
streaming: streaming ?? true
}
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
- if (topP) obj.topP = parseInt(topP, 10)
- if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
- if (presencePenalty) obj.presencePenalty = parseInt(presencePenalty, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty)
if (timeout) obj.timeout = parseInt(timeout, 10)
if (batchSize) obj.batchSize = parseInt(batchSize, 10)
if (bestOf) obj.bestOf = parseInt(bestOf, 10)
diff --git a/packages/components/nodes/llms/Replicate/Replicate.ts b/packages/components/nodes/llms/Replicate/Replicate.ts
new file mode 100644
index 00000000..ca30cd97
--- /dev/null
+++ b/packages/components/nodes/llms/Replicate/Replicate.ts
@@ -0,0 +1,128 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { Replicate, ReplicateInput } from 'langchain/llms/replicate'
+
+class Replicate_LLMs implements INode {
+ label: string
+ name: string
+ version: number
+ type: string
+ icon: string
+ category: string
+ description: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Replicate'
+ this.name = 'replicate'
+ this.version = 1.0
+ this.type = 'Replicate'
+ this.icon = 'replicate.svg'
+ this.category = 'LLMs'
+ this.description = 'Use Replicate to run open source models on cloud'
+ this.baseClasses = [this.type, 'BaseChatModel', ...getBaseClasses(Replicate)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['replicateApi']
+ }
+ this.inputs = [
+ {
+ label: 'Model',
+ name: 'model',
+ type: 'string',
+ placeholder: 'a16z-infra/llama13b-v2-chat:df7690f1994d94e96ad9d568eac121aecf50684a0b0963b25a41cc40061269e5',
+ optional: true
+ },
+ {
+ label: 'Temperature',
+ name: 'temperature',
+ type: 'number',
+ step: 0.1,
+ description:
+ 'Adjusts randomness of outputs, greater than 1 is random and 0 is deterministic, 0.75 is a good starting value.',
+ default: 0.7,
+ optional: true
+ },
+ {
+ label: 'Max Tokens',
+ name: 'maxTokens',
+ type: 'number',
+ step: 1,
+ description: 'Maximum number of tokens to generate. A word is generally 2-3 tokens',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Top Probability',
+ name: 'topP',
+ type: 'number',
+ step: 0.1,
+ description:
+ 'When decoding text, samples from the top p percentage of most likely tokens; lower to ignore less likely tokens',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Repetition Penalty',
+ name: 'repetitionPenalty',
+ type: 'number',
+ step: 0.1,
+ description:
+ 'Penalty for repeated words in generated text; 1 is no penalty, values greater than 1 discourage repetition, less than 1 encourage it. (minimum: 0.01; maximum: 5)',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Additional Inputs',
+ name: 'additionalInputs',
+ type: 'json',
+ description:
+ 'Each model has different parameters, refer to the specific model accepted inputs. For example: llama13b-v2',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const modelName = nodeData.inputs?.model as string
+ const temperature = nodeData.inputs?.temperature as string
+ const maxTokens = nodeData.inputs?.maxTokens as string
+ const topP = nodeData.inputs?.topP as string
+ const repetitionPenalty = nodeData.inputs?.repetitionPenalty as string
+ const additionalInputs = nodeData.inputs?.additionalInputs as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
+
+ const version = modelName.split(':').pop()
+ const name = modelName.split(':')[0].split('/').pop()
+ const org = modelName.split(':')[0].split('/')[0]
+
+ const obj: ReplicateInput = {
+ model: `${org}/${name}:${version}`,
+ apiKey
+ }
+
+ let inputs: any = {}
+ if (maxTokens) inputs.max_length = parseInt(maxTokens, 10)
+ if (temperature) inputs.temperature = parseFloat(temperature)
+ if (topP) inputs.top_p = parseFloat(topP)
+ if (repetitionPenalty) inputs.repetition_penalty = parseFloat(repetitionPenalty)
+ if (additionalInputs) {
+ const parsedInputs =
+ typeof additionalInputs === 'object' ? additionalInputs : additionalInputs ? JSON.parse(additionalInputs) : {}
+ inputs = { ...inputs, ...parsedInputs }
+ }
+ if (Object.keys(inputs).length) obj.input = inputs
+
+ const model = new Replicate(obj)
+ return model
+ }
+}
+
+module.exports = { nodeClass: Replicate_LLMs }
diff --git a/packages/components/nodes/llms/Replicate/replicate.svg b/packages/components/nodes/llms/Replicate/replicate.svg
new file mode 100644
index 00000000..2e46453f
--- /dev/null
+++ b/packages/components/nodes/llms/Replicate/replicate.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/memory/BufferMemory/BufferMemory.ts b/packages/components/nodes/memory/BufferMemory/BufferMemory.ts
index fd635ff4..7793d96d 100644
--- a/packages/components/nodes/memory/BufferMemory/BufferMemory.ts
+++ b/packages/components/nodes/memory/BufferMemory/BufferMemory.ts
@@ -5,6 +5,7 @@ import { BufferMemory } from 'langchain/memory'
class BufferMemory_Memory implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class BufferMemory_Memory implements INode {
constructor() {
this.label = 'Buffer Memory'
this.name = 'bufferMemory'
+ this.version = 1.0
this.type = 'BufferMemory'
this.icon = 'memory.svg'
this.category = 'Memory'
diff --git a/packages/components/nodes/memory/BufferWindowMemory/BufferWindowMemory.ts b/packages/components/nodes/memory/BufferWindowMemory/BufferWindowMemory.ts
index ae783fec..cf8e7f1d 100644
--- a/packages/components/nodes/memory/BufferWindowMemory/BufferWindowMemory.ts
+++ b/packages/components/nodes/memory/BufferWindowMemory/BufferWindowMemory.ts
@@ -5,6 +5,7 @@ import { BufferWindowMemory, BufferWindowMemoryInput } from 'langchain/memory'
class BufferWindowMemory_Memory implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class BufferWindowMemory_Memory implements INode {
constructor() {
this.label = 'Buffer Window Memory'
this.name = 'bufferWindowMemory'
+ this.version = 1.0
this.type = 'BufferWindowMemory'
this.icon = 'memory.svg'
this.category = 'Memory'
diff --git a/packages/components/nodes/memory/ConversationSummaryMemory/ConversationSummaryMemory.ts b/packages/components/nodes/memory/ConversationSummaryMemory/ConversationSummaryMemory.ts
index 3c055e8e..332d73aa 100644
--- a/packages/components/nodes/memory/ConversationSummaryMemory/ConversationSummaryMemory.ts
+++ b/packages/components/nodes/memory/ConversationSummaryMemory/ConversationSummaryMemory.ts
@@ -6,6 +6,7 @@ import { BaseLanguageModel } from 'langchain/base_language'
class ConversationSummaryMemory_Memory implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -16,6 +17,7 @@ class ConversationSummaryMemory_Memory implements INode {
constructor() {
this.label = 'Conversation Summary Memory'
this.name = 'conversationSummaryMemory'
+ this.version = 1.0
this.type = 'ConversationSummaryMemory'
this.icon = 'memory.svg'
this.category = 'Memory'
diff --git a/packages/components/nodes/memory/DynamoDb/DynamoDb.ts b/packages/components/nodes/memory/DynamoDb/DynamoDb.ts
new file mode 100644
index 00000000..6926912f
--- /dev/null
+++ b/packages/components/nodes/memory/DynamoDb/DynamoDb.ts
@@ -0,0 +1,117 @@
+import { ICommonObject, INode, INodeData, INodeParams, getBaseClasses, getCredentialData, getCredentialParam } from '../../../src'
+import { DynamoDBChatMessageHistory } from 'langchain/stores/message/dynamodb'
+import { BufferMemory } from 'langchain/memory'
+
+class DynamoDb_Memory implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'DynamoDB Chat Memory'
+ this.name = 'DynamoDBChatMemory'
+ this.version = 1.0
+ this.type = 'DynamoDBChatMemory'
+ this.icon = 'dynamodb.svg'
+ this.category = 'Memory'
+ this.description = 'Stores the conversation in dynamo db table'
+ this.baseClasses = [this.type, ...getBaseClasses(BufferMemory)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['dynamodbMemoryApi']
+ }
+ this.inputs = [
+ {
+ label: 'Table Name',
+ name: 'tableName',
+ type: 'string'
+ },
+ {
+ label: 'Partition Key',
+ name: 'partitionKey',
+ type: 'string'
+ },
+ {
+ label: 'Region',
+ name: 'region',
+ type: 'string',
+ description: 'The aws region in which table is located',
+ placeholder: 'us-east-1'
+ },
+ {
+ label: 'Session ID',
+ name: 'sessionId',
+ type: 'string',
+ description: 'if empty, chatId will be used automatically',
+ default: '',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Memory Key',
+ name: 'memoryKey',
+ type: 'string',
+ default: 'chat_history',
+ additionalParams: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ return initalizeDynamoDB(nodeData, options)
+ }
+
+ async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise {
+ const dynamodbMemory = await initalizeDynamoDB(nodeData, options)
+ const sessionId = nodeData.inputs?.sessionId as string
+ const chatId = options?.chatId as string
+ options.logger.info(`Clearing DynamoDb memory session ${sessionId ? sessionId : chatId}`)
+ await dynamodbMemory.clear()
+ options.logger.info(`Successfully cleared DynamoDb memory session ${sessionId ? sessionId : chatId}`)
+ }
+}
+
+const initalizeDynamoDB = async (nodeData: INodeData, options: ICommonObject): Promise => {
+ 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 memoryKey = nodeData.inputs?.memoryKey as string
+
+ const chatId = options.chatId
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const accessKeyId = getCredentialParam('accessKey', credentialData, nodeData)
+ const secretAccessKey = getCredentialParam('secretAccessKey', credentialData, nodeData)
+
+ const dynamoDb = new DynamoDBChatMessageHistory({
+ tableName,
+ partitionKey,
+ sessionId: sessionId ? sessionId : chatId,
+ config: {
+ region,
+ credentials: {
+ accessKeyId,
+ secretAccessKey
+ }
+ }
+ })
+
+ const memory = new BufferMemory({
+ memoryKey,
+ chatHistory: dynamoDb,
+ returnMessages: true
+ })
+ return memory
+}
+
+module.exports = { nodeClass: DynamoDb_Memory }
diff --git a/packages/components/nodes/memory/DynamoDb/dynamodb.svg b/packages/components/nodes/memory/DynamoDb/dynamodb.svg
new file mode 100644
index 00000000..f2798350
--- /dev/null
+++ b/packages/components/nodes/memory/DynamoDb/dynamodb.svg
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/packages/components/nodes/memory/MotorheadMemory/MotorheadMemory.ts b/packages/components/nodes/memory/MotorheadMemory/MotorheadMemory.ts
new file mode 100644
index 00000000..bb23de9d
--- /dev/null
+++ b/packages/components/nodes/memory/MotorheadMemory/MotorheadMemory.ts
@@ -0,0 +1,109 @@
+import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { ICommonObject } from '../../../src'
+import { MotorheadMemory, MotorheadMemoryInput } from 'langchain/memory'
+
+class MotorMemory_Memory implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Motorhead Memory'
+ this.name = 'motorheadMemory'
+ this.version = 1.0
+ this.type = 'MotorheadMemory'
+ this.icon = 'motorhead.png'
+ this.category = 'Memory'
+ this.description = 'Use Motorhead Memory to store chat conversations'
+ this.baseClasses = [this.type, ...getBaseClasses(MotorheadMemory)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ optional: true,
+ description: 'Only needed when using hosted solution - https://getmetal.io',
+ credentialNames: ['motorheadMemoryApi']
+ }
+ this.inputs = [
+ {
+ label: 'Base URL',
+ name: 'baseURL',
+ type: 'string',
+ optional: true,
+ description: 'To use the online version, leave the URL blank. More details at https://getmetal.io.'
+ },
+ {
+ label: 'Session Id',
+ name: 'sessionId',
+ type: 'string',
+ description: 'if empty, chatId will be used automatically',
+ default: '',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Memory Key',
+ name: 'memoryKey',
+ type: 'string',
+ default: 'chat_history',
+ additionalParams: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ return initalizeMotorhead(nodeData, options)
+ }
+
+ async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise {
+ const motorhead = await initalizeMotorhead(nodeData, options)
+ const sessionId = nodeData.inputs?.sessionId as string
+ const chatId = options?.chatId as string
+ options.logger.info(`Clearing Motorhead memory session ${sessionId ? sessionId : chatId}`)
+ await motorhead.clear()
+ options.logger.info(`Successfully cleared Motorhead memory session ${sessionId ? sessionId : chatId}`)
+ }
+}
+
+const initalizeMotorhead = async (nodeData: INodeData, options: ICommonObject): Promise => {
+ const memoryKey = nodeData.inputs?.memoryKey as string
+ const baseURL = nodeData.inputs?.baseURL as string
+ const sessionId = nodeData.inputs?.sessionId as string
+
+ const chatId = options?.chatId as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
+ const clientId = getCredentialParam('clientId', credentialData, nodeData)
+
+ 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 }
diff --git a/packages/components/nodes/memory/MotorheadMemory/motorhead.png b/packages/components/nodes/memory/MotorheadMemory/motorhead.png
new file mode 100644
index 00000000..e1dfbde0
Binary files /dev/null and b/packages/components/nodes/memory/MotorheadMemory/motorhead.png differ
diff --git a/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts b/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts
new file mode 100644
index 00000000..7b3e2cb5
--- /dev/null
+++ b/packages/components/nodes/memory/RedisBackedChatMemory/RedisBackedChatMemory.ts
@@ -0,0 +1,103 @@
+import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject } from '../../../src'
+import { BufferMemory } from 'langchain/memory'
+import { RedisChatMessageHistory, RedisChatMessageHistoryInput } from 'langchain/stores/message/redis'
+import { createClient } from 'redis'
+
+class RedisBackedChatMemory_Memory implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Redis-Backed Chat Memory'
+ this.name = 'RedisBackedChatMemory'
+ this.version = 1.0
+ this.type = 'RedisBackedChatMemory'
+ this.icon = 'redis.svg'
+ this.category = 'Memory'
+ this.description = 'Summarizes the conversation and stores the memory in Redis server'
+ this.baseClasses = [this.type, ...getBaseClasses(BufferMemory)]
+ this.inputs = [
+ {
+ label: 'Base URL',
+ name: 'baseURL',
+ type: 'string',
+ default: 'redis://localhost:6379'
+ },
+ {
+ label: 'Session Id',
+ name: 'sessionId',
+ type: 'string',
+ description: 'if empty, chatId will be used automatically',
+ default: '',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Session Timeouts',
+ name: 'sessionTTL',
+ type: 'number',
+ description: 'Omit this parameter to make sessions never expire',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Memory Key',
+ name: 'memoryKey',
+ type: 'string',
+ default: 'chat_history',
+ additionalParams: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ return initalizeRedis(nodeData, options)
+ }
+
+ async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise {
+ const redis = initalizeRedis(nodeData, options)
+ const sessionId = nodeData.inputs?.sessionId as string
+ const chatId = options?.chatId as string
+ options.logger.info(`Clearing Redis memory session ${sessionId ? sessionId : chatId}`)
+ await redis.clear()
+ options.logger.info(`Successfully cleared Redis memory session ${sessionId ? sessionId : chatId}`)
+ }
+}
+
+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 }
diff --git a/packages/components/nodes/memory/RedisBackedChatMemory/redis.svg b/packages/components/nodes/memory/RedisBackedChatMemory/redis.svg
new file mode 100644
index 00000000..90359069
--- /dev/null
+++ b/packages/components/nodes/memory/RedisBackedChatMemory/redis.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/memory/ZepMemory/ZepMemory.ts b/packages/components/nodes/memory/ZepMemory/ZepMemory.ts
index 1fb6d9ff..3faa29b9 100644
--- a/packages/components/nodes/memory/ZepMemory/ZepMemory.ts
+++ b/packages/components/nodes/memory/ZepMemory/ZepMemory.ts
@@ -1,27 +1,38 @@
-import { SystemChatMessage } from 'langchain/schema'
+import { SystemMessage } from 'langchain/schema'
import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { ZepMemory, ZepMemoryInput } from 'langchain/memory/zep'
import { ICommonObject } from '../../../src'
class ZepMemory_Memory implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Zep Memory'
this.name = 'ZepMemory'
+ this.version = 1.0
this.type = 'ZepMemory'
- this.icon = 'memory.svg'
+ this.icon = 'zep.png'
this.category = 'Memory'
this.description = 'Summarizes the conversation and stores the memory in zep server'
this.baseClasses = [this.type, ...getBaseClasses(ZepMemory)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ optional: true,
+ description: 'Configure JWT authentication on your Zep instance (Optional)',
+ credentialNames: ['zepMemoryApi']
+ }
this.inputs = [
{
label: 'Base URL',
@@ -41,7 +52,15 @@ class ZepMemory_Memory implements INode {
type: 'string',
description: 'if empty, chatId will be used automatically',
default: '',
- additionalParams: true
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Size',
+ name: 'k',
+ type: 'number',
+ default: '10',
+ description: 'Window of size k to surface the last k back-and-forths to use as memory.'
},
{
label: 'Auto Summary Template',
@@ -89,40 +108,24 @@ class ZepMemory_Memory implements INode {
}
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
- 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 autoSummary = nodeData.inputs?.autoSummary as boolean
- const sessionId = nodeData.inputs?.sessionId as string
- const chatId = options?.chatId as string
+ const k = nodeData.inputs?.k as string
- const obj: ZepMemoryInput = {
- baseURL,
- sessionId: sessionId ? sessionId : chatId,
- aiPrefix,
- humanPrefix,
- returnMessages: true,
- memoryKey,
- inputKey
- }
-
- let zep = new ZepMemory(obj)
+ let zep = await initalizeZep(nodeData, options)
// hack to support summary
let tmpFunc = zep.loadMemoryVariables
zep.loadMemoryVariables = async (values) => {
let data = await tmpFunc.bind(zep, values)()
if (autoSummary && zep.returnMessages && data[zep.memoryKey] && data[zep.memoryKey].length) {
- const memory = await zep.zepClient.getMemory(zep.sessionId, 10)
+ const memory = await zep.zepClient.getMemory(zep.sessionId, parseInt(k, 10) ?? 10)
if (memory?.summary) {
let summary = autoSummaryTemplate.replace(/{summary}/g, memory.summary.content)
// eslint-disable-next-line no-console
console.log('[ZepMemory] auto summary:', summary)
- data[zep.memoryKey].unshift(new SystemChatMessage(summary))
+ data[zep.memoryKey].unshift(new SystemMessage(summary))
}
}
// for langchain zep memory compatibility, or we will get "Missing value for input variable chat_history"
@@ -135,6 +138,42 @@ class ZepMemory_Memory implements INode {
}
return zep
}
+
+ async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise {
+ const zep = await initalizeZep(nodeData, options)
+ const sessionId = nodeData.inputs?.sessionId as string
+ const chatId = options?.chatId as string
+ options.logger.info(`Clearing Zep memory session ${sessionId ? sessionId : chatId}`)
+ await zep.clear()
+ options.logger.info(`Successfully cleared Zep memory session ${sessionId ? sessionId : chatId}`)
+ }
+}
+
+const initalizeZep = async (nodeData: INodeData, options: ICommonObject): Promise => {
+ 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 chatId = options?.chatId as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
+
+ 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 }
diff --git a/packages/components/nodes/memory/ZepMemory/memory.svg b/packages/components/nodes/memory/ZepMemory/memory.svg
deleted file mode 100644
index ca8e17da..00000000
--- a/packages/components/nodes/memory/ZepMemory/memory.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
\ No newline at end of file
diff --git a/packages/components/nodes/memory/ZepMemory/zep.png b/packages/components/nodes/memory/ZepMemory/zep.png
new file mode 100644
index 00000000..293be6f6
Binary files /dev/null and b/packages/components/nodes/memory/ZepMemory/zep.png differ
diff --git a/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts b/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts
index c3c4d77f..c9ec751d 100644
--- a/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts
+++ b/packages/components/nodes/prompts/ChatPromptTemplate/ChatPromptTemplate.ts
@@ -5,6 +5,7 @@ import { ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemp
class ChatPromptTemplate_Prompts implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class ChatPromptTemplate_Prompts implements INode {
constructor() {
this.label = 'Chat Prompt Template'
this.name = 'chatPromptTemplate'
+ this.version = 1.0
this.type = 'ChatPromptTemplate'
this.icon = 'prompt.svg'
this.category = 'Prompts'
@@ -38,12 +40,7 @@ class ChatPromptTemplate_Prompts implements INode {
{
label: 'Format Prompt Values',
name: 'promptValues',
- type: 'string',
- rows: 4,
- placeholder: `{
- "input_language": "English",
- "output_language": "French"
-}`,
+ type: 'json',
optional: true,
acceptVariable: true,
list: true
@@ -63,7 +60,7 @@ class ChatPromptTemplate_Prompts implements INode {
let promptValues: ICommonObject = {}
if (promptValuesStr) {
- promptValues = JSON.parse(promptValuesStr.replace(/\s/g, ''))
+ promptValues = JSON.parse(promptValuesStr)
}
// @ts-ignore
prompt.promptValues = promptValues
diff --git a/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts b/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts
index a42a1d08..ed1d3cb2 100644
--- a/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts
+++ b/packages/components/nodes/prompts/FewShotPromptTemplate/FewShotPromptTemplate.ts
@@ -7,6 +7,7 @@ import { TemplateFormat } from 'langchain/dist/prompts/template'
class FewShotPromptTemplate_Prompts implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class FewShotPromptTemplate_Prompts implements INode {
constructor() {
this.label = 'Few Shot Prompt Template'
this.name = 'fewShotPromptTemplate'
+ this.version = 1.0
this.type = 'FewShotPromptTemplate'
this.icon = 'prompt.svg'
this.category = 'Prompts'
@@ -86,7 +88,7 @@ class FewShotPromptTemplate_Prompts implements INode {
const examplePrompt = nodeData.inputs?.examplePrompt as PromptTemplate
const inputVariables = getInputVariables(suffix)
- const examples: Example[] = JSON.parse(examplesStr.replace(/\s/g, ''))
+ const examples: Example[] = JSON.parse(examplesStr)
try {
const obj: FewShotPromptTemplateInput = {
diff --git a/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts b/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts
index cfa2c488..a401e282 100644
--- a/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts
+++ b/packages/components/nodes/prompts/PromptTemplate/PromptTemplate.ts
@@ -1,10 +1,11 @@
import { ICommonObject, INode, INodeData, INodeParams, PromptTemplate } from '../../../src/Interface'
-import { getBaseClasses, getInputVariables, returnJSONStr } from '../../../src/utils'
+import { getBaseClasses, getInputVariables } from '../../../src/utils'
import { PromptTemplateInput } from 'langchain/prompts'
class PromptTemplate_Prompts implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class PromptTemplate_Prompts implements INode {
constructor() {
this.label = 'Prompt Template'
this.name = 'promptTemplate'
+ this.version = 1.0
this.type = 'PromptTemplate'
this.icon = 'prompt.svg'
this.category = 'Prompts'
@@ -31,12 +33,7 @@ class PromptTemplate_Prompts implements INode {
{
label: 'Format Prompt Values',
name: 'promptValues',
- type: 'string',
- rows: 4,
- placeholder: `{
- "input_language": "English",
- "output_language": "French"
-}`,
+ type: 'json',
optional: true,
acceptVariable: true,
list: true
@@ -46,12 +43,11 @@ class PromptTemplate_Prompts implements INode {
async init(nodeData: INodeData): Promise {
const template = nodeData.inputs?.template as string
- let promptValuesStr = nodeData.inputs?.promptValues as string
+ const promptValuesStr = nodeData.inputs?.promptValues as string
let promptValues: ICommonObject = {}
if (promptValuesStr) {
- promptValuesStr = promptValuesStr.replace(/\s/g, '')
- promptValues = JSON.parse(returnJSONStr(promptValuesStr))
+ promptValues = JSON.parse(promptValuesStr)
}
const inputVariables = getInputVariables(template)
diff --git a/packages/components/nodes/retrievers/HydeRetriever/HydeRetriever.ts b/packages/components/nodes/retrievers/HydeRetriever/HydeRetriever.ts
new file mode 100644
index 00000000..2baf677e
--- /dev/null
+++ b/packages/components/nodes/retrievers/HydeRetriever/HydeRetriever.ts
@@ -0,0 +1,123 @@
+import { VectorStore } from 'langchain/vectorstores/base'
+import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { HydeRetriever, HydeRetrieverOptions, PromptKey } from 'langchain/retrievers/hyde'
+import { BaseLanguageModel } from 'langchain/base_language'
+import { PromptTemplate } from 'langchain/prompts'
+
+class HydeRetriever_Retrievers implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Hyde Retriever'
+ this.name = 'HydeRetriever'
+ this.version = 1.0
+ this.type = 'HydeRetriever'
+ this.icon = 'hyderetriever.svg'
+ this.category = 'Retrievers'
+ this.description = 'Use HyDE retriever to retrieve from a vector store'
+ this.baseClasses = [this.type, 'BaseRetriever']
+ this.inputs = [
+ {
+ label: 'Language Model',
+ name: 'model',
+ type: 'BaseLanguageModel'
+ },
+ {
+ label: 'Vector Store',
+ name: 'vectorStore',
+ type: 'VectorStore'
+ },
+ {
+ label: 'Prompt Key',
+ name: 'promptKey',
+ type: 'options',
+ options: [
+ {
+ label: 'websearch',
+ name: 'websearch'
+ },
+ {
+ label: 'scifact',
+ name: 'scifact'
+ },
+ {
+ label: 'arguana',
+ name: 'arguana'
+ },
+ {
+ label: 'trec-covid',
+ name: 'trec-covid'
+ },
+ {
+ label: 'fiqa',
+ name: 'fiqa'
+ },
+ {
+ label: 'dbpedia-entity',
+ name: 'dbpedia-entity'
+ },
+ {
+ label: 'trec-news',
+ name: 'trec-news'
+ },
+ {
+ label: 'mr-tydi',
+ name: 'mr-tydi'
+ }
+ ],
+ default: 'websearch'
+ },
+ {
+ label: 'Custom Prompt',
+ name: 'customPrompt',
+ description: 'If custom prompt is used, this will override Prompt Key',
+ placeholder: 'Please write a passage to answer the question\nQuestion: {question}\nPassage:',
+ type: 'string',
+ rows: 4,
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Default to 4',
+ placeholder: '4',
+ type: 'number',
+ default: 4,
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData): Promise {
+ const llm = nodeData.inputs?.model as BaseLanguageModel
+ const vectorStore = nodeData.inputs?.vectorStore as VectorStore
+ const promptKey = nodeData.inputs?.promptKey as PromptKey
+ const customPrompt = nodeData.inputs?.customPrompt as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseInt(topK, 10) : 4
+
+ const obj: HydeRetrieverOptions = {
+ llm,
+ vectorStore,
+ k
+ }
+
+ if (customPrompt) obj.promptTemplate = PromptTemplate.fromTemplate(customPrompt)
+ else if (promptKey) obj.promptTemplate = promptKey
+
+ const retriever = new HydeRetriever(obj)
+ return retriever
+ }
+}
+
+module.exports = { nodeClass: HydeRetriever_Retrievers }
diff --git a/packages/components/nodes/retrievers/HydeRetriever/hyderetriever.svg b/packages/components/nodes/retrievers/HydeRetriever/hyderetriever.svg
new file mode 100644
index 00000000..da3a9f20
--- /dev/null
+++ b/packages/components/nodes/retrievers/HydeRetriever/hyderetriever.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/retrievers/PromptRetriever/PromptRetriever.ts b/packages/components/nodes/retrievers/PromptRetriever/PromptRetriever.ts
index e3b9a4ac..7ffaa64f 100644
--- a/packages/components/nodes/retrievers/PromptRetriever/PromptRetriever.ts
+++ b/packages/components/nodes/retrievers/PromptRetriever/PromptRetriever.ts
@@ -3,6 +3,7 @@ import { INode, INodeData, INodeParams, PromptRetriever, PromptRetrieverInput }
class PromptRetriever_Retrievers implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -13,6 +14,7 @@ class PromptRetriever_Retrievers implements INode {
constructor() {
this.label = 'Prompt Retriever'
this.name = 'promptRetriever'
+ this.version = 1.0
this.type = 'PromptRetriever'
this.icon = 'promptretriever.svg'
this.category = 'Retrievers'
diff --git a/packages/components/nodes/retrievers/VectorStoreRetriever/VectorStoreRetriever.ts b/packages/components/nodes/retrievers/VectorStoreRetriever/VectorStoreRetriever.ts
index 2ccfc995..41f66571 100644
--- a/packages/components/nodes/retrievers/VectorStoreRetriever/VectorStoreRetriever.ts
+++ b/packages/components/nodes/retrievers/VectorStoreRetriever/VectorStoreRetriever.ts
@@ -4,6 +4,7 @@ import { INode, INodeData, INodeParams, VectorStoreRetriever, VectorStoreRetriev
class VectorStoreRetriever_Retrievers implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -14,6 +15,7 @@ class VectorStoreRetriever_Retrievers implements INode {
constructor() {
this.label = 'Vector Store Retriever'
this.name = 'vectorStoreRetriever'
+ this.version = 1.0
this.type = 'VectorStoreRetriever'
this.icon = 'vectorretriever.svg'
this.category = 'Retrievers'
diff --git a/packages/components/nodes/textsplitters/CharacterTextSplitter/CharacterTextSplitter.ts b/packages/components/nodes/textsplitters/CharacterTextSplitter/CharacterTextSplitter.ts
index 90387e8b..f9427d10 100644
--- a/packages/components/nodes/textsplitters/CharacterTextSplitter/CharacterTextSplitter.ts
+++ b/packages/components/nodes/textsplitters/CharacterTextSplitter/CharacterTextSplitter.ts
@@ -5,6 +5,7 @@ import { CharacterTextSplitter, CharacterTextSplitterParams } from 'langchain/te
class CharacterTextSplitter_TextSplitters implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class CharacterTextSplitter_TextSplitters implements INode {
constructor() {
this.label = 'Character Text Splitter'
this.name = 'characterTextSplitter'
+ this.version = 1.0
this.type = 'CharacterTextSplitter'
this.icon = 'textsplitter.svg'
this.category = 'Text Splitters'
diff --git a/packages/components/nodes/textsplitters/CodeTextSplitter/CodeTextSplitter.ts b/packages/components/nodes/textsplitters/CodeTextSplitter/CodeTextSplitter.ts
index b14655b8..ed643f33 100644
--- a/packages/components/nodes/textsplitters/CodeTextSplitter/CodeTextSplitter.ts
+++ b/packages/components/nodes/textsplitters/CodeTextSplitter/CodeTextSplitter.ts
@@ -9,6 +9,7 @@ import {
class CodeTextSplitter_TextSplitters implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -18,6 +19,7 @@ class CodeTextSplitter_TextSplitters implements INode {
constructor() {
this.label = 'Code Text Splitter'
this.name = 'codeTextSplitter'
+ this.version = 1.0
this.type = 'CodeTextSplitter'
this.icon = 'codeTextSplitter.svg'
this.category = 'Text Splitters'
diff --git a/packages/components/nodes/textsplitters/HtmlToMarkdownTextSplitter/HtmlToMarkdownTextSplitter.ts b/packages/components/nodes/textsplitters/HtmlToMarkdownTextSplitter/HtmlToMarkdownTextSplitter.ts
new file mode 100644
index 00000000..699764e5
--- /dev/null
+++ b/packages/components/nodes/textsplitters/HtmlToMarkdownTextSplitter/HtmlToMarkdownTextSplitter.ts
@@ -0,0 +1,72 @@
+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
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'HtmlToMarkdown Text Splitter'
+ this.name = 'htmlToMarkdownTextSplitter'
+ this.version = 1.0
+ 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 {
+ 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) {
+ {
+ super(fields)
+ }
+ }
+ splitText(text: string): Promise {
+ return new Promise((resolve) => {
+ const markdown = NodeHtmlMarkdown.translate(text)
+ super.splitText(markdown).then((result) => {
+ resolve(result)
+ })
+ })
+ }
+}
+module.exports = { nodeClass: HtmlToMarkdownTextSplitter_TextSplitters }
diff --git a/packages/components/nodes/textsplitters/HtmlToMarkdownTextSplitter/htmlToMarkdownTextSplitter.svg b/packages/components/nodes/textsplitters/HtmlToMarkdownTextSplitter/htmlToMarkdownTextSplitter.svg
new file mode 100644
index 00000000..f7d45d60
--- /dev/null
+++ b/packages/components/nodes/textsplitters/HtmlToMarkdownTextSplitter/htmlToMarkdownTextSplitter.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/textsplitters/MarkdownTextSplitter/MarkdownTextSplitter.ts b/packages/components/nodes/textsplitters/MarkdownTextSplitter/MarkdownTextSplitter.ts
index 02c37d8d..0a12845a 100644
--- a/packages/components/nodes/textsplitters/MarkdownTextSplitter/MarkdownTextSplitter.ts
+++ b/packages/components/nodes/textsplitters/MarkdownTextSplitter/MarkdownTextSplitter.ts
@@ -5,6 +5,7 @@ import { MarkdownTextSplitter, MarkdownTextSplitterParams } from 'langchain/text
class MarkdownTextSplitter_TextSplitters implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class MarkdownTextSplitter_TextSplitters implements INode {
constructor() {
this.label = 'Markdown Text Splitter'
this.name = 'markdownTextSplitter'
+ this.version = 1.0
this.type = 'MarkdownTextSplitter'
this.icon = 'markdownTextSplitter.svg'
this.category = 'Text Splitters'
diff --git a/packages/components/nodes/textsplitters/RecursiveCharacterTextSplitter/RecursiveCharacterTextSplitter.ts b/packages/components/nodes/textsplitters/RecursiveCharacterTextSplitter/RecursiveCharacterTextSplitter.ts
index 432b5ca9..dcca70ba 100644
--- a/packages/components/nodes/textsplitters/RecursiveCharacterTextSplitter/RecursiveCharacterTextSplitter.ts
+++ b/packages/components/nodes/textsplitters/RecursiveCharacterTextSplitter/RecursiveCharacterTextSplitter.ts
@@ -5,6 +5,7 @@ import { RecursiveCharacterTextSplitter, RecursiveCharacterTextSplitterParams }
class RecursiveCharacterTextSplitter_TextSplitters implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class RecursiveCharacterTextSplitter_TextSplitters implements INode {
constructor() {
this.label = 'Recursive Character Text Splitter'
this.name = 'recursiveCharacterTextSplitter'
+ this.version = 1.0
this.type = 'RecursiveCharacterTextSplitter'
this.icon = 'textsplitter.svg'
this.category = 'Text Splitters'
diff --git a/packages/components/nodes/textsplitters/TokenTextSplitter/TokenTextSplitter.ts b/packages/components/nodes/textsplitters/TokenTextSplitter/TokenTextSplitter.ts
index 8c8d6abe..0b11eebc 100644
--- a/packages/components/nodes/textsplitters/TokenTextSplitter/TokenTextSplitter.ts
+++ b/packages/components/nodes/textsplitters/TokenTextSplitter/TokenTextSplitter.ts
@@ -6,6 +6,7 @@ import { TiktokenEncoding } from '@dqbd/tiktoken'
class TokenTextSplitter_TextSplitters implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -16,6 +17,7 @@ class TokenTextSplitter_TextSplitters implements INode {
constructor() {
this.label = 'Token Text Splitter'
this.name = 'tokenTextSplitter'
+ this.version = 1.0
this.type = 'TokenTextSplitter'
this.icon = 'tiktoken.svg'
this.category = 'Text Splitters'
diff --git a/packages/components/nodes/tools/AIPlugin/AIPlugin.ts b/packages/components/nodes/tools/AIPlugin/AIPlugin.ts
index ad21f8db..e9c0fa3d 100644
--- a/packages/components/nodes/tools/AIPlugin/AIPlugin.ts
+++ b/packages/components/nodes/tools/AIPlugin/AIPlugin.ts
@@ -5,6 +5,7 @@ import { getBaseClasses } from '../../../src/utils'
class AIPlugin implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class AIPlugin implements INode {
constructor() {
this.label = 'AI Plugin'
this.name = 'aiPlugin'
+ this.version = 1.0
this.type = 'AIPlugin'
this.icon = 'aiplugin.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/BraveSearchAPI/BraveSearchAPI.ts b/packages/components/nodes/tools/BraveSearchAPI/BraveSearchAPI.ts
new file mode 100644
index 00000000..9e9c760d
--- /dev/null
+++ b/packages/components/nodes/tools/BraveSearchAPI/BraveSearchAPI.ts
@@ -0,0 +1,42 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { BraveSearch } from 'langchain/tools'
+
+class BraveSearchAPI_Tools implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'BraveSearch API'
+ this.name = 'braveSearchAPI'
+ this.version = 1.0
+ 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 = []
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['braveSearchApi']
+ }
+ this.baseClasses = [this.type, ...getBaseClasses(BraveSearch)]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const braveApiKey = getCredentialParam('braveApiKey', credentialData, nodeData)
+ return new BraveSearch({ apiKey: braveApiKey })
+ }
+}
+
+module.exports = { nodeClass: BraveSearchAPI_Tools }
diff --git a/packages/components/nodes/tools/BraveSearchAPI/brave.svg b/packages/components/nodes/tools/BraveSearchAPI/brave.svg
new file mode 100644
index 00000000..0c0c0e86
--- /dev/null
+++ b/packages/components/nodes/tools/BraveSearchAPI/brave.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/tools/Calculator/Calculator.ts b/packages/components/nodes/tools/Calculator/Calculator.ts
index 85284f0f..db1e0b2b 100644
--- a/packages/components/nodes/tools/Calculator/Calculator.ts
+++ b/packages/components/nodes/tools/Calculator/Calculator.ts
@@ -5,6 +5,7 @@ import { Calculator } from 'langchain/tools/calculator'
class Calculator_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -14,6 +15,7 @@ class Calculator_Tools implements INode {
constructor() {
this.label = 'Calculator'
this.name = 'calculator'
+ this.version = 1.0
this.type = 'Calculator'
this.icon = 'calculator.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/ChainTool/ChainTool.ts b/packages/components/nodes/tools/ChainTool/ChainTool.ts
index 32e414af..42b5e6e1 100644
--- a/packages/components/nodes/tools/ChainTool/ChainTool.ts
+++ b/packages/components/nodes/tools/ChainTool/ChainTool.ts
@@ -1,11 +1,12 @@
import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
-import { ChainTool } from 'langchain/tools'
import { BaseChain } from 'langchain/chains'
+import { ChainTool } from './core'
class ChainTool_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -16,6 +17,7 @@ class ChainTool_Tools implements INode {
constructor() {
this.label = 'Chain Tool'
this.name = 'chainTool'
+ this.version = 1.0
this.type = 'ChainTool'
this.icon = 'chaintool.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/ChainTool/core.ts b/packages/components/nodes/tools/ChainTool/core.ts
new file mode 100644
index 00000000..6c3dba55
--- /dev/null
+++ b/packages/components/nodes/tools/ChainTool/core.ts
@@ -0,0 +1,25 @@
+import { DynamicTool, DynamicToolInput } from 'langchain/tools'
+import { BaseChain } from 'langchain/chains'
+
+export interface ChainToolInput extends Omit {
+ chain: BaseChain
+}
+
+export class ChainTool extends DynamicTool {
+ chain: BaseChain
+
+ constructor({ chain, ...rest }: ChainToolInput) {
+ super({
+ ...rest,
+ func: async (input, runManager) => {
+ // To enable LLM Chain which has promptValues
+ if ((chain as any).prompt && (chain as any).prompt.promptValues) {
+ const values = await chain.call((chain as any).prompt.promptValues, runManager?.getChild())
+ return values?.text
+ }
+ return chain.run(input, runManager?.getChild())
+ }
+ })
+ this.chain = chain
+ }
+}
diff --git a/packages/components/nodes/tools/CustomTool/CustomTool.ts b/packages/components/nodes/tools/CustomTool/CustomTool.ts
index 768e9092..26b30627 100644
--- a/packages/components/nodes/tools/CustomTool/CustomTool.ts
+++ b/packages/components/nodes/tools/CustomTool/CustomTool.ts
@@ -7,6 +7,7 @@ import { DataSource } from 'typeorm'
class CustomTool_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class CustomTool_Tools implements INode {
constructor() {
this.label = 'Custom Tool'
this.name = 'customTool'
+ this.version = 1.0
this.type = 'CustomTool'
this.icon = 'customtool.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/CustomTool/core.ts b/packages/components/nodes/tools/CustomTool/core.ts
index 0d3d7bcd..12dd72f1 100644
--- a/packages/components/nodes/tools/CustomTool/core.ts
+++ b/packages/components/nodes/tools/CustomTool/core.ts
@@ -2,7 +2,37 @@ import { z } from 'zod'
import { CallbackManagerForToolRun } from 'langchain/callbacks'
import { StructuredTool, ToolParams } from 'langchain/tools'
import { NodeVM } from 'vm2'
-import { availableDependencies } from '../../../src/utils'
+
+/*
+ * List of dependencies allowed to be import in vm2
+ */
+const availableDependencies = [
+ '@dqbd/tiktoken',
+ '@getzep/zep-js',
+ '@huggingface/inference',
+ '@pinecone-database/pinecone',
+ '@supabase/supabase-js',
+ 'axios',
+ 'cheerio',
+ 'chromadb',
+ 'cohere-ai',
+ 'd3-dsv',
+ 'form-data',
+ 'graphql',
+ 'html-to-text',
+ 'langchain',
+ 'linkifyjs',
+ 'mammoth',
+ 'moment',
+ 'node-fetch',
+ 'pdf-parse',
+ 'pdfjs-dist',
+ 'playwright',
+ 'puppeteer',
+ 'srt-parser-2',
+ 'typeorm',
+ 'weaviate-ts-client'
+]
export interface BaseDynamicToolInput extends ToolParams {
name: string
@@ -51,25 +81,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 = {
console: 'inherit',
sandbox,
require: {
- external: false as boolean | { modules: string[] },
- builtin: ['*']
+ external: { modules: deps },
+ builtin: builtinDeps
}
} 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 response = await vm.run(`module.exports = async function() {${this.code}}()`, __dirname)
diff --git a/packages/components/nodes/tools/GoogleSearchAPI/GoogleSearchAPI.ts b/packages/components/nodes/tools/GoogleSearchAPI/GoogleSearchAPI.ts
new file mode 100644
index 00000000..29ebae8b
--- /dev/null
+++ b/packages/components/nodes/tools/GoogleSearchAPI/GoogleSearchAPI.ts
@@ -0,0 +1,43 @@
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { GoogleCustomSearch } from 'langchain/tools'
+
+class GoogleCustomSearchAPI_Tools implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ credential: INodeParams
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'Google Custom Search'
+ this.name = 'googleCustomSearch'
+ this.version = 1.0
+ this.type = 'GoogleCustomSearchAPI'
+ this.icon = 'google.png'
+ this.category = 'Tools'
+ this.description = 'Wrapper around Google Custom Search API - a real-time API to access Google search results'
+ this.inputs = []
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['googleCustomSearchApi']
+ }
+ this.baseClasses = [this.type, ...getBaseClasses(GoogleCustomSearch)]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const googleApiKey = getCredentialParam('googleCustomSearchApiKey', credentialData, nodeData)
+ const googleCseId = getCredentialParam('googleCustomSearchApiId', credentialData, nodeData)
+ return new GoogleCustomSearch({ apiKey: googleApiKey, googleCSEId: googleCseId })
+ }
+}
+
+module.exports = { nodeClass: GoogleCustomSearchAPI_Tools }
diff --git a/packages/components/nodes/tools/GoogleSearchAPI/google.png b/packages/components/nodes/tools/GoogleSearchAPI/google.png
new file mode 100644
index 00000000..c7cd4ca1
Binary files /dev/null and b/packages/components/nodes/tools/GoogleSearchAPI/google.png differ
diff --git a/packages/components/nodes/tools/MakeWebhook/MakeWebhook.ts b/packages/components/nodes/tools/MakeWebhook/MakeWebhook.ts
index 38e0cdd1..e30e3874 100644
--- a/packages/components/nodes/tools/MakeWebhook/MakeWebhook.ts
+++ b/packages/components/nodes/tools/MakeWebhook/MakeWebhook.ts
@@ -5,6 +5,7 @@ import { MakeWebhookTool } from './core'
class MakeWebhook_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class MakeWebhook_Tools implements INode {
constructor() {
this.label = 'Make.com Webhook'
this.name = 'makeWebhook'
+ this.version = 1.0
this.type = 'MakeWebhook'
this.icon = 'make.png'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/OpenAPIToolkit/OpenAPIToolkit.ts b/packages/components/nodes/tools/OpenAPIToolkit/OpenAPIToolkit.ts
index d6168061..d1bf3891 100644
--- a/packages/components/nodes/tools/OpenAPIToolkit/OpenAPIToolkit.ts
+++ b/packages/components/nodes/tools/OpenAPIToolkit/OpenAPIToolkit.ts
@@ -1,32 +1,39 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { OpenApiToolkit } from 'langchain/agents'
import { JsonSpec, JsonObject } from 'langchain/tools'
import { BaseLanguageModel } from 'langchain/base_language'
import { load } from 'js-yaml'
+import { getCredentialData, getCredentialParam } from '../../../src'
class OpenAPIToolkit_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'OpenAPI Toolkit'
this.name = 'openAPIToolkit'
+ this.version = 1.0
this.type = 'OpenAPIToolkit'
this.icon = 'openapi.png'
this.category = 'Tools'
this.description = 'Load OpenAPI specification'
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Only needed if the YAML OpenAPI Spec requires authentication',
+ optional: true,
+ credentialNames: ['openAPIAuth']
+ }
this.inputs = [
- {
- label: 'OpenAI API Key',
- name: 'openAIApiKey',
- type: 'password'
- },
{
label: 'Language Model',
name: 'model',
@@ -42,11 +49,13 @@ class OpenAPIToolkit_Tools implements INode {
this.baseClasses = [this.type, 'Tool']
}
- async init(nodeData: INodeData): Promise {
- const openAIApiKey = nodeData.inputs?.openAIApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const model = nodeData.inputs?.model as BaseLanguageModel
const yamlFileBase64 = nodeData.inputs?.yamlFile as string
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const openAPIToken = getCredentialParam('openAPIToken', credentialData, nodeData)
+
const splitDataURI = yamlFileBase64.split(',')
splitDataURI.pop()
const bf = Buffer.from(splitDataURI.pop() || '', 'base64')
@@ -56,10 +65,10 @@ class OpenAPIToolkit_Tools implements INode {
throw new Error('Failed to load OpenAPI spec')
}
- const headers = {
- 'Content-Type': 'application/json',
- Authorization: `Bearer ${openAIApiKey}`
+ const headers: ICommonObject = {
+ 'Content-Type': 'application/json'
}
+ if (openAPIToken) headers.Authorization = `Bearer ${openAPIToken}`
const toolkit = new OpenApiToolkit(new JsonSpec(data), model, headers)
return toolkit.tools
diff --git a/packages/components/nodes/tools/ReadFile/ReadFile.ts b/packages/components/nodes/tools/ReadFile/ReadFile.ts
index b6678943..2aa2c66e 100644
--- a/packages/components/nodes/tools/ReadFile/ReadFile.ts
+++ b/packages/components/nodes/tools/ReadFile/ReadFile.ts
@@ -6,6 +6,7 @@ import { NodeFileStore } from 'langchain/stores/file/node'
class ReadFile_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -16,6 +17,7 @@ class ReadFile_Tools implements INode {
constructor() {
this.label = 'Read File'
this.name = 'readFile'
+ this.version = 1.0
this.type = 'ReadFile'
this.icon = 'readfile.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/RequestsGet/RequestsGet.ts b/packages/components/nodes/tools/RequestsGet/RequestsGet.ts
index 0b7f0ac8..91cff500 100644
--- a/packages/components/nodes/tools/RequestsGet/RequestsGet.ts
+++ b/packages/components/nodes/tools/RequestsGet/RequestsGet.ts
@@ -5,6 +5,7 @@ import { desc, RequestParameters, RequestsGetTool } from './core'
class RequestsGet_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class RequestsGet_Tools implements INode {
constructor() {
this.label = 'Requests Get'
this.name = 'requestsGet'
+ this.version = 1.0
this.type = 'RequestsGet'
this.icon = 'requestsget.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/RequestsPost/RequestsPost.ts b/packages/components/nodes/tools/RequestsPost/RequestsPost.ts
index 0e64556f..9ff3d142 100644
--- a/packages/components/nodes/tools/RequestsPost/RequestsPost.ts
+++ b/packages/components/nodes/tools/RequestsPost/RequestsPost.ts
@@ -5,6 +5,7 @@ import { RequestParameters, desc, RequestsPostTool } from './core'
class RequestsPost_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -15,6 +16,7 @@ class RequestsPost_Tools implements INode {
constructor() {
this.label = 'Requests Post'
this.name = 'requestsPost'
+ this.version = 1.0
this.type = 'RequestsPost'
this.icon = 'requestspost.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/SerpAPI/SerpAPI.ts b/packages/components/nodes/tools/SerpAPI/SerpAPI.ts
index 69432408..b7230c85 100644
--- a/packages/components/nodes/tools/SerpAPI/SerpAPI.ts
+++ b/packages/components/nodes/tools/SerpAPI/SerpAPI.ts
@@ -1,37 +1,41 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { SerpAPI } from 'langchain/tools'
class SerpAPI_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Serp API'
this.name = 'serpAPI'
+ this.version = 1.0
this.type = 'SerpAPI'
this.icon = 'serp.png'
this.category = 'Tools'
this.description = 'Wrapper around SerpAPI - a real-time API to access Google search results'
- this.inputs = [
- {
- label: 'Serp Api Key',
- name: 'apiKey',
- type: 'password'
- }
- ]
+ this.inputs = []
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['serpApi']
+ }
this.baseClasses = [this.type, ...getBaseClasses(SerpAPI)]
}
- async init(nodeData: INodeData): Promise {
- const apiKey = nodeData.inputs?.apiKey as string
- return new SerpAPI(apiKey)
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const serpApiKey = getCredentialParam('serpApiKey', credentialData, nodeData)
+ return new SerpAPI(serpApiKey)
}
}
diff --git a/packages/components/nodes/tools/Serper/Serper.ts b/packages/components/nodes/tools/Serper/Serper.ts
index 65dff57c..1facdb3d 100644
--- a/packages/components/nodes/tools/Serper/Serper.ts
+++ b/packages/components/nodes/tools/Serper/Serper.ts
@@ -1,37 +1,41 @@
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
-import { getBaseClasses } from '../../../src/utils'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { Serper } from 'langchain/tools'
class Serper_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
+ credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Serper'
this.name = 'serper'
+ this.version = 1.0
this.type = 'Serper'
this.icon = 'serper.png'
this.category = 'Tools'
this.description = 'Wrapper around Serper.dev - Google Search API'
- this.inputs = [
- {
- label: 'Serper Api Key',
- name: 'apiKey',
- type: 'password'
- }
- ]
+ this.inputs = []
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['serperApi']
+ }
this.baseClasses = [this.type, ...getBaseClasses(Serper)]
}
- async init(nodeData: INodeData): Promise {
- const apiKey = nodeData.inputs?.apiKey as string
- return new Serper(apiKey)
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const serperApiKey = getCredentialParam('serperApiKey', credentialData, nodeData)
+ return new Serper(serperApiKey)
}
}
diff --git a/packages/components/nodes/tools/WebBrowser/WebBrowser.ts b/packages/components/nodes/tools/WebBrowser/WebBrowser.ts
index 09478047..64a093d0 100644
--- a/packages/components/nodes/tools/WebBrowser/WebBrowser.ts
+++ b/packages/components/nodes/tools/WebBrowser/WebBrowser.ts
@@ -7,6 +7,7 @@ import { Embeddings } from 'langchain/embeddings/base'
class WebBrowser_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class WebBrowser_Tools implements INode {
constructor() {
this.label = 'Web Browser'
this.name = 'webBrowser'
+ this.version = 1.0
this.type = 'WebBrowser'
this.icon = 'webBrowser.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/WriteFile/WriteFile.ts b/packages/components/nodes/tools/WriteFile/WriteFile.ts
index 208166d8..2eb7843f 100644
--- a/packages/components/nodes/tools/WriteFile/WriteFile.ts
+++ b/packages/components/nodes/tools/WriteFile/WriteFile.ts
@@ -6,6 +6,7 @@ import { NodeFileStore } from 'langchain/stores/file/node'
class WriteFile_Tools implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -16,6 +17,7 @@ class WriteFile_Tools implements INode {
constructor() {
this.label = 'Write File'
this.name = 'writeFile'
+ this.version = 1.0
this.type = 'WriteFile'
this.icon = 'writefile.svg'
this.category = 'Tools'
diff --git a/packages/components/nodes/tools/ZapierNLA/ZapierNLA.ts b/packages/components/nodes/tools/ZapierNLA/ZapierNLA.ts
index d16e32e6..49543136 100644
--- a/packages/components/nodes/tools/ZapierNLA/ZapierNLA.ts
+++ b/packages/components/nodes/tools/ZapierNLA/ZapierNLA.ts
@@ -1,39 +1,44 @@
import { ZapierNLAWrapper, ZapierNLAWrapperParams } from 'langchain/tools'
-import { INode, INodeData, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { ZapierToolKit } from 'langchain/agents'
+import { getCredentialData, getCredentialParam } from '../../../src'
class ZapierNLA_Tools 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 = 'Zapier NLA'
this.name = 'zapierNLA'
+ this.version = 1.0
this.type = 'ZapierNLA'
- this.icon = 'zapier.png'
+ this.icon = 'zapier.svg'
this.category = 'Tools'
this.description = "Access to apps and actions on Zapier's platform through a natural language API interface"
- this.inputs = [
- {
- label: 'Zapier NLA Api Key',
- name: 'apiKey',
- type: 'password'
- }
- ]
+ this.inputs = []
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['zapierNLAApi']
+ }
this.baseClasses = [this.type, 'Tool']
}
- async init(nodeData: INodeData): Promise {
- const apiKey = nodeData.inputs?.apiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const zapierNLAApiKey = getCredentialParam('zapierNLAApiKey', credentialData, nodeData)
const obj: Partial = {
- apiKey
+ apiKey: zapierNLAApiKey
}
const zapier = new ZapierNLAWrapper(obj)
const toolkit = await ZapierToolKit.fromZapierNLAWrapper(zapier)
diff --git a/packages/components/nodes/tools/ZapierNLA/zapier.png b/packages/components/nodes/tools/ZapierNLA/zapier.png
deleted file mode 100644
index 769716fa..00000000
Binary files a/packages/components/nodes/tools/ZapierNLA/zapier.png and /dev/null differ
diff --git a/packages/components/nodes/tools/ZapierNLA/zapier.svg b/packages/components/nodes/tools/ZapierNLA/zapier.svg
new file mode 100644
index 00000000..6ed35f29
--- /dev/null
+++ b/packages/components/nodes/tools/ZapierNLA/zapier.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/packages/components/nodes/vectorstores/Chroma_Existing/Chroma_Existing.ts b/packages/components/nodes/vectorstores/Chroma_Existing/Chroma_Existing.ts
index 3ce93e87..8b84d33e 100644
--- a/packages/components/nodes/vectorstores/Chroma_Existing/Chroma_Existing.ts
+++ b/packages/components/nodes/vectorstores/Chroma_Existing/Chroma_Existing.ts
@@ -6,6 +6,7 @@ import { getBaseClasses } from '../../../src/utils'
class Chroma_Existing_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class Chroma_Existing_VectorStores implements INode {
constructor() {
this.label = 'Chroma Load Existing Index'
this.name = 'chromaExistingIndex'
+ this.version = 1.0
this.type = 'Chroma'
this.icon = 'chroma.svg'
this.category = 'Vector Stores'
@@ -69,7 +71,7 @@ class Chroma_Existing_VectorStores implements INode {
const chromaURL = nodeData.inputs?.chromaURL as string
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
const obj: {
collectionName: string
diff --git a/packages/components/nodes/vectorstores/Chroma_Upsert/Chroma_Upsert.ts b/packages/components/nodes/vectorstores/Chroma_Upsert/Chroma_Upsert.ts
index f32fbb67..2be1bb3a 100644
--- a/packages/components/nodes/vectorstores/Chroma_Upsert/Chroma_Upsert.ts
+++ b/packages/components/nodes/vectorstores/Chroma_Upsert/Chroma_Upsert.ts
@@ -8,6 +8,7 @@ import { flatten } from 'lodash'
class ChromaUpsert_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -19,6 +20,7 @@ class ChromaUpsert_VectorStores implements INode {
constructor() {
this.label = 'Chroma Upsert Document'
this.name = 'chromaUpsert'
+ this.version = 1.0
this.type = 'Chroma'
this.icon = 'chroma.svg'
this.category = 'Vector Stores'
@@ -78,7 +80,7 @@ class ChromaUpsert_VectorStores implements INode {
const chromaURL = nodeData.inputs?.chromaURL as string
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
const flattenDocs = docs && docs.length ? flatten(docs) : []
const finalDocs = []
diff --git a/packages/components/nodes/vectorstores/Faiss_Existing/Faiss_Existing.ts b/packages/components/nodes/vectorstores/Faiss_Existing/Faiss_Existing.ts
index 6dd18594..8c8d03a8 100644
--- a/packages/components/nodes/vectorstores/Faiss_Existing/Faiss_Existing.ts
+++ b/packages/components/nodes/vectorstores/Faiss_Existing/Faiss_Existing.ts
@@ -6,6 +6,7 @@ import { getBaseClasses } from '../../../src/utils'
class Faiss_Existing_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -17,6 +18,7 @@ class Faiss_Existing_VectorStores implements INode {
constructor() {
this.label = 'Faiss Load Existing Index'
this.name = 'faissExistingIndex'
+ this.version = 1.0
this.type = 'Faiss'
this.icon = 'faiss.svg'
this.category = 'Vector Stores'
@@ -64,7 +66,7 @@ class Faiss_Existing_VectorStores implements INode {
const basePath = nodeData.inputs?.basePath as string
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
const vectorStore = await FaissStore.load(basePath, embeddings)
diff --git a/packages/components/nodes/vectorstores/Faiss_Upsert/Faiss_Upsert.ts b/packages/components/nodes/vectorstores/Faiss_Upsert/Faiss_Upsert.ts
index 5e5f9028..f56eccdf 100644
--- a/packages/components/nodes/vectorstores/Faiss_Upsert/Faiss_Upsert.ts
+++ b/packages/components/nodes/vectorstores/Faiss_Upsert/Faiss_Upsert.ts
@@ -8,6 +8,7 @@ import { flatten } from 'lodash'
class FaissUpsert_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -19,6 +20,7 @@ class FaissUpsert_VectorStores implements INode {
constructor() {
this.label = 'Faiss Upsert Document'
this.name = 'faissUpsert'
+ this.version = 1.0
this.type = 'Faiss'
this.icon = 'faiss.svg'
this.category = 'Vector Stores'
@@ -73,7 +75,7 @@ class FaissUpsert_VectorStores implements INode {
const output = nodeData.outputs?.output as string
const basePath = nodeData.inputs?.basePath as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
const flattenDocs = docs && docs.length ? flatten(docs) : []
const finalDocs = []
diff --git a/packages/components/nodes/vectorstores/InMemory/InMemoryVectorStore.ts b/packages/components/nodes/vectorstores/InMemory/InMemoryVectorStore.ts
index 32a785a5..55a01e2b 100644
--- a/packages/components/nodes/vectorstores/InMemory/InMemoryVectorStore.ts
+++ b/packages/components/nodes/vectorstores/InMemory/InMemoryVectorStore.ts
@@ -8,6 +8,7 @@ import { flatten } from 'lodash'
class InMemoryVectorStore_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
@@ -19,6 +20,7 @@ class InMemoryVectorStore_VectorStores implements INode {
constructor() {
this.label = 'In-Memory Vector Store'
this.name = 'memoryVectorStore'
+ this.version = 1.0
this.type = 'Memory'
this.icon = 'memory.svg'
this.category = 'Vector Stores'
@@ -64,7 +66,7 @@ class InMemoryVectorStore_VectorStores implements INode {
const embeddings = nodeData.inputs?.embeddings as Embeddings
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
const flattenDocs = docs && docs.length ? flatten(docs) : []
const finalDocs = []
diff --git a/packages/components/nodes/vectorstores/OpenSearch_Existing/OpenSearch_existing.ts b/packages/components/nodes/vectorstores/OpenSearch_Existing/OpenSearch_existing.ts
new file mode 100644
index 00000000..c8d09470
--- /dev/null
+++ b/packages/components/nodes/vectorstores/OpenSearch_Existing/OpenSearch_existing.ts
@@ -0,0 +1,97 @@
+import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { OpenSearchVectorStore } from 'langchain/vectorstores/opensearch'
+import { Embeddings } from 'langchain/embeddings/base'
+import { Client } from '@opensearch-project/opensearch'
+import { getBaseClasses } from '../../../src/utils'
+
+class OpenSearch_Existing_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'OpenSearch Load Existing Index'
+ this.name = 'openSearchExistingIndex'
+ this.version = 1.0
+ this.type = 'OpenSearch'
+ this.icon = 'opensearch.png'
+ this.category = 'Vector Stores'
+ this.description = 'Load existing index from OpenSearch (i.e: Document has been upserted)'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.inputs = [
+ {
+ label: 'Embeddings',
+ name: 'embeddings',
+ type: 'Embeddings'
+ },
+ {
+ label: 'OpenSearch URL',
+ name: 'opensearchURL',
+ type: 'string',
+ placeholder: 'http://127.0.0.1:9200'
+ },
+ {
+ label: 'Index Name',
+ name: 'indexName',
+ type: 'string'
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Default to 4',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'OpenSearch Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'OpenSearch Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(OpenSearchVectorStore)]
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData): Promise {
+ const embeddings = nodeData.inputs?.embeddings as Embeddings
+ const opensearchURL = nodeData.inputs?.opensearchURL as string
+ const indexName = nodeData.inputs?.indexName as string
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseFloat(topK) : 4
+
+ const client = new Client({
+ nodes: [opensearchURL]
+ })
+
+ const vectorStore = new OpenSearchVectorStore(embeddings, {
+ client,
+ indexName
+ })
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: OpenSearch_Existing_VectorStores }
diff --git a/packages/components/nodes/vectorstores/OpenSearch_Existing/opensearch.png b/packages/components/nodes/vectorstores/OpenSearch_Existing/opensearch.png
new file mode 100644
index 00000000..3fdcfd3f
Binary files /dev/null and b/packages/components/nodes/vectorstores/OpenSearch_Existing/opensearch.png differ
diff --git a/packages/components/nodes/vectorstores/OpenSearch_Upsert/OpenSearch_Upsert.ts b/packages/components/nodes/vectorstores/OpenSearch_Upsert/OpenSearch_Upsert.ts
new file mode 100644
index 00000000..c11d8b11
--- /dev/null
+++ b/packages/components/nodes/vectorstores/OpenSearch_Upsert/OpenSearch_Upsert.ts
@@ -0,0 +1,112 @@
+import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { OpenSearchVectorStore } from 'langchain/vectorstores/opensearch'
+import { Embeddings } from 'langchain/embeddings/base'
+import { Document } from 'langchain/document'
+import { Client } from '@opensearch-project/opensearch'
+import { flatten } from 'lodash'
+import { getBaseClasses } from '../../../src/utils'
+
+class OpenSearchUpsert_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'OpenSearch Upsert Document'
+ this.name = 'openSearchUpsertDocument'
+ this.version = 1.0
+ this.type = 'OpenSearch'
+ this.icon = 'opensearch.png'
+ this.category = 'Vector Stores'
+ this.description = 'Upsert documents to OpenSearch'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.inputs = [
+ {
+ label: 'Document',
+ name: 'document',
+ type: 'Document',
+ list: true
+ },
+ {
+ label: 'Embeddings',
+ name: 'embeddings',
+ type: 'Embeddings'
+ },
+ {
+ label: 'OpenSearch URL',
+ name: 'opensearchURL',
+ type: 'string',
+ placeholder: 'http://127.0.0.1:9200'
+ },
+ {
+ label: 'Index Name',
+ name: 'indexName',
+ type: 'string'
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Default to 4',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'OpenSearch Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'OpenSearch Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(OpenSearchVectorStore)]
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData): Promise {
+ const docs = nodeData.inputs?.document as Document[]
+ const embeddings = nodeData.inputs?.embeddings as Embeddings
+ const opensearchURL = nodeData.inputs?.opensearchURL as string
+ const indexName = nodeData.inputs?.indexName as string
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseFloat(topK) : 4
+
+ const flattenDocs = docs && docs.length ? flatten(docs) : []
+ const finalDocs = []
+ for (let i = 0; i < flattenDocs.length; i += 1) {
+ finalDocs.push(new Document(flattenDocs[i]))
+ }
+
+ const client = new Client({
+ nodes: [opensearchURL]
+ })
+
+ const vectorStore = await OpenSearchVectorStore.fromDocuments(finalDocs, embeddings, {
+ client,
+ indexName: indexName
+ })
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: OpenSearchUpsert_VectorStores }
diff --git a/packages/components/nodes/vectorstores/OpenSearch_Upsert/opensearch.png b/packages/components/nodes/vectorstores/OpenSearch_Upsert/opensearch.png
new file mode 100644
index 00000000..3fdcfd3f
Binary files /dev/null and b/packages/components/nodes/vectorstores/OpenSearch_Upsert/opensearch.png differ
diff --git a/packages/components/nodes/vectorstores/Pinecone_Existing/Pinecone_Existing.ts b/packages/components/nodes/vectorstores/Pinecone_Existing/Pinecone_Existing.ts
index e57da396..2369165d 100644
--- a/packages/components/nodes/vectorstores/Pinecone_Existing/Pinecone_Existing.ts
+++ b/packages/components/nodes/vectorstores/Pinecone_Existing/Pinecone_Existing.ts
@@ -1,44 +1,43 @@
-import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { PineconeClient } from '@pinecone-database/pinecone'
import { PineconeLibArgs, PineconeStore } from 'langchain/vectorstores/pinecone'
import { Embeddings } from 'langchain/embeddings/base'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
class Pinecone_Existing_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]
+ credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Pinecone Load Existing Index'
this.name = 'pineconeExistingIndex'
+ this.version = 1.0
this.type = 'Pinecone'
this.icon = 'pinecone.png'
this.category = 'Vector Stores'
this.description = 'Load existing index from Pinecone (i.e: Document has been upserted)'
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['pineconeApi']
+ }
this.inputs = [
{
label: 'Embeddings',
name: 'embeddings',
type: 'Embeddings'
},
- {
- label: 'Pinecone Api Key',
- name: 'pineconeApiKey',
- type: 'password'
- },
- {
- label: 'Pinecone Environment',
- name: 'pineconeEnv',
- type: 'string'
- },
{
label: 'Pinecone Index',
name: 'pineconeIndex',
@@ -83,16 +82,18 @@ class Pinecone_Existing_VectorStores implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const pineconeApiKey = nodeData.inputs?.pineconeApiKey as string
- const pineconeEnv = nodeData.inputs?.pineconeEnv as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const index = nodeData.inputs?.pineconeIndex as string
const pineconeNamespace = nodeData.inputs?.pineconeNamespace as string
const pineconeMetadataFilter = nodeData.inputs?.pineconeMetadataFilter
const embeddings = nodeData.inputs?.embeddings as Embeddings
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const pineconeApiKey = getCredentialParam('pineconeApiKey', credentialData, nodeData)
+ const pineconeEnv = getCredentialParam('pineconeEnv', credentialData, nodeData)
const client = new PineconeClient()
await client.init({
diff --git a/packages/components/nodes/vectorstores/Pinecone_Upsert/Pinecone_Upsert.ts b/packages/components/nodes/vectorstores/Pinecone_Upsert/Pinecone_Upsert.ts
index ad1767c2..3d2a6497 100644
--- a/packages/components/nodes/vectorstores/Pinecone_Upsert/Pinecone_Upsert.ts
+++ b/packages/components/nodes/vectorstores/Pinecone_Upsert/Pinecone_Upsert.ts
@@ -1,30 +1,39 @@
-import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { PineconeClient } from '@pinecone-database/pinecone'
import { PineconeLibArgs, PineconeStore } from 'langchain/vectorstores/pinecone'
import { Embeddings } from 'langchain/embeddings/base'
import { Document } from 'langchain/document'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { flatten } from 'lodash'
class PineconeUpsert_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]
+ credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Pinecone Upsert Document'
this.name = 'pineconeUpsert'
+ this.version = 1.0
this.type = 'Pinecone'
this.icon = 'pinecone.png'
this.category = 'Vector Stores'
this.description = 'Upsert documents to Pinecone'
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['pineconeApi']
+ }
this.inputs = [
{
label: 'Document',
@@ -37,16 +46,6 @@ class PineconeUpsert_VectorStores implements INode {
name: 'embeddings',
type: 'Embeddings'
},
- {
- label: 'Pinecone Api Key',
- name: 'pineconeApiKey',
- type: 'password'
- },
- {
- label: 'Pinecone Environment',
- name: 'pineconeEnv',
- type: 'string'
- },
{
label: 'Pinecone Index',
name: 'pineconeIndex',
@@ -84,16 +83,18 @@ class PineconeUpsert_VectorStores implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const pineconeApiKey = nodeData.inputs?.pineconeApiKey as string
- const pineconeEnv = nodeData.inputs?.pineconeEnv as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const index = nodeData.inputs?.pineconeIndex as string
const pineconeNamespace = nodeData.inputs?.pineconeNamespace as string
const docs = nodeData.inputs?.document as Document[]
const embeddings = nodeData.inputs?.embeddings as Embeddings
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const pineconeApiKey = getCredentialParam('pineconeApiKey', credentialData, nodeData)
+ const pineconeEnv = getCredentialParam('pineconeEnv', credentialData, nodeData)
const client = new PineconeClient()
await client.init({
diff --git a/packages/components/nodes/vectorstores/Qdrant_Existing/Qdrant_Existing.ts b/packages/components/nodes/vectorstores/Qdrant_Existing/Qdrant_Existing.ts
new file mode 100644
index 00000000..16f83b08
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Qdrant_Existing/Qdrant_Existing.ts
@@ -0,0 +1,126 @@
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { QdrantClient } from '@qdrant/js-client-rest'
+import { QdrantVectorStore, QdrantLibArgs } from 'langchain/vectorstores/qdrant'
+import { Embeddings } from 'langchain/embeddings/base'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+
+class Qdrant_Existing_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'Qdrant Load Existing Index'
+ this.name = 'qdrantExistingIndex'
+ this.version = 1.0
+ this.type = 'Qdrant'
+ this.icon = 'qdrant.png'
+ this.category = 'Vector Stores'
+ this.description = 'Load existing index from Qdrant (i.e., documents have been upserted)'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Only needed when using Qdrant cloud hosted',
+ optional: true,
+ credentialNames: ['qdrantApi']
+ }
+ this.inputs = [
+ {
+ label: 'Embeddings',
+ name: 'embeddings',
+ type: 'Embeddings'
+ },
+ {
+ label: 'Qdrant Server URL',
+ name: 'qdrantServerUrl',
+ type: 'string',
+ placeholder: 'http://localhost:6333'
+ },
+ {
+ label: 'Qdrant Collection Name',
+ name: 'qdrantCollection',
+ type: 'string'
+ },
+ {
+ label: 'Qdrant Collection Cofiguration',
+ name: 'qdrantCollectionCofiguration',
+ type: 'json',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Default to 4',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'Qdrant Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'Qdrant Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(QdrantVectorStore)]
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const qdrantServerUrl = nodeData.inputs?.qdrantServerUrl as string
+ const collectionName = nodeData.inputs?.qdrantCollection as string
+ let qdrantCollectionCofiguration = nodeData.inputs?.qdrantCollectionCofiguration
+ const embeddings = nodeData.inputs?.embeddings as Embeddings
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const qdrantApiKey = getCredentialParam('qdrantApiKey', credentialData, nodeData)
+
+ const client = new QdrantClient({
+ url: qdrantServerUrl,
+ apiKey: qdrantApiKey
+ })
+
+ const dbConfig: QdrantLibArgs = {
+ client,
+ collectionName
+ }
+
+ if (qdrantCollectionCofiguration) {
+ qdrantCollectionCofiguration =
+ typeof qdrantCollectionCofiguration === 'object' ? qdrantCollectionCofiguration : JSON.parse(qdrantCollectionCofiguration)
+ dbConfig.collectionConfig = qdrantCollectionCofiguration
+ }
+
+ const vectorStore = await QdrantVectorStore.fromExistingCollection(embeddings, dbConfig)
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: Qdrant_Existing_VectorStores }
diff --git a/packages/components/nodes/vectorstores/Qdrant_Existing/qdrant.png b/packages/components/nodes/vectorstores/Qdrant_Existing/qdrant.png
new file mode 100644
index 00000000..ecb2a56d
Binary files /dev/null and b/packages/components/nodes/vectorstores/Qdrant_Existing/qdrant.png differ
diff --git a/packages/components/nodes/vectorstores/Qdrant_Upsert/Qdrant_Upsert.ts b/packages/components/nodes/vectorstores/Qdrant_Upsert/Qdrant_Upsert.ts
new file mode 100644
index 00000000..dcc3099d
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Qdrant_Upsert/Qdrant_Upsert.ts
@@ -0,0 +1,127 @@
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { QdrantClient } from '@qdrant/js-client-rest'
+import { QdrantVectorStore, QdrantLibArgs } from 'langchain/vectorstores/qdrant'
+import { Embeddings } from 'langchain/embeddings/base'
+import { Document } from 'langchain/document'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { flatten } from 'lodash'
+
+class QdrantUpsert_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'Qdrant Upsert Document'
+ this.name = 'qdrantUpsert'
+ this.version = 1.0
+ this.type = 'Qdrant'
+ this.icon = 'qdrant.png'
+ this.category = 'Vector Stores'
+ this.description = 'Upsert documents to Qdrant'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Only needed when using Qdrant cloud hosted',
+ optional: true,
+ credentialNames: ['qdrantApi']
+ }
+ this.inputs = [
+ {
+ label: 'Document',
+ name: 'document',
+ type: 'Document',
+ list: true
+ },
+ {
+ label: 'Embeddings',
+ name: 'embeddings',
+ type: 'Embeddings'
+ },
+ {
+ label: 'Qdrant Server URL',
+ name: 'qdrantServerUrl',
+ type: 'string',
+ placeholder: 'http://localhost:6333'
+ },
+ {
+ label: 'Qdrant Collection Name',
+ name: 'qdrantCollection',
+ type: 'string'
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Default to 4',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'Qdrant Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'Qdrant Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(QdrantVectorStore)]
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const qdrantServerUrl = nodeData.inputs?.qdrantServerUrl as string
+ const collectionName = nodeData.inputs?.qdrantCollection as string
+ const docs = nodeData.inputs?.document as Document[]
+ const embeddings = nodeData.inputs?.embeddings as Embeddings
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const qdrantApiKey = getCredentialParam('qdrantApiKey', credentialData, nodeData)
+
+ const client = new QdrantClient({
+ url: qdrantServerUrl,
+ apiKey: qdrantApiKey
+ })
+
+ const flattenDocs = docs && docs.length ? flatten(docs) : []
+ const finalDocs = []
+ for (let i = 0; i < flattenDocs.length; i += 1) {
+ finalDocs.push(new Document(flattenDocs[i]))
+ }
+
+ const dbConfig: QdrantLibArgs = {
+ client,
+ url: qdrantServerUrl,
+ collectionName
+ }
+ const vectorStore = await QdrantVectorStore.fromDocuments(finalDocs, embeddings, dbConfig)
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: QdrantUpsert_VectorStores }
diff --git a/packages/components/nodes/vectorstores/Qdrant_Upsert/qdrant.png b/packages/components/nodes/vectorstores/Qdrant_Upsert/qdrant.png
new file mode 100644
index 00000000..ecb2a56d
Binary files /dev/null and b/packages/components/nodes/vectorstores/Qdrant_Upsert/qdrant.png differ
diff --git a/packages/components/nodes/vectorstores/Singlestore_Existing/Singlestore_Existing.ts b/packages/components/nodes/vectorstores/Singlestore_Existing/Singlestore_Existing.ts
new file mode 100644
index 00000000..c5f6fbce
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Singlestore_Existing/Singlestore_Existing.ts
@@ -0,0 +1,146 @@
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { Embeddings } from 'langchain/embeddings/base'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { SingleStoreVectorStore, SingleStoreVectorStoreConfig } from 'langchain/vectorstores/singlestore'
+
+class SingleStoreExisting_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'SingleStore Load Existing Table'
+ this.name = 'singlestoreExisting'
+ this.version = 1.0
+ this.type = 'SingleStore'
+ this.icon = 'singlestore.svg'
+ this.category = 'Vector Stores'
+ this.description = 'Load existing document from SingleStore'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Needed when using SingleStore cloud hosted',
+ optional: true,
+ credentialNames: ['singleStoreApi']
+ }
+ this.inputs = [
+ {
+ label: 'Embeddings',
+ name: 'embeddings',
+ type: 'Embeddings'
+ },
+ {
+ label: 'Host',
+ name: 'host',
+ type: 'string'
+ },
+ {
+ label: 'Database',
+ name: 'database',
+ type: 'string'
+ },
+ {
+ label: 'Table Name',
+ name: 'tableName',
+ type: 'string',
+ placeholder: 'embeddings',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Content Column Name',
+ name: 'contentColumnName',
+ type: 'string',
+ placeholder: 'content',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Vector Column Name',
+ name: 'vectorColumnName',
+ type: 'string',
+ placeholder: 'vector',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Metadata Column Name',
+ name: 'metadataColumnName',
+ type: 'string',
+ placeholder: 'metadata',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'SingleStore Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'SingleStore Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(SingleStoreVectorStore)]
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const user = getCredentialParam('user', credentialData, nodeData)
+ const password = getCredentialParam('password', credentialData, nodeData)
+
+ const singleStoreConnectionConfig = {
+ connectionOptions: {
+ host: nodeData.inputs?.host as string,
+ port: 3306,
+ user,
+ password,
+ database: nodeData.inputs?.database as string
+ },
+ ...(nodeData.inputs?.tableName ? { tableName: nodeData.inputs.tableName as string } : {}),
+ ...(nodeData.inputs?.contentColumnName ? { contentColumnName: nodeData.inputs.contentColumnName as string } : {}),
+ ...(nodeData.inputs?.vectorColumnName ? { vectorColumnName: nodeData.inputs.vectorColumnName as string } : {}),
+ ...(nodeData.inputs?.metadataColumnName ? { metadataColumnName: nodeData.inputs.metadataColumnName as string } : {})
+ } as SingleStoreVectorStoreConfig
+
+ const embeddings = nodeData.inputs?.embeddings as Embeddings
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseFloat(topK) : 4
+
+ let vectorStore: SingleStoreVectorStore
+
+ vectorStore = new SingleStoreVectorStore(embeddings, singleStoreConnectionConfig)
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: SingleStoreExisting_VectorStores }
diff --git a/packages/components/nodes/vectorstores/Singlestore_Existing/singlestore.svg b/packages/components/nodes/vectorstores/Singlestore_Existing/singlestore.svg
new file mode 100644
index 00000000..bd8dc817
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Singlestore_Existing/singlestore.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/packages/components/nodes/vectorstores/Singlestore_Upsert/Singlestore_Upsert.ts b/packages/components/nodes/vectorstores/Singlestore_Upsert/Singlestore_Upsert.ts
new file mode 100644
index 00000000..9889a154
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Singlestore_Upsert/Singlestore_Upsert.ts
@@ -0,0 +1,162 @@
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { Embeddings } from 'langchain/embeddings/base'
+import { Document } from 'langchain/document'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { SingleStoreVectorStore, SingleStoreVectorStoreConfig } from 'langchain/vectorstores/singlestore'
+import { flatten } from 'lodash'
+
+class SingleStoreUpsert_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'SingleStore Upsert Document'
+ this.name = 'singlestoreUpsert'
+ this.version = 1.0
+ this.type = 'SingleStore'
+ this.icon = 'singlestore.svg'
+ this.category = 'Vector Stores'
+ this.description = 'Upsert documents to SingleStore'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Needed when using SingleStore cloud hosted',
+ optional: true,
+ credentialNames: ['singleStoreApi']
+ }
+ this.inputs = [
+ {
+ label: 'Document',
+ name: 'document',
+ type: 'Document',
+ list: true
+ },
+ {
+ label: 'Embeddings',
+ name: 'embeddings',
+ type: 'Embeddings'
+ },
+ {
+ label: 'Host',
+ name: 'host',
+ type: 'string'
+ },
+ {
+ label: 'Database',
+ name: 'database',
+ type: 'string'
+ },
+ {
+ label: 'Table Name',
+ name: 'tableName',
+ type: 'string',
+ placeholder: 'embeddings',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Content Column Name',
+ name: 'contentColumnName',
+ type: 'string',
+ placeholder: 'content',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Vector Column Name',
+ name: 'vectorColumnName',
+ type: 'string',
+ placeholder: 'vector',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Metadata Column Name',
+ name: 'metadataColumnName',
+ type: 'string',
+ placeholder: 'metadata',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'SingleStore Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'SingleStore Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(SingleStoreVectorStore)]
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const user = getCredentialParam('user', credentialData, nodeData)
+ const password = getCredentialParam('password', credentialData, nodeData)
+
+ const singleStoreConnectionConfig = {
+ connectionOptions: {
+ host: nodeData.inputs?.host as string,
+ port: 3306,
+ user,
+ password,
+ database: nodeData.inputs?.database as string
+ },
+ ...(nodeData.inputs?.tableName ? { tableName: nodeData.inputs.tableName as string } : {}),
+ ...(nodeData.inputs?.contentColumnName ? { contentColumnName: nodeData.inputs.contentColumnName as string } : {}),
+ ...(nodeData.inputs?.vectorColumnName ? { vectorColumnName: nodeData.inputs.vectorColumnName as string } : {}),
+ ...(nodeData.inputs?.metadataColumnName ? { metadataColumnName: nodeData.inputs.metadataColumnName as string } : {})
+ } as SingleStoreVectorStoreConfig
+
+ const docs = nodeData.inputs?.document as Document[]
+ const embeddings = nodeData.inputs?.embeddings as Embeddings
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseFloat(topK) : 4
+
+ const flattenDocs = docs && docs.length ? flatten(docs) : []
+ const finalDocs = []
+ for (let i = 0; i < flattenDocs.length; i += 1) {
+ finalDocs.push(new Document(flattenDocs[i]))
+ }
+
+ let vectorStore: SingleStoreVectorStore
+
+ vectorStore = new SingleStoreVectorStore(embeddings, singleStoreConnectionConfig)
+ vectorStore.addDocuments.bind(vectorStore)(finalDocs)
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: SingleStoreUpsert_VectorStores }
diff --git a/packages/components/nodes/vectorstores/Singlestore_Upsert/singlestore.svg b/packages/components/nodes/vectorstores/Singlestore_Upsert/singlestore.svg
new file mode 100644
index 00000000..bd8dc817
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Singlestore_Upsert/singlestore.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/packages/components/nodes/vectorstores/Supabase_Existing/Supabase_Exisiting.ts b/packages/components/nodes/vectorstores/Supabase_Existing/Supabase_Exisiting.ts
index 173660ca..ed6febb5 100644
--- a/packages/components/nodes/vectorstores/Supabase_Existing/Supabase_Exisiting.ts
+++ b/packages/components/nodes/vectorstores/Supabase_Existing/Supabase_Exisiting.ts
@@ -1,39 +1,43 @@
-import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { Embeddings } from 'langchain/embeddings/base'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { SupabaseLibArgs, SupabaseVectorStore } from 'langchain/vectorstores/supabase'
import { createClient } from '@supabase/supabase-js'
class Supabase_Existing_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]
+ credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Supabase Load Existing Index'
this.name = 'supabaseExistingIndex'
+ this.version = 1.0
this.type = 'Supabase'
this.icon = 'supabase.svg'
this.category = 'Vector Stores'
this.description = 'Load existing index from Supabase (i.e: Document has been upserted)'
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['supabaseApi']
+ }
this.inputs = [
{
label: 'Embeddings',
name: 'embeddings',
type: 'Embeddings'
},
- {
- label: 'Supabase API Key',
- name: 'supabaseApiKey',
- type: 'password'
- },
{
label: 'Supabase Project URL',
name: 'supabaseProjUrl',
@@ -80,8 +84,7 @@ class Supabase_Existing_VectorStores implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const supabaseApiKey = nodeData.inputs?.supabaseApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const supabaseProjUrl = nodeData.inputs?.supabaseProjUrl as string
const tableName = nodeData.inputs?.tableName as string
const queryName = nodeData.inputs?.queryName as string
@@ -89,7 +92,10 @@ class Supabase_Existing_VectorStores implements INode {
const supabaseMetadataFilter = nodeData.inputs?.supabaseMetadataFilter
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const supabaseApiKey = getCredentialParam('supabaseApiKey', credentialData, nodeData)
const client = createClient(supabaseProjUrl, supabaseApiKey)
diff --git a/packages/components/nodes/vectorstores/Supabase_Upsert/Supabase_Upsert.ts b/packages/components/nodes/vectorstores/Supabase_Upsert/Supabase_Upsert.ts
index 69997a56..90fe2121 100644
--- a/packages/components/nodes/vectorstores/Supabase_Upsert/Supabase_Upsert.ts
+++ b/packages/components/nodes/vectorstores/Supabase_Upsert/Supabase_Upsert.ts
@@ -1,7 +1,7 @@
-import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { Embeddings } from 'langchain/embeddings/base'
import { Document } from 'langchain/document'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'
import { createClient } from '@supabase/supabase-js'
import { flatten } from 'lodash'
@@ -9,22 +9,31 @@ import { flatten } from 'lodash'
class SupabaseUpsert_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]
+ credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Supabase Upsert Document'
this.name = 'supabaseUpsert'
+ this.version = 1.0
this.type = 'Supabase'
this.icon = 'supabase.svg'
this.category = 'Vector Stores'
this.description = 'Upsert documents to Supabase'
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['supabaseApi']
+ }
this.inputs = [
{
label: 'Document',
@@ -37,11 +46,6 @@ class SupabaseUpsert_VectorStores implements INode {
name: 'embeddings',
type: 'Embeddings'
},
- {
- label: 'Supabase API Key',
- name: 'supabaseApiKey',
- type: 'password'
- },
{
label: 'Supabase Project URL',
name: 'supabaseProjUrl',
@@ -81,8 +85,7 @@ class SupabaseUpsert_VectorStores implements INode {
]
}
- async init(nodeData: INodeData): Promise {
- const supabaseApiKey = nodeData.inputs?.supabaseApiKey as string
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const supabaseProjUrl = nodeData.inputs?.supabaseProjUrl as string
const tableName = nodeData.inputs?.tableName as string
const queryName = nodeData.inputs?.queryName as string
@@ -90,7 +93,10 @@ class SupabaseUpsert_VectorStores implements INode {
const embeddings = nodeData.inputs?.embeddings as Embeddings
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const supabaseApiKey = getCredentialParam('supabaseApiKey', credentialData, nodeData)
const client = createClient(supabaseProjUrl, supabaseApiKey)
diff --git a/packages/components/nodes/vectorstores/Vectara_Existing/Vectara_Existing.ts b/packages/components/nodes/vectorstores/Vectara_Existing/Vectara_Existing.ts
new file mode 100644
index 00000000..725a9e32
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Vectara_Existing/Vectara_Existing.ts
@@ -0,0 +1,111 @@
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { VectaraStore, VectaraLibArgs, VectaraFilter } from 'langchain/vectorstores/vectara'
+
+class VectaraExisting_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'Vectara Load Existing Index'
+ this.name = 'vectaraExistingIndex'
+ this.version = 1.0
+ this.type = 'Vectara'
+ this.icon = 'vectara.png'
+ this.category = 'Vector Stores'
+ this.description = 'Load existing index from Vectara (i.e: Document has been upserted)'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['vectaraApi']
+ }
+ this.inputs = [
+ {
+ label: 'Vectara Metadata Filter',
+ name: 'filter',
+ type: 'json',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Lambda',
+ name: 'lambda',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Defaults to 4',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'Vectara Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'Vectara Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(VectaraStore)]
+ }
+ ]
+ }
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
+ const customerId = getCredentialParam('customerID', credentialData, nodeData)
+ const corpusId = getCredentialParam('corpusID', credentialData, nodeData)
+
+ const vectaraMetadatafilter = nodeData.inputs?.filter as VectaraFilter
+ const lambda = nodeData.inputs?.lambda as number
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseInt(topK, 10) : 4
+
+ const vectaraArgs: VectaraLibArgs = {
+ apiKey: apiKey,
+ customerId: customerId,
+ corpusId: corpusId
+ }
+
+ const vectaraFilter: VectaraFilter = {}
+
+ if (vectaraMetadatafilter) {
+ const metadatafilter = typeof vectaraMetadatafilter === 'object' ? vectaraMetadatafilter : JSON.parse(vectaraMetadatafilter)
+ vectaraFilter.filter = metadatafilter
+ }
+
+ if (lambda) vectaraFilter.lambda = lambda
+
+ const vectorStore = new VectaraStore(vectaraArgs)
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k, vectaraFilter)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: VectaraExisting_VectorStores }
diff --git a/packages/components/nodes/vectorstores/Vectara_Existing/vectara.png b/packages/components/nodes/vectorstores/Vectara_Existing/vectara.png
new file mode 100644
index 00000000..a13a34e6
Binary files /dev/null and b/packages/components/nodes/vectorstores/Vectara_Existing/vectara.png differ
diff --git a/packages/components/nodes/vectorstores/Vectara_Upsert/Vectara_Upsert.ts b/packages/components/nodes/vectorstores/Vectara_Upsert/Vectara_Upsert.ts
new file mode 100644
index 00000000..bc236060
--- /dev/null
+++ b/packages/components/nodes/vectorstores/Vectara_Upsert/Vectara_Upsert.ts
@@ -0,0 +1,128 @@
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { Embeddings } from 'langchain/embeddings/base'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+import { VectaraStore, VectaraLibArgs, VectaraFilter } from 'langchain/vectorstores/vectara'
+import { Document } from 'langchain/document'
+import { flatten } from 'lodash'
+
+class VectaraExisting_VectorStores implements INode {
+ label: string
+ name: string
+ version: number
+ description: string
+ type: string
+ icon: string
+ category: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+ outputs: INodeOutputsValue[]
+
+ constructor() {
+ this.label = 'Vectara Upsert Document'
+ this.name = 'vectaraExisting'
+ this.version = 1.0
+ this.type = 'Vectara'
+ this.icon = 'vectara.png'
+ this.category = 'Vector Stores'
+ this.description = 'Upsert documents to Vectara'
+ this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['vectaraApi']
+ }
+ this.inputs = [
+ {
+ label: 'Document',
+ name: 'document',
+ type: 'Document',
+ list: true
+ },
+ {
+ label: 'Filter',
+ name: 'filter',
+ type: 'json',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Lambda',
+ name: 'lambda',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ },
+ {
+ label: 'Top K',
+ name: 'topK',
+ description: 'Number of top results to fetch. Defaults to 4',
+ placeholder: '4',
+ type: 'number',
+ additionalParams: true,
+ optional: true
+ }
+ ]
+ this.outputs = [
+ {
+ label: 'Vectara Retriever',
+ name: 'retriever',
+ baseClasses: this.baseClasses
+ },
+ {
+ label: 'Vectara Vector Store',
+ name: 'vectorStore',
+ baseClasses: [this.type, ...getBaseClasses(VectaraStore)]
+ }
+ ]
+ }
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const apiKey = getCredentialParam('apiKey', credentialData, nodeData)
+ const customerId = getCredentialParam('customerID', credentialData, nodeData)
+ const corpusId = getCredentialParam('corpusID', credentialData, nodeData)
+
+ const docs = nodeData.inputs?.document as Document[]
+ const embeddings = {} as Embeddings
+ const vectaraMetadatafilter = nodeData.inputs?.filter as VectaraFilter
+ const lambda = nodeData.inputs?.lambda as number
+ const output = nodeData.outputs?.output as string
+ const topK = nodeData.inputs?.topK as string
+ const k = topK ? parseInt(topK, 10) : 4
+
+ const vectaraArgs: VectaraLibArgs = {
+ apiKey: apiKey,
+ customerId: customerId,
+ corpusId: corpusId
+ }
+
+ const vectaraFilter: VectaraFilter = {}
+
+ if (vectaraMetadatafilter) {
+ const metadatafilter = typeof vectaraMetadatafilter === 'object' ? vectaraMetadatafilter : JSON.parse(vectaraMetadatafilter)
+ vectaraFilter.filter = metadatafilter
+ }
+
+ if (lambda) vectaraFilter.lambda = lambda
+
+ const flattenDocs = docs && docs.length ? flatten(docs) : []
+ const finalDocs = []
+ for (let i = 0; i < flattenDocs.length; i += 1) {
+ finalDocs.push(new Document(flattenDocs[i]))
+ }
+
+ const vectorStore = await VectaraStore.fromDocuments(finalDocs, embeddings, vectaraArgs)
+
+ if (output === 'retriever') {
+ const retriever = vectorStore.asRetriever(k, vectaraFilter)
+ return retriever
+ } else if (output === 'vectorStore') {
+ ;(vectorStore as any).k = k
+ return vectorStore
+ }
+ return vectorStore
+ }
+}
+
+module.exports = { nodeClass: VectaraExisting_VectorStores }
diff --git a/packages/components/nodes/vectorstores/Vectara_Upsert/vectara.png b/packages/components/nodes/vectorstores/Vectara_Upsert/vectara.png
new file mode 100644
index 00000000..a13a34e6
Binary files /dev/null and b/packages/components/nodes/vectorstores/Vectara_Upsert/vectara.png differ
diff --git a/packages/components/nodes/vectorstores/Weaviate_Existing/Weaviate_Existing.ts b/packages/components/nodes/vectorstores/Weaviate_Existing/Weaviate_Existing.ts
index 595691bd..e35a3917 100644
--- a/packages/components/nodes/vectorstores/Weaviate_Existing/Weaviate_Existing.ts
+++ b/packages/components/nodes/vectorstores/Weaviate_Existing/Weaviate_Existing.ts
@@ -1,28 +1,39 @@
-import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { Embeddings } from 'langchain/embeddings/base'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import weaviate, { WeaviateClient, ApiKey } from 'weaviate-ts-client'
import { WeaviateLibArgs, WeaviateStore } from 'langchain/vectorstores/weaviate'
class Weaviate_Existing_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]
+ credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Weaviate Load Existing Index'
this.name = 'weaviateExistingIndex'
+ this.version = 1.0
this.type = 'Weaviate'
this.icon = 'weaviate.png'
this.category = 'Vector Stores'
this.description = 'Load existing index from Weaviate (i.e: Document has been upserted)'
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Only needed when using Weaviate cloud hosted',
+ optional: true,
+ credentialNames: ['weaviateApi']
+ }
this.inputs = [
{
label: 'Embeddings',
@@ -57,12 +68,6 @@ class Weaviate_Existing_VectorStores implements INode {
type: 'string',
placeholder: 'Test'
},
- {
- label: 'Weaviate API Key',
- name: 'weaviateApiKey',
- type: 'password',
- optional: true
- },
{
label: 'Weaviate Text Key',
name: 'weaviateTextKey',
@@ -104,17 +109,19 @@ class Weaviate_Existing_VectorStores implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const weaviateScheme = nodeData.inputs?.weaviateScheme as string
const weaviateHost = nodeData.inputs?.weaviateHost as string
const weaviateIndex = nodeData.inputs?.weaviateIndex as string
- const weaviateApiKey = nodeData.inputs?.weaviateApiKey as string
const weaviateTextKey = nodeData.inputs?.weaviateTextKey as string
const weaviateMetadataKeys = nodeData.inputs?.weaviateMetadataKeys as string
const embeddings = nodeData.inputs?.embeddings as Embeddings
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const weaviateApiKey = getCredentialParam('weaviateApiKey', credentialData, nodeData)
const clientConfig: any = {
scheme: weaviateScheme,
diff --git a/packages/components/nodes/vectorstores/Weaviate_Upsert/Weaviate_Upsert.ts b/packages/components/nodes/vectorstores/Weaviate_Upsert/Weaviate_Upsert.ts
index 06137426..a2f82831 100644
--- a/packages/components/nodes/vectorstores/Weaviate_Upsert/Weaviate_Upsert.ts
+++ b/packages/components/nodes/vectorstores/Weaviate_Upsert/Weaviate_Upsert.ts
@@ -1,7 +1,7 @@
-import { INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
+import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
import { Embeddings } from 'langchain/embeddings/base'
import { Document } from 'langchain/document'
-import { getBaseClasses } from '../../../src/utils'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { WeaviateLibArgs, WeaviateStore } from 'langchain/vectorstores/weaviate'
import weaviate, { WeaviateClient, ApiKey } from 'weaviate-ts-client'
import { flatten } from 'lodash'
@@ -9,22 +9,33 @@ import { flatten } from 'lodash'
class WeaviateUpsert_VectorStores implements INode {
label: string
name: string
+ version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]
+ credential: INodeParams
outputs: INodeOutputsValue[]
constructor() {
this.label = 'Weaviate Upsert Document'
this.name = 'weaviateUpsert'
+ this.version = 1.0
this.type = 'Weaviate'
this.icon = 'weaviate.png'
this.category = 'Vector Stores'
this.description = 'Upsert documents to Weaviate'
this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever']
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ description: 'Only needed when using Weaviate cloud hosted',
+ optional: true,
+ credentialNames: ['weaviateApi']
+ }
this.inputs = [
{
label: 'Document',
@@ -65,12 +76,6 @@ class WeaviateUpsert_VectorStores implements INode {
type: 'string',
placeholder: 'Test'
},
- {
- label: 'Weaviate API Key',
- name: 'weaviateApiKey',
- type: 'password',
- optional: true
- },
{
label: 'Weaviate Text Key',
name: 'weaviateTextKey',
@@ -112,18 +117,20 @@ class WeaviateUpsert_VectorStores implements INode {
]
}
- async init(nodeData: INodeData): Promise {
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
const weaviateScheme = nodeData.inputs?.weaviateScheme as string
const weaviateHost = nodeData.inputs?.weaviateHost as string
const weaviateIndex = nodeData.inputs?.weaviateIndex as string
- const weaviateApiKey = nodeData.inputs?.weaviateApiKey as string
const weaviateTextKey = nodeData.inputs?.weaviateTextKey as string
const weaviateMetadataKeys = nodeData.inputs?.weaviateMetadataKeys as string
const docs = nodeData.inputs?.document as Document[]
const embeddings = nodeData.inputs?.embeddings as Embeddings
const output = nodeData.outputs?.output as string
const topK = nodeData.inputs?.topK as string
- const k = topK ? parseInt(topK, 10) : 4
+ const k = topK ? parseFloat(topK) : 4
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const weaviateApiKey = getCredentialParam('weaviateApiKey', credentialData, nodeData)
const clientConfig: any = {
scheme: weaviateScheme,
diff --git a/packages/components/package.json b/packages/components/package.json
index bc55fb70..f9529c66 100644
--- a/packages/components/package.json
+++ b/packages/components/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise-components",
- "version": "1.2.14",
+ "version": "1.3.2",
"description": "Flowiseai Components",
"main": "dist/src/index",
"types": "dist/src/index.d.ts",
@@ -16,13 +16,18 @@
},
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
+ "@aws-sdk/client-dynamodb": "^3.360.0",
"@dqbd/tiktoken": "^1.0.7",
- "@getzep/zep-js": "^0.3.1",
- "@huggingface/inference": "1",
- "@pinecone-database/pinecone": "^0.0.12",
- "@supabase/supabase-js": "^2.21.0",
+ "@getzep/zep-js": "^0.4.1",
+ "@huggingface/inference": "^2.6.1",
+ "@notionhq/client": "^2.2.8",
+ "@opensearch-project/opensearch": "^1.2.0",
+ "@pinecone-database/pinecone": "^0.0.14",
+ "@qdrant/js-client-rest": "^1.2.2",
+ "@supabase/supabase-js": "^2.29.0",
"@types/js-yaml": "^4.0.5",
"apify-client": "^2.7.1",
+ "@types/jsdom": "^21.1.1",
"axios": "^0.27.2",
"cheerio": "^1.0.0-rc.12",
"chromadb": "^1.4.2",
@@ -30,19 +35,25 @@
"d3-dsv": "2",
"dotenv": "^16.0.0",
"express": "^4.17.3",
- "faiss-node": "^0.2.1",
+ "faiss-node": "^0.2.2",
"form-data": "^4.0.0",
"graphql": "^16.6.0",
"html-to-text": "^9.0.5",
- "langchain": "^0.0.96",
+ "langchain": "^0.0.117",
"linkifyjs": "^4.1.1",
"mammoth": "^1.5.1",
"moment": "^2.29.3",
+ "mysql2": "^3.5.1",
"node-fetch": "^2.6.11",
+ "node-html-markdown": "^1.3.0",
+ "notion-to-md": "^3.1.1",
"pdf-parse": "^1.1.1",
"pdfjs-dist": "^3.7.107",
"playwright": "^1.35.0",
"puppeteer": "^20.7.1",
+ "pyodide": ">=0.21.0-alpha.2",
+ "redis": "^4.6.7",
+ "replicate": "^0.12.3",
"srt-parser-2": "^1.2.3",
"vm2": "^3.9.19",
"weaviate-ts-client": "^1.1.0",
diff --git a/packages/components/src/Interface.ts b/packages/components/src/Interface.ts
index f8a6fd58..e883d056 100644
--- a/packages/components/src/Interface.ts
+++ b/packages/components/src/Interface.ts
@@ -57,8 +57,11 @@ export interface INodeParams {
type: NodeParamsType | string
default?: CommonType | ICommonObject | ICommonObject[]
description?: string
+ warning?: string
options?: Array
+ credentialNames?: Array
optional?: boolean | INodeDisplay
+ step?: number
rows?: number
list?: boolean
acceptVariable?: boolean
@@ -81,6 +84,7 @@ export interface INodeProperties {
name: string
type: string
icon: string
+ version: number
category: string
baseClasses: string[]
description?: string
@@ -95,16 +99,25 @@ export interface INode extends INodeProperties {
}
init?(nodeData: INodeData, input: string, options?: ICommonObject): Promise
run?(nodeData: INodeData, input: string, options?: ICommonObject): Promise
+ clearSessionMemory?(nodeData: INodeData, options?: ICommonObject): Promise
}
export interface INodeData extends INodeProperties {
id: string
inputs?: ICommonObject
outputs?: ICommonObject
+ credential?: string
instance?: any
loadMethod?: string // method to load async options
}
+export interface INodeCredential {
+ label: string
+ name: string
+ description?: string
+ inputs?: INodeParams[]
+}
+
export interface IMessage {
message: string
type: MessageType
diff --git a/packages/components/src/handler.ts b/packages/components/src/handler.ts
new file mode 100644
index 00000000..8e363361
--- /dev/null
+++ b/packages/components/src/handler.ts
@@ -0,0 +1,180 @@
+import { BaseTracer, Run, BaseCallbackHandler } from 'langchain/callbacks'
+import { AgentAction, ChainValues } from 'langchain/schema'
+import { Logger } from 'winston'
+import { Server } from 'socket.io'
+
+interface AgentRun extends Run {
+ actions: AgentAction[]
+}
+
+function tryJsonStringify(obj: unknown, fallback: string) {
+ try {
+ return JSON.stringify(obj, null, 2)
+ } catch (err) {
+ return fallback
+ }
+}
+
+function elapsed(run: Run): string {
+ if (!run.end_time) return ''
+ const elapsed = run.end_time - run.start_time
+ if (elapsed < 1000) {
+ return `${elapsed}ms`
+ }
+ return `${(elapsed / 1000).toFixed(2)}s`
+}
+
+export class ConsoleCallbackHandler extends BaseTracer {
+ name = 'console_callback_handler' as const
+ logger: Logger
+
+ protected persistRun(_run: Run) {
+ return Promise.resolve()
+ }
+
+ constructor(logger: Logger) {
+ super()
+ this.logger = logger
+ }
+
+ // utility methods
+
+ getParents(run: Run) {
+ const parents: Run[] = []
+ let currentRun = run
+ while (currentRun.parent_run_id) {
+ const parent = this.runMap.get(currentRun.parent_run_id)
+ if (parent) {
+ parents.push(parent)
+ currentRun = parent
+ } else {
+ break
+ }
+ }
+ return parents
+ }
+
+ getBreadcrumbs(run: Run) {
+ const parents = this.getParents(run).reverse()
+ const string = [...parents, run]
+ .map((parent) => {
+ const name = `${parent.execution_order}:${parent.run_type}:${parent.name}`
+ return name
+ })
+ .join(' > ')
+ return string
+ }
+
+ // logging methods
+
+ onChainStart(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(`[chain/start] [${crumbs}] Entering Chain run with input: ${tryJsonStringify(run.inputs, '[inputs]')}`)
+ }
+
+ onChainEnd(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(
+ `[chain/end] [${crumbs}] [${elapsed(run)}] Exiting Chain run with output: ${tryJsonStringify(run.outputs, '[outputs]')}`
+ )
+ }
+
+ onChainError(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(
+ `[chain/error] [${crumbs}] [${elapsed(run)}] Chain run errored with error: ${tryJsonStringify(run.error, '[error]')}`
+ )
+ }
+
+ onLLMStart(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ const inputs = 'prompts' in run.inputs ? { prompts: (run.inputs.prompts as string[]).map((p) => p.trim()) } : run.inputs
+ this.logger.verbose(`[llm/start] [${crumbs}] Entering LLM run with input: ${tryJsonStringify(inputs, '[inputs]')}`)
+ }
+
+ onLLMEnd(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(
+ `[llm/end] [${crumbs}] [${elapsed(run)}] Exiting LLM run with output: ${tryJsonStringify(run.outputs, '[response]')}`
+ )
+ }
+
+ onLLMError(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(
+ `[llm/error] [${crumbs}] [${elapsed(run)}] LLM run errored with error: ${tryJsonStringify(run.error, '[error]')}`
+ )
+ }
+
+ onToolStart(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(`[tool/start] [${crumbs}] Entering Tool run with input: "${run.inputs.input?.trim()}"`)
+ }
+
+ onToolEnd(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(`[tool/end] [${crumbs}] [${elapsed(run)}] Exiting Tool run with output: "${run.outputs?.output?.trim()}"`)
+ }
+
+ onToolError(run: Run) {
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(
+ `[tool/error] [${crumbs}] [${elapsed(run)}] Tool run errored with error: ${tryJsonStringify(run.error, '[error]')}`
+ )
+ }
+
+ onAgentAction(run: Run) {
+ const agentRun = run as AgentRun
+ const crumbs = this.getBreadcrumbs(run)
+ this.logger.verbose(
+ `[agent/action] [${crumbs}] Agent selected action: ${tryJsonStringify(
+ agentRun.actions[agentRun.actions.length - 1],
+ '[action]'
+ )}`
+ )
+ }
+}
+
+/**
+ * Custom chain handler class
+ */
+export class CustomChainHandler extends BaseCallbackHandler {
+ name = 'custom_chain_handler'
+ isLLMStarted = false
+ socketIO: Server
+ socketIOClientId = ''
+ skipK = 0 // Skip streaming for first K numbers of handleLLMStart
+ returnSourceDocuments = false
+
+ constructor(socketIO: Server, socketIOClientId: string, skipK?: number, returnSourceDocuments?: boolean) {
+ super()
+ this.socketIO = socketIO
+ this.socketIOClientId = socketIOClientId
+ this.skipK = skipK ?? this.skipK
+ this.returnSourceDocuments = returnSourceDocuments ?? this.returnSourceDocuments
+ }
+
+ handleLLMStart() {
+ if (this.skipK > 0) this.skipK -= 1
+ }
+
+ handleLLMNewToken(token: string) {
+ if (this.skipK === 0) {
+ if (!this.isLLMStarted) {
+ this.isLLMStarted = true
+ this.socketIO.to(this.socketIOClientId).emit('start', token)
+ }
+ this.socketIO.to(this.socketIOClientId).emit('token', token)
+ }
+ }
+
+ handleLLMEnd() {
+ this.socketIO.to(this.socketIOClientId).emit('end')
+ }
+
+ handleChainEnd(outputs: ChainValues): void | Promise {
+ if (this.returnSourceDocuments) {
+ this.socketIO.to(this.socketIOClientId).emit('sourceDocuments', outputs?.sourceDocuments)
+ }
+ }
+}
diff --git a/packages/components/src/utils.ts b/packages/components/src/utils.ts
index ad8d28dc..363dd026 100644
--- a/packages/components/src/utils.ts
+++ b/packages/components/src/utils.ts
@@ -2,9 +2,10 @@ import axios from 'axios'
import { load } from 'cheerio'
import * as fs from 'fs'
import * as path from 'path'
-import { BaseCallbackHandler } from 'langchain/callbacks'
-import { Server } from 'socket.io'
-import { ChainValues } from 'langchain/dist/schema'
+import { JSDOM } from 'jsdom'
+import { DataSource } from 'typeorm'
+import { ICommonObject, IDatabaseEntity, INodeData } from './Interface'
+import { AES, enc } from 'crypto-js'
export const numberOrExpressionRegex = '^(\\d+\\.?\\d*|{{.*}})$' //return true if string consists only numbers OR expression {{}}
export const notEmptyRegex = '(.|\\s)*\\S(.|\\s)*' //return true if string is not empty or blank
@@ -202,114 +203,282 @@ export const getAvailableURLs = async (url: string, limit: number) => {
}
/**
- * Custom chain handler class
+ * Search for href through htmlBody string
*/
-export class CustomChainHandler extends BaseCallbackHandler {
- name = 'custom_chain_handler'
- isLLMStarted = false
- socketIO: Server
- socketIOClientId = ''
- skipK = 0 // Skip streaming for first K numbers of handleLLMStart
- returnSourceDocuments = false
-
- constructor(socketIO: Server, socketIOClientId: string, skipK?: number, returnSourceDocuments?: boolean) {
- super()
- this.socketIO = socketIO
- this.socketIOClientId = socketIOClientId
- this.skipK = skipK ?? this.skipK
- this.returnSourceDocuments = returnSourceDocuments ?? this.returnSourceDocuments
- }
-
- handleLLMStart() {
- if (this.skipK > 0) this.skipK -= 1
- }
-
- handleLLMNewToken(token: string) {
- if (this.skipK === 0) {
- if (!this.isLLMStarted) {
- this.isLLMStarted = true
- this.socketIO.to(this.socketIOClientId).emit('start', token)
+function getURLsFromHTML(htmlBody: string, baseURL: string): string[] {
+ const dom = new JSDOM(htmlBody)
+ const linkElements = dom.window.document.querySelectorAll('a')
+ const urls: string[] = []
+ for (const linkElement of linkElements) {
+ if (linkElement.href.slice(0, 1) === '/') {
+ try {
+ const urlObj = new URL(baseURL + linkElement.href)
+ urls.push(urlObj.href) //relative
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error with relative url: ${err.message}`)
+ continue
}
- this.socketIO.to(this.socketIOClientId).emit('token', token)
- }
- }
-
- handleLLMEnd() {
- this.socketIO.to(this.socketIOClientId).emit('end')
- }
-
- handleChainEnd(outputs: ChainValues): void | Promise {
- if (this.returnSourceDocuments) {
- this.socketIO.to(this.socketIOClientId).emit('sourceDocuments', outputs?.sourceDocuments)
- }
- }
-}
-
-export const returnJSONStr = (jsonStr: string): string => {
- let jsonStrArray = jsonStr.split(':')
-
- let wholeString = ''
- for (let i = 0; i < jsonStrArray.length; i++) {
- if (jsonStrArray[i].includes(',') && jsonStrArray[i + 1] !== undefined) {
- const splitValueAndTitle = jsonStrArray[i].split(',')
- const value = splitValueAndTitle[0]
- const newTitle = splitValueAndTitle[1]
- wholeString += handleEscapeDoubleQuote(value) + ',' + newTitle + ':'
} else {
- wholeString += wholeString === '' ? jsonStrArray[i] + ':' : handleEscapeDoubleQuote(jsonStrArray[i])
- }
- }
- return wholeString
-}
-
-const handleEscapeDoubleQuote = (value: string): string => {
- let newValue = ''
- if (value.includes('"')) {
- const valueArray = value.split('"')
- for (let i = 0; i < valueArray.length; i++) {
- if ((i + 1) % 2 !== 0) {
- switch (valueArray[i]) {
- case '':
- newValue += '"'
- break
- case '}':
- newValue += '"}'
- break
- default:
- newValue += '\\"' + valueArray[i] + '\\"'
- }
- } else {
- newValue += valueArray[i]
+ try {
+ const urlObj = new URL(linkElement.href)
+ urls.push(urlObj.href) //absolute
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error with absolute url: ${err.message}`)
+ continue
}
}
}
- return newValue === '' ? value : newValue
+ return urls
}
-export const availableDependencies = [
- '@dqbd/tiktoken',
- '@getzep/zep-js',
- '@huggingface/inference',
- '@pinecone-database/pinecone',
- '@supabase/supabase-js',
- 'axios',
- 'cheerio',
- 'chromadb',
- 'cohere-ai',
- 'd3-dsv',
- 'form-data',
- 'graphql',
- 'html-to-text',
- 'langchain',
- 'linkifyjs',
- 'mammoth',
- 'moment',
- 'node-fetch',
- 'pdf-parse',
- 'pdfjs-dist',
- 'playwright',
- 'puppeteer',
- 'srt-parser-2',
- 'typeorm',
- 'weaviate-ts-client'
+/**
+ * Normalize URL to prevent crawling the same page
+ */
+function normalizeURL(urlString: string): string {
+ const urlObj = new URL(urlString)
+ const hostPath = urlObj.hostname + urlObj.pathname
+ if (hostPath.length > 0 && hostPath.slice(-1) == '/') {
+ // handling trailing slash
+ return hostPath.slice(0, -1)
+ }
+ return hostPath
+}
+
+/**
+ * Recursive crawl using normalizeURL and getURLsFromHTML
+ */
+async function crawl(baseURL: string, currentURL: string, pages: string[], limit: number): Promise {
+ const baseURLObj = new URL(baseURL)
+ const currentURLObj = new URL(currentURL)
+
+ if (limit !== 0 && pages.length === limit) return pages
+
+ if (baseURLObj.hostname !== currentURLObj.hostname) return pages
+
+ const normalizeCurrentURL = baseURLObj.protocol + '//' + normalizeURL(currentURL)
+ if (pages.includes(normalizeCurrentURL)) {
+ return pages
+ }
+
+ pages.push(normalizeCurrentURL)
+
+ if (process.env.DEBUG === 'true') console.info(`actively crawling ${currentURL}`)
+ try {
+ const resp = await fetch(currentURL)
+
+ if (resp.status > 399) {
+ if (process.env.DEBUG === 'true') console.error(`error in fetch with status code: ${resp.status}, on page: ${currentURL}`)
+ return pages
+ }
+
+ const contentType: string | null = resp.headers.get('content-type')
+ if ((contentType && !contentType.includes('text/html')) || !contentType) {
+ if (process.env.DEBUG === 'true') console.error(`non html response, content type: ${contentType}, on page: ${currentURL}`)
+ return pages
+ }
+
+ const htmlBody = await resp.text()
+ const nextURLs = getURLsFromHTML(htmlBody, baseURL)
+ for (const nextURL of nextURLs) {
+ pages = await crawl(baseURL, nextURL, pages, limit)
+ }
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error in fetch url: ${err.message}, on page: ${currentURL}`)
+ }
+ return pages
+}
+
+/**
+ * Prep URL before passing into recursive carwl function
+ */
+export async function webCrawl(stringURL: string, limit: number): Promise {
+ const URLObj = new URL(stringURL)
+ const modifyURL = stringURL.slice(-1) === '/' ? stringURL.slice(0, -1) : stringURL
+ return await crawl(URLObj.protocol + '//' + URLObj.hostname, modifyURL, [], limit)
+}
+
+export function getURLsFromXML(xmlBody: string, limit: number): string[] {
+ const dom = new JSDOM(xmlBody, { contentType: 'text/xml' })
+ const linkElements = dom.window.document.querySelectorAll('url')
+ const urls: string[] = []
+ for (const linkElement of linkElements) {
+ const locElement = linkElement.querySelector('loc')
+ if (limit !== 0 && urls.length === limit) break
+ if (locElement?.textContent) {
+ urls.push(locElement.textContent)
+ }
+ }
+ return urls
+}
+
+export async function xmlScrape(currentURL: string, limit: number): Promise {
+ let urls: string[] = []
+ if (process.env.DEBUG === 'true') console.info(`actively scarping ${currentURL}`)
+ try {
+ const resp = await fetch(currentURL)
+
+ if (resp.status > 399) {
+ if (process.env.DEBUG === 'true') console.error(`error in fetch with status code: ${resp.status}, on page: ${currentURL}`)
+ return urls
+ }
+
+ const contentType: string | null = resp.headers.get('content-type')
+ 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}`)
+ return urls
+ }
+
+ const xmlBody = await resp.text()
+ urls = getURLsFromXML(xmlBody, limit)
+ } catch (err) {
+ if (process.env.DEBUG === 'true') console.error(`error in fetch url: ${err.message}, on page: ${currentURL}`)
+ }
+ return urls
+}
+
+/*
+ * Get env variables
+ * @param {string} url
+ * @returns {string[]}
+ */
+export const getEnvironmentVariable = (name: string): string | undefined => {
+ try {
+ return typeof process !== 'undefined' ? process.env?.[name] : undefined
+ } catch (e) {
+ return undefined
+ }
+}
+
+/**
+ * Returns the path of encryption key
+ * @returns {string}
+ */
+const getEncryptionKeyFilePath = (): string => {
+ const checkPaths = [
+ path.join(__dirname, '..', '..', 'encryption.key'),
+ path.join(__dirname, '..', '..', 'server', 'encryption.key'),
+ path.join(__dirname, '..', '..', '..', 'encryption.key'),
+ path.join(__dirname, '..', '..', '..', 'server', 'encryption.key'),
+ path.join(__dirname, '..', '..', '..', '..', 'encryption.key'),
+ path.join(__dirname, '..', '..', '..', '..', 'server', 'encryption.key'),
+ path.join(__dirname, '..', '..', '..', '..', '..', 'encryption.key'),
+ path.join(__dirname, '..', '..', '..', '..', '..', 'server', 'encryption.key')
+ ]
+ for (const checkPath of checkPaths) {
+ if (fs.existsSync(checkPath)) {
+ return checkPath
+ }
+ }
+ return ''
+}
+
+const getEncryptionKeyPath = (): string => {
+ return process.env.SECRETKEY_PATH ? path.join(process.env.SECRETKEY_PATH, 'encryption.key') : getEncryptionKeyFilePath()
+}
+
+/**
+ * Returns the encryption key
+ * @returns {Promise}
+ */
+const getEncryptionKey = async (): Promise => {
+ try {
+ return await fs.promises.readFile(getEncryptionKeyPath(), 'utf8')
+ } catch (error) {
+ throw new Error(error)
+ }
+}
+
+/**
+ * Decrypt credential data
+ * @param {string} encryptedData
+ * @param {string} componentCredentialName
+ * @param {IComponentCredentials} componentCredentials
+ * @returns {Promise}
+ */
+const decryptCredentialData = async (encryptedData: string): Promise => {
+ const encryptKey = await getEncryptionKey()
+ const decryptedData = AES.decrypt(encryptedData, encryptKey)
+ try {
+ return JSON.parse(decryptedData.toString(enc.Utf8))
+ } catch (e) {
+ console.error(e)
+ throw new Error('Credentials could not be decrypted.')
+ }
+}
+
+/**
+ * Get credential data
+ * @param {string} selectedCredentialId
+ * @param {ICommonObject} options
+ * @returns {Promise}
+ */
+export const getCredentialData = async (selectedCredentialId: string, options: ICommonObject): Promise => {
+ const appDataSource = options.appDataSource as DataSource
+ const databaseEntities = options.databaseEntities as IDatabaseEntity
+
+ try {
+ const credential = await appDataSource.getRepository(databaseEntities['Credential']).findOneBy({
+ id: selectedCredentialId
+ })
+
+ if (!credential) return {}
+
+ // Decrpyt credentialData
+ const decryptedCredentialData = await decryptCredentialData(credential.encryptedData)
+
+ return decryptedCredentialData
+ } catch (e) {
+ throw new Error(e)
+ }
+}
+
+export const getCredentialParam = (paramName: string, credentialData: ICommonObject, nodeData: INodeData): any => {
+ return (nodeData.inputs as ICommonObject)[paramName] ?? credentialData[paramName] ?? undefined
+}
+
+// reference https://www.freeformatter.com/json-escape.html
+const jsonEscapeCharacters = [
+ { escape: '"', value: 'FLOWISE_DOUBLE_QUOTE' },
+ { escape: '\n', value: 'FLOWISE_NEWLINE' },
+ { escape: '\b', value: 'FLOWISE_BACKSPACE' },
+ { escape: '\f', value: 'FLOWISE_FORM_FEED' },
+ { escape: '\r', value: 'FLOWISE_CARRIAGE_RETURN' },
+ { escape: '\t', value: 'FLOWISE_TAB' },
+ { escape: '\\', value: 'FLOWISE_BACKSLASH' }
]
+
+function handleEscapesJSONParse(input: string, reverse: Boolean): string {
+ for (const element of jsonEscapeCharacters) {
+ input = reverse ? input.replaceAll(element.value, element.escape) : input.replaceAll(element.escape, element.value)
+ }
+ return input
+}
+
+function iterateEscapesJSONParse(input: any, reverse: Boolean): any {
+ for (const element in input) {
+ const type = typeof input[element]
+ if (type === 'string') input[element] = handleEscapesJSONParse(input[element], reverse)
+ else if (type === 'object') input[element] = iterateEscapesJSONParse(input[element], reverse)
+ }
+ return input
+}
+
+export function handleEscapeCharacters(input: any, reverse: Boolean): any {
+ const type = typeof input
+ if (type === 'string') return handleEscapesJSONParse(input, reverse)
+ else if (type === 'object') return iterateEscapesJSONParse(input, reverse)
+ return input
+}
+
+export const getUserHome = (): string => {
+ let variableName = 'HOME'
+ if (process.platform === 'win32') {
+ variableName = 'USERPROFILE'
+ }
+
+ if (process.env[variableName] === undefined) {
+ // If for some reason the variable does not exist, fall back to current folder
+ return process.cwd()
+ }
+ return process.env[variableName] as string
+}
diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json
index 2002d62f..d213dabc 100644
--- a/packages/components/tsconfig.json
+++ b/packages/components/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "lib": ["ES2020"],
+ "lib": ["ES2020", "ES2021.String"],
"experimentalDecorators": true /* Enable experimental support for TC39 stage 2 draft decorators. */,
"emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */,
"target": "ES2020", // or higher
@@ -16,5 +16,5 @@
"declaration": true,
"module": "commonjs"
},
- "include": ["src", "nodes"]
+ "include": ["src", "nodes", "credentials"]
}
diff --git a/packages/server/.env.example b/packages/server/.env.example
index e313316d..1e10452c 100644
--- a/packages/server/.env.example
+++ b/packages/server/.env.example
@@ -1,5 +1,22 @@
PORT=3000
+PASSPHRASE=MYPASSPHRASE # Passphrase used to create encryption key
+# DATABASE_PATH=/your_database_path/.flowise
+# APIKEY_PATH=/your_api_key_path/.flowise
+# SECRETKEY_PATH=/your_api_key_path/.flowise
+# LOG_PATH=/your_log_path/.flowise/logs
+
+# DATABASE_TYPE=postgres
+# DATABASE_PORT=""
+# DATABASE_HOST=""
+# DATABASE_NAME="flowise"
+# DATABASE_USER=""
+# DATABASE_PASSWORD=""
+# OVERRIDE_DATABASE=true
+
# FLOWISE_USERNAME=user
# FLOWISE_PASSWORD=1234
-# DATABASE_PATH=/your_database_path/.flowise
-# EXECUTION_MODE=child or main
\ No newline at end of file
+# DEBUG=true
+# LOG_LEVEL=debug (error | warn | info | verbose | debug)
+# EXECUTION_MODE=main (child | main)
+# TOOL_FUNCTION_BUILTIN_DEP=crypto,fs
+# TOOL_FUNCTION_EXTERNAL_DEP=moment,lodash
diff --git a/packages/server/README.md b/packages/server/README.md
index e4d1e439..6c3bc7f9 100644
--- a/packages/server/README.md
+++ b/packages/server/README.md
@@ -1,10 +1,10 @@
-# Flowise - LangchainJS UI
+# Flowise - Low-Code LLM apps builder

-Drag & drop UI to build your customized LLM flow using [LangchainJS](https://github.com/hwchase17/langchainjs)
+Drag & drop UI to build your customized LLM flow
## β‘Quick Start
@@ -29,6 +29,16 @@ FLOWISE_USERNAME=user
FLOWISE_PASSWORD=1234
```
+## π± 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. Read [more](https://github.com/FlowiseAI/Flowise/blob/main/CONTRIBUTING.md#-env-variables)
+
+You can also specify the env variables when using `npx`. For example:
+
+```
+npx flowise start --PORT=3000 --DEBUG=true
+```
+
## π Documentation
[Flowise Docs](https://docs.flowiseai.com/)
diff --git a/packages/server/marketplaces/chatflows/API Agent OpenAI.json b/packages/server/marketplaces/chatflows/API Agent OpenAI.json
new file mode 100644
index 00000000..01e3d8f9
--- /dev/null
+++ b/packages/server/marketplaces/chatflows/API Agent OpenAI.json
@@ -0,0 +1,650 @@
+{
+ "description": "Use OpenAI Function Agent and Chain to automatically decide which API to call, generating url and body request from conversation",
+ "nodes": [
+ {
+ "width": 300,
+ "height": 510,
+ "id": "openApiChain_1",
+ "position": {
+ "x": 1203.1825726424859,
+ "y": 300.7226683414998
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openApiChain_1",
+ "label": "OpenAPI Chain",
+ "name": "openApiChain",
+ "version": 1,
+ "type": "OpenAPIChain",
+ "baseClasses": ["OpenAPIChain", "BaseChain"],
+ "category": "Chains",
+ "description": "Chain that automatically select and call APIs based only on an OpenAPI spec",
+ "inputParams": [
+ {
+ "label": "YAML Link",
+ "name": "yamlLink",
+ "type": "string",
+ "placeholder": "https://api.speak.com/openapi.yaml",
+ "description": "If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead",
+ "id": "openApiChain_1-input-yamlLink-string"
+ },
+ {
+ "label": "YAML File",
+ "name": "yamlFile",
+ "type": "file",
+ "fileType": ".yaml",
+ "description": "If YAML link is provided, uploaded YAML File will be ignored and YAML link will be used instead",
+ "id": "openApiChain_1-input-yamlFile-file"
+ },
+ {
+ "label": "Headers",
+ "name": "headers",
+ "type": "json",
+ "additionalParams": true,
+ "optional": true,
+ "id": "openApiChain_1-input-headers-json"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "ChatOpenAI Model",
+ "name": "model",
+ "type": "ChatOpenAI",
+ "id": "openApiChain_1-input-model-ChatOpenAI"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_1.data.instance}}",
+ "yamlLink": "https://gist.githubusercontent.com/roaldnefs/053e505b2b7a807290908fe9aa3e1f00/raw/0a212622ebfef501163f91e23803552411ed00e4/openapi.yaml",
+ "headers": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openApiChain_1-output-openApiChain-OpenAPIChain|BaseChain",
+ "name": "openApiChain",
+ "label": "OpenAPIChain",
+ "type": "OpenAPIChain | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1203.1825726424859,
+ "y": 300.7226683414998
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_1",
+ "position": {
+ "x": 792.3201947594027,
+ "y": 293.61889966751846
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_1",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_1-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_1-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_1-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 792.3201947594027,
+ "y": 293.61889966751846
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 602,
+ "id": "chainTool_0",
+ "position": {
+ "x": 1635.3466862861876,
+ "y": 272.3189405402944
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chainTool_0",
+ "label": "Chain Tool",
+ "name": "chainTool",
+ "version": 1,
+ "type": "ChainTool",
+ "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool"],
+ "category": "Tools",
+ "description": "Use a chain as allowed tool for agent",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "name",
+ "type": "string",
+ "placeholder": "state-of-union-qa",
+ "id": "chainTool_0-input-name-string"
+ },
+ {
+ "label": "Chain Description",
+ "name": "description",
+ "type": "string",
+ "rows": 3,
+ "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
+ "id": "chainTool_0-input-description-string"
+ },
+ {
+ "label": "Return Direct",
+ "name": "returnDirect",
+ "type": "boolean",
+ "optional": true,
+ "id": "chainTool_0-input-returnDirect-boolean"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Base Chain",
+ "name": "baseChain",
+ "type": "BaseChain",
+ "id": "chainTool_0-input-baseChain-BaseChain"
+ }
+ ],
+ "inputs": {
+ "name": "comic-qa",
+ "description": "useful for when you need to ask question about comic",
+ "returnDirect": "",
+ "baseChain": "{{openApiChain_1.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "chainTool_0-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool",
+ "name": "chainTool",
+ "label": "ChainTool",
+ "type": "ChainTool | DynamicTool | Tool | StructuredTool"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1635.3466862861876,
+ "y": 272.3189405402944
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 383,
+ "id": "openAIFunctionAgent_0",
+ "position": {
+ "x": 2076.1829525256576,
+ "y": 706.1299276365058
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIFunctionAgent_0",
+ "label": "OpenAI Function Agent",
+ "name": "openAIFunctionAgent",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain"],
+ "category": "Agents",
+ "description": "An agent that uses OpenAI's Function Calling functionality to pick the tool and args to call",
+ "inputParams": [
+ {
+ "label": "System Message",
+ "name": "systemMessage",
+ "type": "string",
+ "rows": 4,
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIFunctionAgent_0-input-systemMessage-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "openAIFunctionAgent_0-input-tools-Tool"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseChatMemory",
+ "id": "openAIFunctionAgent_0-input-memory-BaseChatMemory"
+ },
+ {
+ "label": "OpenAI Chat Model",
+ "name": "model",
+ "description": "Only works with gpt-3.5-turbo-0613 and gpt-4-0613. Refer docs for more info",
+ "type": "BaseChatModel",
+ "id": "openAIFunctionAgent_0-input-model-BaseChatModel"
+ }
+ ],
+ "inputs": {
+ "tools": ["{{chainTool_0.data.instance}}"],
+ "memory": "{{bufferMemory_0.data.instance}}",
+ "model": "{{chatOpenAI_2.data.instance}}",
+ "systemMessage": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIFunctionAgent_0-output-openAIFunctionAgent-AgentExecutor|BaseChain",
+ "name": "openAIFunctionAgent",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 2076.1829525256576,
+ "y": 706.1299276365058
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_2",
+ "position": {
+ "x": 1645.450699499575,
+ "y": 992.6341744217375
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_2",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_2-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_2-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_2-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_2-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_2-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_2-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_2-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_2-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_2-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1645.450699499575,
+ "y": 992.6341744217375
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 376,
+ "id": "bufferMemory_0",
+ "position": {
+ "x": 1148.8461056155377,
+ "y": 967.8215757228843
+ },
+ "type": "customNode",
+ "data": {
+ "id": "bufferMemory_0",
+ "label": "Buffer Memory",
+ "name": "bufferMemory",
+ "version": 1,
+ "type": "BufferMemory",
+ "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Remembers previous conversational back and forths directly",
+ "inputParams": [
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "id": "bufferMemory_0-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "id": "bufferMemory_0-input-inputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "memoryKey": "chat_history",
+ "inputKey": "input"
+ },
+ "outputAnchors": [
+ {
+ "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "name": "bufferMemory",
+ "label": "BufferMemory",
+ "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 1148.8461056155377,
+ "y": 967.8215757228843
+ },
+ "selected": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "chatOpenAI_1",
+ "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "openApiChain_1",
+ "targetHandle": "openApiChain_1-input-model-ChatOpenAI",
+ "type": "buttonedge",
+ "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openApiChain_1-openApiChain_1-input-model-ChatOpenAI",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openApiChain_1",
+ "sourceHandle": "openApiChain_1-output-openApiChain-OpenAPIChain|BaseChain",
+ "target": "chainTool_0",
+ "targetHandle": "chainTool_0-input-baseChain-BaseChain",
+ "type": "buttonedge",
+ "id": "openApiChain_1-openApiChain_1-output-openApiChain-OpenAPIChain|BaseChain-chainTool_0-chainTool_0-input-baseChain-BaseChain",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chainTool_0",
+ "sourceHandle": "chainTool_0-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool",
+ "target": "openAIFunctionAgent_0",
+ "targetHandle": "openAIFunctionAgent_0-input-tools-Tool",
+ "type": "buttonedge",
+ "id": "chainTool_0-chainTool_0-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool-openAIFunctionAgent_0-openAIFunctionAgent_0-input-tools-Tool",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_2",
+ "sourceHandle": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "openAIFunctionAgent_0",
+ "targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "bufferMemory_0",
+ "sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "target": "openAIFunctionAgent_0",
+ "targetHandle": "openAIFunctionAgent_0-input-memory-BaseChatMemory",
+ "type": "buttonedge",
+ "id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-openAIFunctionAgent_0-openAIFunctionAgent_0-input-memory-BaseChatMemory",
+ "data": {
+ "label": ""
+ }
+ }
+ ]
+}
diff --git a/packages/server/marketplaces/API Agent.json b/packages/server/marketplaces/chatflows/API Agent.json
similarity index 88%
rename from packages/server/marketplaces/API Agent.json
rename to packages/server/marketplaces/chatflows/API Agent.json
index 8ca79926..b9862add 100644
--- a/packages/server/marketplaces/API Agent.json
+++ b/packages/server/marketplaces/chatflows/API Agent.json
@@ -14,6 +14,7 @@
"id": "getApiChain_0",
"label": "GET API Chain",
"name": "getApiChain",
+ "version": 1,
"type": "GETApiChain",
"baseClasses": ["GETApiChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -89,89 +90,6 @@
},
"dragging": false
},
- {
- "width": 300,
- "height": 383,
- "id": "conversationalAgent_0",
- "position": {
- "x": 1993.8540808923876,
- "y": 952.6297081192247
- },
- "type": "customNode",
- "data": {
- "id": "conversationalAgent_0",
- "label": "Conversational Agent",
- "name": "conversationalAgent",
- "type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
- "category": "Agents",
- "description": "Conversational agent for a chat model. It will utilize chat specific prompts",
- "inputParams": [
- {
- "label": "System Message",
- "name": "systemMessage",
- "type": "string",
- "rows": 4,
- "optional": true,
- "additionalParams": true,
- "id": "conversationalAgent_0-input-systemMessage-string"
- },
- {
- "label": "Human Message",
- "name": "humanMessage",
- "type": "string",
- "rows": 4,
- "optional": true,
- "additionalParams": true,
- "id": "conversationalAgent_0-input-humanMessage-string"
- }
- ],
- "inputAnchors": [
- {
- "label": "Allowed Tools",
- "name": "tools",
- "type": "Tool",
- "list": true,
- "id": "conversationalAgent_0-input-tools-Tool"
- },
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "conversationalAgent_0-input-model-BaseLanguageModel"
- },
- {
- "label": "Memory",
- "name": "memory",
- "type": "BaseChatMemory",
- "id": "conversationalAgent_0-input-memory-BaseChatMemory"
- }
- ],
- "inputs": {
- "tools": ["{{chainTool_0.data.instance}}", "{{chainTool_1.data.instance}}"],
- "model": "{{chatOpenAI_0.data.instance}}",
- "memory": "{{bufferMemory_0.data.instance}}",
- "systemMessage": "",
- "humanMessage": ""
- },
- "outputAnchors": [
- {
- "id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|BaseLangChain",
- "name": "conversationalAgent",
- "label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1993.8540808923876,
- "y": 952.6297081192247
- },
- "dragging": false
- },
{
"width": 300,
"height": 602,
@@ -185,6 +103,7 @@
"id": "chainTool_0",
"label": "Chain Tool",
"name": "chainTool",
+ "version": 1,
"type": "ChainTool",
"baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -245,157 +164,6 @@
},
"dragging": false
},
- {
- "width": 300,
- "height": 524,
- "id": "chatOpenAI_0",
- "position": {
- "x": 1270.7548070814019,
- "y": 1565.864417576483
- },
- "type": "customNode",
- "data": {
- "id": "chatOpenAI_0",
- "label": "ChatOpenAI",
- "name": "chatOpenAI",
- "type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
- "category": "Chat Models",
- "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "gpt-4",
- "name": "gpt-4"
- },
- {
- "label": "gpt-4-0613",
- "name": "gpt-4-0613"
- },
- {
- "label": "gpt-4-32k",
- "name": "gpt-4-32k"
- },
- {
- "label": "gpt-4-32k-0613",
- "name": "gpt-4-32k-0613"
- },
- {
- "label": "gpt-3.5-turbo",
- "name": "gpt-3.5-turbo"
- },
- {
- "label": "gpt-3.5-turbo-0613",
- "name": "gpt-3.5-turbo-0613"
- },
- {
- "label": "gpt-3.5-turbo-16k",
- "name": "gpt-3.5-turbo-16k"
- },
- {
- "label": "gpt-3.5-turbo-16k-0613",
- "name": "gpt-3.5-turbo-16k-0613"
- }
- ],
- "default": "gpt-3.5-turbo",
- "optional": true,
- "id": "chatOpenAI_0-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.9,
- "optional": true,
- "id": "chatOpenAI_0-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_0-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_0-input-topP-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_0-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_0-input-presencePenalty-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_0-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_0-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "gpt-3.5-turbo",
- "temperature": 0.9,
- "maxTokens": "",
- "topP": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "name": "chatOpenAI",
- "label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1270.7548070814019,
- "y": 1565.864417576483
- },
- "dragging": false
- },
{
"width": 300,
"height": 376,
@@ -409,6 +177,7 @@
"id": "bufferMemory_0",
"label": "Buffer Memory",
"name": "bufferMemory",
+ "version": 1,
"type": "BufferMemory",
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
"category": "Memory",
@@ -454,143 +223,66 @@
},
{
"width": 300,
- "height": 524,
- "id": "chatOpenAI_1",
+ "height": 602,
+ "id": "chainTool_1",
"position": {
- "x": 865.4424095725009,
- "y": 350.7505181391267
+ "x": 1284.7746596034926,
+ "y": 895.1444797047182
},
"type": "customNode",
"data": {
- "id": "chatOpenAI_1",
- "label": "ChatOpenAI",
- "name": "chatOpenAI",
- "type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
- "category": "Chat Models",
- "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "id": "chainTool_1",
+ "label": "Chain Tool",
+ "name": "chainTool",
+ "version": 1,
+ "type": "ChainTool",
+ "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Use a chain as allowed tool for agent",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "gpt-4",
- "name": "gpt-4"
- },
- {
- "label": "gpt-4-0613",
- "name": "gpt-4-0613"
- },
- {
- "label": "gpt-4-32k",
- "name": "gpt-4-32k"
- },
- {
- "label": "gpt-4-32k-0613",
- "name": "gpt-4-32k-0613"
- },
- {
- "label": "gpt-3.5-turbo",
- "name": "gpt-3.5-turbo"
- },
- {
- "label": "gpt-3.5-turbo-0613",
- "name": "gpt-3.5-turbo-0613"
- },
- {
- "label": "gpt-3.5-turbo-16k",
- "name": "gpt-3.5-turbo-16k"
- },
- {
- "label": "gpt-3.5-turbo-16k-0613",
- "name": "gpt-3.5-turbo-16k-0613"
- }
- ],
- "default": "gpt-3.5-turbo",
- "optional": true,
- "id": "chatOpenAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.9,
- "optional": true,
- "id": "chatOpenAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_1-input-topP-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_1-input-presencePenalty-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
+ "label": "Chain Name",
+ "name": "name",
"type": "string",
+ "placeholder": "state-of-union-qa",
+ "id": "chainTool_1-input-name-string"
+ },
+ {
+ "label": "Chain Description",
+ "name": "description",
+ "type": "string",
+ "rows": 3,
+ "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
+ "id": "chainTool_1-input-description-string"
+ },
+ {
+ "label": "Return Direct",
+ "name": "returnDirect",
+ "type": "boolean",
"optional": true,
- "additionalParams": true,
- "id": "chatOpenAI_1-input-basepath-string"
+ "id": "chainTool_1-input-returnDirect-boolean"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Base Chain",
+ "name": "baseChain",
+ "type": "BaseChain",
+ "id": "chainTool_1-input-baseChain-BaseChain"
}
],
- "inputAnchors": [],
"inputs": {
- "modelName": "gpt-3.5-turbo",
- "temperature": 0.9,
- "maxTokens": "",
- "topP": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "timeout": ""
+ "name": "discord-bot",
+ "description": "useful for when you need to send message to Discord",
+ "returnDirect": "",
+ "baseChain": "{{postApiChain_0.data.instance}}"
},
"outputAnchors": [
{
- "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "name": "chatOpenAI",
- "label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "id": "chainTool_1-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
+ "name": "chainTool",
+ "label": "ChainTool",
+ "type": "ChainTool | DynamicTool | Tool | StructuredTool | BaseLangChain"
}
],
"outputs": {},
@@ -598,34 +290,125 @@
},
"selected": false,
"positionAbsolute": {
- "x": 865.4424095725009,
- "y": 350.7505181391267
+ "x": 1284.7746596034926,
+ "y": 895.1444797047182
},
"dragging": false
},
{
"width": 300,
- "height": 524,
+ "height": 459,
+ "id": "postApiChain_0",
+ "position": {
+ "x": 933.3631140153886,
+ "y": 974.8756002461283
+ },
+ "type": "customNode",
+ "data": {
+ "id": "postApiChain_0",
+ "label": "POST API Chain",
+ "name": "postApiChain",
+ "version": 1,
+ "type": "POSTApiChain",
+ "baseClasses": ["POSTApiChain", "BaseChain", "BaseLangChain"],
+ "category": "Chains",
+ "description": "Chain to run queries against POST API",
+ "inputParams": [
+ {
+ "label": "API Documentation",
+ "name": "apiDocs",
+ "type": "string",
+ "description": "Description of how API works. Please refer to more examples",
+ "rows": 4,
+ "id": "postApiChain_0-input-apiDocs-string"
+ },
+ {
+ "label": "Headers",
+ "name": "headers",
+ "type": "json",
+ "additionalParams": true,
+ "optional": true,
+ "id": "postApiChain_0-input-headers-json"
+ },
+ {
+ "label": "URL Prompt",
+ "name": "urlPrompt",
+ "type": "string",
+ "description": "Prompt used to tell LLMs how to construct the URL. Must contains {api_docs} and {question}",
+ "default": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string:",
+ "rows": 4,
+ "additionalParams": true,
+ "id": "postApiChain_0-input-urlPrompt-string"
+ },
+ {
+ "label": "Answer Prompt",
+ "name": "ansPrompt",
+ "type": "string",
+ "description": "Prompt used to tell LLMs how to return the API response. Must contains {api_response}, {api_url}, and {question}",
+ "default": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string: {api_url_body}\n\nHere is the response from the API:\n\n{api_response}\n\nSummarize this response to answer the original question.\n\nSummary:",
+ "rows": 4,
+ "additionalParams": true,
+ "id": "postApiChain_0-input-ansPrompt-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "postApiChain_0-input-model-BaseLanguageModel"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_2.data.instance}}",
+ "apiDocs": "API documentation:\nEndpoint: https://eog776prcv6dg0j.m.pipedream.net\n\nThis API is for sending Discord message\n\nQuery body table:\nmessage | string | Message to send | required\n\nResponse schema (string):\nresult | string",
+ "headers": "",
+ "urlPrompt": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string:",
+ "ansPrompt": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string: {api_url_body}\n\nHere is the response from the API:\n\n{api_response}\n\nSummarize this response to answer the original question.\n\nSummary:"
+ },
+ "outputAnchors": [
+ {
+ "id": "postApiChain_0-output-postApiChain-POSTApiChain|BaseChain|BaseLangChain",
+ "name": "postApiChain",
+ "label": "POSTApiChain",
+ "type": "POSTApiChain | BaseChain | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 933.3631140153886,
+ "y": 974.8756002461283
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
"id": "chatOpenAI_2",
"position": {
- "x": 587.6425146349426,
- "y": 917.1494176892741
+ "x": 572.8941615312035,
+ "y": 937.8425220917356
},
"type": "customNode",
"data": {
"id": "chatOpenAI_2",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_2-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_2-input-credential-credential"
},
{
"label": "Model Name",
@@ -734,14 +517,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -749,72 +533,153 @@
},
"selected": false,
"positionAbsolute": {
- "x": 587.6425146349426,
- "y": 917.1494176892741
+ "x": 572.8941615312035,
+ "y": 937.8425220917356
},
"dragging": false
},
{
"width": 300,
- "height": 602,
- "id": "chainTool_1",
+ "height": 523,
+ "id": "chatOpenAI_1",
"position": {
- "x": 1284.7746596034926,
- "y": 895.1444797047182
+ "x": 828.7788305309582,
+ "y": 302.8996144964516
},
"type": "customNode",
"data": {
- "id": "chainTool_1",
- "label": "Chain Tool",
- "name": "chainTool",
- "type": "ChainTool",
- "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Use a chain as allowed tool for agent",
+ "id": "chatOpenAI_1",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "Chain Name",
- "name": "name",
- "type": "string",
- "placeholder": "state-of-union-qa",
- "id": "chainTool_1-input-name-string"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_1-input-credential-credential"
},
{
- "label": "Chain Description",
- "name": "description",
- "type": "string",
- "rows": 3,
- "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
- "id": "chainTool_1-input-description-string"
- },
- {
- "label": "Return Direct",
- "name": "returnDirect",
- "type": "boolean",
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
"optional": true,
- "id": "chainTool_1-input-returnDirect-boolean"
- }
- ],
- "inputAnchors": [
+ "id": "chatOpenAI_1-input-modelName-options"
+ },
{
- "label": "Base Chain",
- "name": "baseChain",
- "type": "BaseChain",
- "id": "chainTool_1-input-baseChain-BaseChain"
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_1-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_1-input-basepath-string"
}
],
+ "inputAnchors": [],
"inputs": {
- "name": "discord-bot",
- "description": "useful for when you need to send message to Discord",
- "returnDirect": "",
- "baseChain": "{{postApiChain_0.data.instance}}"
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chainTool_1-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
- "name": "chainTool",
- "label": "ChainTool",
- "type": "ChainTool | DynamicTool | Tool | StructuredTool | BaseLangChain"
+ "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -822,98 +687,239 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1284.7746596034926,
- "y": 895.1444797047182
+ "x": 828.7788305309582,
+ "y": 302.8996144964516
},
"dragging": false
},
{
"width": 300,
- "height": 459,
- "id": "postApiChain_0",
+ "height": 523,
+ "id": "chatOpenAI_3",
"position": {
- "x": 933.3631140153886,
- "y": 974.8756002461283
+ "x": 1148.338912314111,
+ "y": 1561.0888070167944
},
"type": "customNode",
"data": {
- "id": "postApiChain_0",
- "label": "POST API Chain",
- "name": "postApiChain",
- "type": "POSTApiChain",
- "baseClasses": ["POSTApiChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "Chain to run queries against POST API",
+ "id": "chatOpenAI_3",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "API Documentation",
- "name": "apiDocs",
- "type": "string",
- "description": "Description of how API works. Please refer to more examples",
- "rows": 4,
- "id": "postApiChain_0-input-apiDocs-string"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_3-input-credential-credential"
},
{
- "label": "Headers",
- "name": "headers",
- "type": "json",
- "additionalParams": true,
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
"optional": true,
- "id": "postApiChain_0-input-headers-json"
+ "id": "chatOpenAI_3-input-modelName-options"
},
{
- "label": "URL Prompt",
- "name": "urlPrompt",
- "type": "string",
- "description": "Prompt used to tell LLMs how to construct the URL. Must contains {api_docs} and {question}",
- "default": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string:",
- "rows": 4,
- "additionalParams": true,
- "id": "postApiChain_0-input-urlPrompt-string"
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_3-input-temperature-number"
},
{
- "label": "Answer Prompt",
- "name": "ansPrompt",
- "type": "string",
- "description": "Prompt used to tell LLMs how to return the API response. Must contains {api_response}, {api_url}, and {question}",
- "default": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string: {api_url_body}\n\nHere is the response from the API:\n\n{api_response}\n\nSummarize this response to answer the original question.\n\nSummary:",
- "rows": 4,
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
"additionalParams": true,
- "id": "postApiChain_0-input-ansPrompt-string"
+ "id": "chatOpenAI_3-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_3-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_3-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_3-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_3-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_3-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_3-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1148.338912314111,
+ "y": 1561.0888070167944
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 383,
+ "id": "conversationalAgent_0",
+ "position": {
+ "x": 2114.071431691489,
+ "y": 941.7926368551367
+ },
+ "type": "customNode",
+ "data": {
+ "id": "conversationalAgent_0",
+ "label": "Conversational Agent",
+ "name": "conversationalAgent",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain"],
+ "category": "Agents",
+ "description": "Conversational agent for a chat model. It will utilize chat specific prompts",
+ "inputParams": [
+ {
+ "label": "System Message",
+ "name": "systemMessage",
+ "type": "string",
+ "rows": 4,
+ "default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
+ "optional": true,
+ "additionalParams": true,
+ "id": "conversationalAgent_0-input-systemMessage-string"
}
],
"inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "conversationalAgent_0-input-tools-Tool"
+ },
{
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
- "id": "postApiChain_0-input-model-BaseLanguageModel"
+ "id": "conversationalAgent_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseChatMemory",
+ "id": "conversationalAgent_0-input-memory-BaseChatMemory"
}
],
"inputs": {
- "model": "{{chatOpenAI_2.data.instance}}",
- "apiDocs": "API documentation:\nEndpoint: https://eog776prcv6dg0j.m.pipedream.net\n\nThis API is for sending Discord message\n\nQuery body table:\nmessage | string | Message to send | required\n\nResponse schema (string):\nresult | string",
- "headers": "",
- "urlPrompt": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string:",
- "ansPrompt": "You are given the below API Documentation:\n{api_docs}\nUsing this documentation, generate a json string with two keys: \"url\" and \"data\".\nThe value of \"url\" should be a string, which is the API url to call for answering the user question.\nThe value of \"data\" should be a dictionary of key-value pairs you want to POST to the url as a JSON body.\nBe careful to always use double quotes for strings in the json string.\nYou should build the json string in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\n\nQuestion:{question}\njson string: {api_url_body}\n\nHere is the response from the API:\n\n{api_response}\n\nSummarize this response to answer the original question.\n\nSummary:"
+ "tools": ["{{chainTool_0.data.instance}}", "{{chainTool_1.data.instance}}"],
+ "model": "{{chatOpenAI_3.data.instance}}",
+ "memory": "{{bufferMemory_0.data.instance}}",
+ "systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
},
"outputAnchors": [
{
- "id": "postApiChain_0-output-postApiChain-POSTApiChain|BaseChain|BaseLangChain",
- "name": "postApiChain",
- "label": "POSTApiChain",
- "type": "POSTApiChain | BaseChain | BaseLangChain"
+ "id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain",
+ "name": "conversationalAgent",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain"
}
],
"outputs": {},
"selected": false
},
"selected": false,
+ "dragging": false,
"positionAbsolute": {
- "x": 933.3631140153886,
- "y": 974.8756002461283
- },
- "dragging": false
+ "x": 2114.071431691489,
+ "y": 941.7926368551367
+ }
}
],
"edges": [
@@ -928,50 +934,6 @@
"label": ""
}
},
- {
- "source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "conversationalAgent_0",
- "targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "bufferMemory_0",
- "sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
- "target": "conversationalAgent_0",
- "targetHandle": "conversationalAgent_0-input-memory-BaseChatMemory",
- "type": "buttonedge",
- "id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-conversationalAgent_0-conversationalAgent_0-input-memory-BaseChatMemory",
- "data": {
- "label": ""
- }
- },
- {
- "source": "chatOpenAI_1",
- "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "getApiChain_0",
- "targetHandle": "getApiChain_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-getApiChain_0-getApiChain_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "chatOpenAI_2",
- "sourceHandle": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "postApiChain_0",
- "targetHandle": "postApiChain_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-postApiChain_0-postApiChain_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
{
"source": "postApiChain_0",
"sourceHandle": "postApiChain_0-output-postApiChain-POSTApiChain|BaseChain|BaseLangChain",
@@ -983,6 +945,28 @@
"label": ""
}
},
+ {
+ "source": "chatOpenAI_2",
+ "sourceHandle": "chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "postApiChain_0",
+ "targetHandle": "postApiChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_2-chatOpenAI_2-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-postApiChain_0-postApiChain_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_1",
+ "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "getApiChain_0",
+ "targetHandle": "getApiChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-getApiChain_0-getApiChain_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
{
"source": "chainTool_0",
"sourceHandle": "chainTool_0-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
@@ -1004,6 +988,28 @@
"data": {
"label": ""
}
+ },
+ {
+ "source": "chatOpenAI_3",
+ "sourceHandle": "chatOpenAI_3-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "conversationalAgent_0",
+ "targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_3-chatOpenAI_3-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "bufferMemory_0",
+ "sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "target": "conversationalAgent_0",
+ "targetHandle": "conversationalAgent_0-input-memory-BaseChatMemory",
+ "type": "buttonedge",
+ "id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-conversationalAgent_0-conversationalAgent_0-input-memory-BaseChatMemory",
+ "data": {
+ "label": ""
+ }
}
]
}
diff --git a/packages/server/marketplaces/Antonym.json b/packages/server/marketplaces/chatflows/Antonym.json
similarity index 70%
rename from packages/server/marketplaces/Antonym.json
rename to packages/server/marketplaces/chatflows/Antonym.json
index 2e21fd22..95d3c151 100644
--- a/packages/server/marketplaces/Antonym.json
+++ b/packages/server/marketplaces/chatflows/Antonym.json
@@ -3,68 +3,7 @@
"nodes": [
{
"width": 300,
- "height": 534,
- "id": "promptTemplate_1",
- "position": {
- "x": 532.2791692529131,
- "y": -31.128527027841372
- },
- "type": "customNode",
- "data": {
- "id": "promptTemplate_1",
- "label": "Prompt Template",
- "name": "promptTemplate",
- "type": "PromptTemplate",
- "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
- "category": "Prompts",
- "description": "Schema to represent a basic prompt for an LLM",
- "inputParams": [
- {
- "label": "Template",
- "name": "template",
- "type": "string",
- "rows": 4,
- "placeholder": "What is a good name for a company that makes {product}?",
- "id": "promptTemplate_1-input-template-string"
- },
- {
- "label": "Format Prompt Values",
- "name": "promptValues",
- "type": "string",
- "rows": 4,
- "placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
- "optional": true,
- "acceptVariable": true,
- "list": true,
- "id": "promptTemplate_1-input-promptValues-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "template": "Word: {word}\\nAntonym: {antonym}\\n",
- "promptValues": ""
- },
- "outputAnchors": [
- {
- "id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "name": "promptTemplate",
- "label": "PromptTemplate",
- "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 532.2791692529131,
- "y": -31.128527027841372
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 956,
+ "height": 955,
"id": "fewShotPromptTemplate_1",
"position": {
"x": 886.3229032369354,
@@ -75,6 +14,7 @@
"id": "fewShotPromptTemplate_1",
"label": "Few Shot Prompt Template",
"name": "fewShotPromptTemplate",
+ "version": 1,
"type": "FewShotPromptTemplate",
"baseClasses": ["FewShotPromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
@@ -139,7 +79,7 @@
],
"inputs": {
"examples": "[\n { \"word\": \"happy\", \"antonym\": \"sad\" },\n { \"word\": \"tall\", \"antonym\": \"short\" }\n]",
- "examplePrompt": "{{promptTemplate_1.data.instance}}",
+ "examplePrompt": "{{promptTemplate_0.data.instance}}",
"prefix": "Give the antonym of every input",
"suffix": "Word: {input}\\nAntonym:",
"exampleSeparator": "\\n\\n",
@@ -165,145 +105,52 @@
},
{
"width": 300,
- "height": 526,
- "id": "openAI_1",
+ "height": 475,
+ "id": "promptTemplate_0",
"position": {
- "x": 1224.5139327142097,
- "y": -30.864315286062364
+ "x": 540.0140796251119,
+ "y": -33.31673494170347
},
"type": "customNode",
"data": {
- "id": "openAI_1",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
+ "id": "promptTemplate_0",
+ "label": "Prompt Template",
+ "name": "promptTemplate",
+ "version": 1,
+ "type": "PromptTemplate",
+ "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
+ "category": "Prompts",
+ "description": "Schema to represent a basic prompt for an LLM",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
+ "label": "Template",
+ "name": "template",
"type": "string",
+ "rows": 4,
+ "placeholder": "What is a good name for a company that makes {product}?",
+ "id": "promptTemplate_0-input-template-string"
+ },
+ {
+ "label": "Format Prompt Values",
+ "name": "promptValues",
+ "type": "json",
"optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-basepath-string"
+ "acceptVariable": true,
+ "list": true,
+ "id": "promptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
- "modelName": "text-davinci-003",
- "temperature": 0.7,
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
+ "template": "Word: {word}\\nAntonym: {antonym}\\n",
+ "promptValues": ""
},
"outputAnchors": [
{
- "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
+ "id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "name": "promptTemplate",
+ "label": "PromptTemplate",
+ "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
}
],
"outputs": {},
@@ -311,26 +158,181 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1224.5139327142097,
- "y": -30.864315286062364
+ "x": 540.0140796251119,
+ "y": -33.31673494170347
},
"dragging": false
},
{
"width": 300,
- "height": 407,
- "id": "llmChain_1",
+ "height": 523,
+ "id": "chatOpenAI_0",
"position": {
- "x": 1635.363191180743,
- "y": 450.00105475193766
+ "x": 1226.7977900193628,
+ "y": 48.01100655894436
},
"type": "customNode",
"data": {
- "id": "llmChain_1",
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1226.7977900193628,
+ "y": 48.01100655894436
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 405,
+ "id": "llmChain_0",
+ "position": {
+ "x": 1573.7490072386481,
+ "y": 429.1905949837192
+ },
+ "type": "customNode",
+ "data": {
+ "id": "llmChain_0",
"label": "LLM Chain",
"name": "llmChain",
+ "version": 1,
"type": "LLMChain",
- "baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
+ "baseClasses": ["LLMChain", "BaseChain"],
"category": "Chains",
"description": "Chain to run queries against LLMs",
"inputParams": [
@@ -340,7 +342,7 @@
"type": "string",
"placeholder": "Name Your Chain",
"optional": true,
- "id": "llmChain_1-input-chainName-string"
+ "id": "llmChain_0-input-chainName-string"
}
],
"inputAnchors": [
@@ -348,17 +350,17 @@
"label": "Language Model",
"name": "model",
"type": "BaseLanguageModel",
- "id": "llmChain_1-input-model-BaseLanguageModel"
+ "id": "llmChain_0-input-model-BaseLanguageModel"
},
{
"label": "Prompt",
"name": "prompt",
"type": "BasePromptTemplate",
- "id": "llmChain_1-input-prompt-BasePromptTemplate"
+ "id": "llmChain_0-input-prompt-BasePromptTemplate"
}
],
"inputs": {
- "model": "{{openAI_1.data.instance}}",
+ "model": "{{chatOpenAI_0.data.instance}}",
"prompt": "{{fewShotPromptTemplate_1.data.instance}}",
"chainName": ""
},
@@ -369,16 +371,16 @@
"type": "options",
"options": [
{
- "id": "llmChain_1-output-llmChain-LLMChain|BaseChain|BaseLangChain",
+ "id": "llmChain_0-output-llmChain-LLMChain|BaseChain",
"name": "llmChain",
"label": "LLM Chain",
- "type": "LLMChain | BaseChain | BaseLangChain"
+ "type": "LLMChain | BaseChain"
},
{
- "id": "llmChain_1-output-outputPrediction-string",
+ "id": "llmChain_0-output-outputPrediction-string|json",
"name": "outputPrediction",
"label": "Output Prediction",
- "type": "string"
+ "type": "string | json"
}
],
"default": "llmChain"
@@ -389,33 +391,33 @@
},
"selected": false
},
- "positionAbsolute": {
- "x": 1635.363191180743,
- "y": 450.00105475193766
- },
"selected": false,
+ "positionAbsolute": {
+ "x": 1573.7490072386481,
+ "y": 429.1905949837192
+ },
"dragging": false
}
],
"edges": [
{
- "source": "promptTemplate_1",
- "sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "source": "promptTemplate_0",
+ "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "fewShotPromptTemplate_1",
"targetHandle": "fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
"type": "buttonedge",
- "id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-fewShotPromptTemplate_1-fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
+ "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-fewShotPromptTemplate_1-fewShotPromptTemplate_1-input-examplePrompt-PromptTemplate",
"data": {
"label": ""
}
},
{
- "source": "openAI_1",
- "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "target": "llmChain_1",
- "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "llmChain_0",
+ "targetHandle": "llmChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-llmChain_0-llmChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
@@ -423,10 +425,10 @@
{
"source": "fewShotPromptTemplate_1",
"sourceHandle": "fewShotPromptTemplate_1-output-fewShotPromptTemplate-FewShotPromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "target": "llmChain_1",
- "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
+ "target": "llmChain_0",
+ "targetHandle": "llmChain_0-input-prompt-BasePromptTemplate",
"type": "buttonedge",
- "id": "fewShotPromptTemplate_1-fewShotPromptTemplate_1-output-fewShotPromptTemplate-FewShotPromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
+ "id": "fewShotPromptTemplate_1-fewShotPromptTemplate_1-output-fewShotPromptTemplate-FewShotPromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_0-llmChain_0-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/AutoGPT.json b/packages/server/marketplaces/chatflows/AutoGPT.json
similarity index 81%
rename from packages/server/marketplaces/AutoGPT.json
rename to packages/server/marketplaces/chatflows/AutoGPT.json
index 47926272..53837151 100644
--- a/packages/server/marketplaces/AutoGPT.json
+++ b/packages/server/marketplaces/chatflows/AutoGPT.json
@@ -3,7 +3,7 @@
"nodes": [
{
"width": 300,
- "height": 629,
+ "height": 627,
"id": "autoGPT_0",
"position": {
"x": 1627.8124366169843,
@@ -14,6 +14,7 @@
"id": "autoGPT_0",
"label": "AutoGPT",
"name": "autoGPT",
+ "version": 1,
"type": "AutoGPT",
"baseClasses": ["AutoGPT"],
"category": "Agents",
@@ -67,8 +68,8 @@
],
"inputs": {
"tools": ["{{readFile_0.data.instance}}", "{{writeFile_1.data.instance}}", "{{serpAPI_0.data.instance}}"],
- "model": "{{chatOpenAI_1.data.instance}}",
- "vectorStoreRetriever": "{{pineconeExistingIndex_1.data.instance}}",
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "vectorStoreRetriever": "{{pineconeExistingIndex_0.data.instance}}",
"aiName": "",
"aiRole": "",
"maxLoop": 5
@@ -93,27 +94,176 @@
},
{
"width": 300,
- "height": 526,
- "id": "chatOpenAI_1",
+ "height": 278,
+ "id": "writeFile_1",
"position": {
- "x": 168.57515834535457,
- "y": -90.74139976987627
+ "x": 539.4976647298655,
+ "y": 36.45930212160803
},
"type": "customNode",
"data": {
- "id": "chatOpenAI_1",
+ "id": "writeFile_1",
+ "label": "Write File",
+ "name": "writeFile",
+ "version": 1,
+ "type": "WriteFile",
+ "baseClasses": ["WriteFile", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Write file to disk",
+ "inputParams": [
+ {
+ "label": "Base Path",
+ "name": "basePath",
+ "placeholder": "C:\\Users\\User\\Desktop",
+ "type": "string",
+ "optional": true,
+ "id": "writeFile_1-input-basePath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "basePath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "writeFile_1-output-writeFile-WriteFile|Tool|StructuredTool|BaseLangChain",
+ "name": "writeFile",
+ "label": "WriteFile",
+ "type": "WriteFile | Tool | StructuredTool | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 539.4976647298655,
+ "y": 36.45930212160803
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 278,
+ "id": "readFile_0",
+ "position": {
+ "x": 881.2568465391292,
+ "y": -112.9631005153393
+ },
+ "type": "customNode",
+ "data": {
+ "id": "readFile_0",
+ "label": "Read File",
+ "name": "readFile",
+ "version": 1,
+ "type": "ReadFile",
+ "baseClasses": ["ReadFile", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Read file from disk",
+ "inputParams": [
+ {
+ "label": "Base Path",
+ "name": "basePath",
+ "placeholder": "C:\\Users\\User\\Desktop",
+ "type": "string",
+ "optional": true,
+ "id": "readFile_0-input-basePath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "basePath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "readFile_0-output-readFile-ReadFile|Tool|StructuredTool|BaseLangChain",
+ "name": "readFile",
+ "label": "ReadFile",
+ "type": "ReadFile | Tool | StructuredTool | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 881.2568465391292,
+ "y": -112.9631005153393
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 277,
+ "id": "serpAPI_0",
+ "position": {
+ "x": 1247.066832724479,
+ "y": -193.77467220135756
+ },
+ "type": "customNode",
+ "data": {
+ "id": "serpAPI_0",
+ "label": "Serp API",
+ "name": "serpAPI",
+ "version": 1,
+ "type": "SerpAPI",
+ "baseClasses": ["SerpAPI", "Tool", "StructuredTool"],
+ "category": "Tools",
+ "description": "Wrapper around SerpAPI - a real-time API to access Google search results",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["serpApi"],
+ "id": "serpAPI_0-input-credential-credential"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {},
+ "outputAnchors": [
+ {
+ "id": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool",
+ "name": "serpAPI",
+ "label": "SerpAPI",
+ "type": "SerpAPI | Tool | StructuredTool"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1247.066832724479,
+ "y": -193.77467220135756
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 176.69787776192283,
+ "y": -116.3808686218022
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_1-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -155,7 +305,7 @@
],
"default": "gpt-3.5-turbo",
"optional": true,
- "id": "chatOpenAI_1-input-modelName-options"
+ "id": "chatOpenAI_0-input-modelName-options"
},
{
"label": "Temperature",
@@ -163,7 +313,7 @@
"type": "number",
"default": 0.9,
"optional": true,
- "id": "chatOpenAI_1-input-temperature-number"
+ "id": "chatOpenAI_0-input-temperature-number"
},
{
"label": "Max Tokens",
@@ -171,7 +321,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-maxTokens-number"
+ "id": "chatOpenAI_0-input-maxTokens-number"
},
{
"label": "Top Probability",
@@ -179,7 +329,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-topP-number"
+ "id": "chatOpenAI_0-input-topP-number"
},
{
"label": "Frequency Penalty",
@@ -187,7 +337,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-frequencyPenalty-number"
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
},
{
"label": "Presence Penalty",
@@ -195,7 +345,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-presencePenalty-number"
+ "id": "chatOpenAI_0-input-presencePenalty-number"
},
{
"label": "Timeout",
@@ -203,7 +353,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-timeout-number"
+ "id": "chatOpenAI_0-input-timeout-number"
},
{
"label": "BasePath",
@@ -211,25 +361,26 @@
"type": "string",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-basepath-string"
+ "id": "chatOpenAI_0-input-basepath-string"
}
],
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
- "temperature": "0",
+ "temperature": 0.9,
"maxTokens": "",
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -237,177 +388,36 @@
},
"selected": false,
"positionAbsolute": {
- "x": 168.57515834535457,
- "y": -90.74139976987627
+ "x": 176.69787776192283,
+ "y": -116.3808686218022
},
"dragging": false
},
{
"width": 300,
- "height": 279,
- "id": "writeFile_1",
- "position": {
- "x": 546.3440710182241,
- "y": 55.28691941459434
- },
- "type": "customNode",
- "data": {
- "id": "writeFile_1",
- "label": "Write File",
- "name": "writeFile",
- "type": "WriteFile",
- "baseClasses": ["WriteFile", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Write file to disk",
- "inputParams": [
- {
- "label": "Base Path",
- "name": "basePath",
- "placeholder": "C:\\Users\\User\\Desktop",
- "type": "string",
- "optional": true,
- "id": "writeFile_1-input-basePath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "basePath": ""
- },
- "outputAnchors": [
- {
- "id": "writeFile_1-output-writeFile-WriteFile|Tool|StructuredTool|BaseLangChain",
- "name": "writeFile",
- "label": "WriteFile",
- "type": "WriteFile | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 546.3440710182241,
- "y": 55.28691941459434
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 279,
- "id": "readFile_0",
- "position": {
- "x": 881.2568465391292,
- "y": -112.9631005153393
- },
- "type": "customNode",
- "data": {
- "id": "readFile_0",
- "label": "Read File",
- "name": "readFile",
- "type": "ReadFile",
- "baseClasses": ["ReadFile", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Read file from disk",
- "inputParams": [
- {
- "label": "Base Path",
- "name": "basePath",
- "placeholder": "C:\\Users\\User\\Desktop",
- "type": "string",
- "optional": true,
- "id": "readFile_0-input-basePath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "basePath": ""
- },
- "outputAnchors": [
- {
- "id": "readFile_0-output-readFile-ReadFile|Tool|StructuredTool|BaseLangChain",
- "name": "readFile",
- "label": "ReadFile",
- "type": "ReadFile | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 881.2568465391292,
- "y": -112.9631005153393
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 279,
- "id": "serpAPI_0",
- "position": {
- "x": 1244.740380161344,
- "y": -193.9135818023827
- },
- "type": "customNode",
- "data": {
- "id": "serpAPI_0",
- "label": "Serp API",
- "name": "serpAPI",
- "type": "SerpAPI",
- "baseClasses": ["SerpAPI", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Wrapper around SerpAPI - a real-time API to access Google search results",
- "inputParams": [
- {
- "label": "Serp Api Key",
- "name": "apiKey",
- "type": "password",
- "id": "serpAPI_0-input-apiKey-password"
- }
- ],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
- "name": "serpAPI",
- "label": "SerpAPI",
- "type": "SerpAPI | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1244.740380161344,
- "y": -193.9135818023827
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 331,
+ "height": 329,
"id": "openAIEmbeddings_0",
"position": {
- "x": 530.4714276286077,
- "y": 487.0228196121594
+ "x": 606.7317612889267,
+ "y": 439.5269912996025
},
"type": "customNode",
"data": {
"id": "openAIEmbeddings_0",
"label": "OpenAI Embeddings",
"name": "openAIEmbeddings",
+ "version": 1,
"type": "OpenAIEmbeddings",
"baseClasses": ["OpenAIEmbeddings", "Embeddings"],
"category": "Embeddings",
"description": "OpenAI API to generate embeddings for a given text",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
},
{
"label": "Strip New Lines",
@@ -446,7 +456,8 @@
"inputs": {
"stripNewLines": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
@@ -459,57 +470,53 @@
"outputs": {},
"selected": false
},
- "positionAbsolute": {
- "x": 530.4714276286077,
- "y": 487.0228196121594
- },
"selected": false,
+ "positionAbsolute": {
+ "x": 606.7317612889267,
+ "y": 439.5269912996025
+ },
"dragging": false
},
{
"width": 300,
- "height": 652,
- "id": "pineconeExistingIndex_1",
+ "height": 505,
+ "id": "pineconeExistingIndex_0",
"position": {
- "x": 943.1601557586332,
- "y": 404.9622062733608
+ "x": 1001.3784758268554,
+ "y": 415.24072209485803
},
"type": "customNode",
"data": {
- "id": "pineconeExistingIndex_1",
+ "id": "pineconeExistingIndex_0",
"label": "Pinecone Load Existing Index",
"name": "pineconeExistingIndex",
+ "version": 1,
"type": "Pinecone",
"baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
"category": "Vector Stores",
"description": "Load existing index from Pinecone (i.e: Document has been upserted)",
"inputParams": [
{
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeExistingIndex_1-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeExistingIndex_1-input-pineconeEnv-string"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeExistingIndex_0-input-credential-credential"
},
{
"label": "Pinecone Index",
"name": "pineconeIndex",
"type": "string",
- "id": "pineconeExistingIndex_1-input-pineconeIndex-string"
+ "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
},
{
"label": "Pinecone Namespace",
"name": "pineconeNamespace",
"type": "string",
"placeholder": "my-first-namespace",
- "optional": true,
"additionalParams": true,
- "id": "pineconeExistingIndex_1-input-pineconeNamespace-string"
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
},
{
"label": "Pinecone Metadata Filter",
@@ -517,7 +524,7 @@
"type": "json",
"optional": true,
"additionalParams": true,
- "id": "pineconeExistingIndex_1-input-pineconeMetadataFilter-json"
+ "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
},
{
"label": "Top K",
@@ -527,7 +534,7 @@
"type": "number",
"additionalParams": true,
"optional": true,
- "id": "pineconeExistingIndex_1-input-topK-number"
+ "id": "pineconeExistingIndex_0-input-topK-number"
}
],
"inputAnchors": [
@@ -535,14 +542,15 @@
"label": "Embeddings",
"name": "embeddings",
"type": "Embeddings",
- "id": "pineconeExistingIndex_1-input-embeddings-Embeddings"
+ "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
}
],
"inputs": {
"embeddings": "{{openAIEmbeddings_0.data.instance}}",
- "pineconeEnv": "us-west4-gcp",
"pineconeIndex": "",
- "pineconeNamespace": ""
+ "pineconeNamespace": "",
+ "pineconeMetadataFilter": "",
+ "topK": ""
},
"outputAnchors": [
{
@@ -551,13 +559,13 @@
"type": "options",
"options": [
{
- "id": "pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
"name": "retriever",
"label": "Pinecone Retriever",
"type": "Pinecone | VectorStoreRetriever | BaseRetriever"
},
{
- "id": "pineconeExistingIndex_1-output-vectorStore-Pinecone|VectorStore",
+ "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
"name": "vectorStore",
"label": "Pinecone Vector Store",
"type": "Pinecone | VectorStore"
@@ -572,47 +580,14 @@
"selected": false
},
"selected": false,
+ "dragging": false,
"positionAbsolute": {
- "x": 943.1601557586332,
- "y": 404.9622062733608
- },
- "dragging": false
+ "x": 1001.3784758268554,
+ "y": 415.24072209485803
+ }
}
],
"edges": [
- {
- "source": "pineconeExistingIndex_1",
- "sourceHandle": "pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "target": "autoGPT_0",
- "targetHandle": "autoGPT_0-input-vectorStoreRetriever-BaseRetriever",
- "type": "buttonedge",
- "id": "pineconeExistingIndex_1-pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-autoGPT_0-autoGPT_0-input-vectorStoreRetriever-BaseRetriever",
- "data": {
- "label": ""
- }
- },
- {
- "source": "openAIEmbeddings_0",
- "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "pineconeExistingIndex_1",
- "targetHandle": "pineconeExistingIndex_1-input-embeddings-Embeddings",
- "type": "buttonedge",
- "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_1-pineconeExistingIndex_1-input-embeddings-Embeddings",
- "data": {
- "label": ""
- }
- },
- {
- "source": "chatOpenAI_1",
- "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "autoGPT_0",
- "targetHandle": "autoGPT_0-input-model-BaseChatModel",
- "type": "buttonedge",
- "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-autoGPT_0-autoGPT_0-input-model-BaseChatModel",
- "data": {
- "label": ""
- }
- },
{
"source": "writeFile_1",
"sourceHandle": "writeFile_1-output-writeFile-WriteFile|Tool|StructuredTool|BaseLangChain",
@@ -635,13 +610,46 @@
"label": ""
}
},
+ {
+ "source": "pineconeExistingIndex_0",
+ "sourceHandle": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "target": "autoGPT_0",
+ "targetHandle": "autoGPT_0-input-vectorStoreRetriever-BaseRetriever",
+ "type": "buttonedge",
+ "id": "pineconeExistingIndex_0-pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-autoGPT_0-autoGPT_0-input-vectorStoreRetriever-BaseRetriever",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeExistingIndex_0",
+ "targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "autoGPT_0",
+ "targetHandle": "autoGPT_0-input-model-BaseChatModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-autoGPT_0-autoGPT_0-input-model-BaseChatModel",
+ "data": {
+ "label": ""
+ }
+ },
{
"source": "serpAPI_0",
- "sourceHandle": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
+ "sourceHandle": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool",
"target": "autoGPT_0",
"targetHandle": "autoGPT_0-input-tools-Tool",
"type": "buttonedge",
- "id": "serpAPI_0-serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain-autoGPT_0-autoGPT_0-input-tools-Tool",
+ "id": "serpAPI_0-serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool-autoGPT_0-autoGPT_0-input-tools-Tool",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/BabyAGI.json b/packages/server/marketplaces/chatflows/BabyAGI.json
similarity index 74%
rename from packages/server/marketplaces/BabyAGI.json
rename to packages/server/marketplaces/chatflows/BabyAGI.json
index 572d73f1..c2897531 100644
--- a/packages/server/marketplaces/BabyAGI.json
+++ b/packages/server/marketplaces/chatflows/BabyAGI.json
@@ -3,220 +3,93 @@
"nodes": [
{
"width": 300,
- "height": 331,
- "id": "openAIEmbeddings_1",
+ "height": 379,
+ "id": "babyAGI_1",
"position": {
- "x": -84.60344342694289,
- "y": -189.6930708050951
+ "x": 950.8042093214954,
+ "y": 66.00028106865324
},
"type": "customNode",
"data": {
- "id": "openAIEmbeddings_1",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
+ "id": "babyAGI_1",
+ "label": "BabyAGI",
+ "name": "babyAGI",
+ "version": 1,
+ "type": "BabyAGI",
+ "baseClasses": ["BabyAGI"],
+ "category": "Agents",
+ "description": "Task Driven Autonomous Agent which creates new task and reprioritizes task list based on objective",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_1-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
+ "label": "Task Loop",
+ "name": "taskLoop",
"type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-basepath-string"
+ "default": 3,
+ "id": "babyAGI_1-input-taskLoop-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Chat Model",
+ "name": "model",
+ "type": "BaseChatModel",
+ "id": "babyAGI_1-input-model-BaseChatModel"
+ },
+ {
+ "label": "Vector Store",
+ "name": "vectorStore",
+ "type": "VectorStore",
+ "id": "babyAGI_1-input-vectorStore-VectorStore"
}
],
- "inputAnchors": [],
"inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "vectorStore": "{{pineconeExistingIndex_0.data.instance}}",
+ "taskLoop": 3
},
"outputAnchors": [
{
- "id": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
+ "id": "babyAGI_1-output-babyAGI-BabyAGI",
+ "name": "babyAGI",
+ "label": "BabyAGI",
+ "type": "BabyAGI"
}
],
"outputs": {},
"selected": false
},
- "positionAbsolute": {
- "x": -84.60344342694289,
- "y": -189.6930708050951
- },
"selected": false,
- "dragging": false
+ "dragging": false,
+ "positionAbsolute": {
+ "x": 950.8042093214954,
+ "y": 66.00028106865324
+ }
},
{
"width": 300,
- "height": 652,
- "id": "pineconeExistingIndex_1",
+ "height": 523,
+ "id": "chatOpenAI_0",
"position": {
- "x": 264.729293346415,
- "y": -190.36689763560724
+ "x": 587.1798180512677,
+ "y": -355.9845878719703
},
"type": "customNode",
"data": {
- "id": "pineconeExistingIndex_1",
- "label": "Pinecone Load Existing Index",
- "name": "pineconeExistingIndex",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeExistingIndex_1-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeExistingIndex_1-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeExistingIndex_1-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_1-input-pineconeNamespace-string"
- },
- {
- "label": "Pinecone Metadata Filter",
- "name": "pineconeMetadataFilter",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_1-input-pineconeMetadataFilter-json"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "pineconeExistingIndex_1-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "pineconeExistingIndex_1-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_1.data.instance}}",
- "pineconeEnv": "us-west4-gcp",
- "pineconeIndex": "",
- "pineconeNamespace": ""
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "pineconeExistingIndex_1-output-vectorStore-Pinecone|VectorStore",
- "name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "vectorStore"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 264.729293346415,
- "y": -190.36689763560724
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 526,
- "id": "chatOpenAI_1",
- "position": {
- "x": 590.3367401418911,
- "y": -374.0329977259934
- },
- "type": "customNode",
- "data": {
- "id": "chatOpenAI_1",
+ "id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_1-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -258,7 +131,7 @@
],
"default": "gpt-3.5-turbo",
"optional": true,
- "id": "chatOpenAI_1-input-modelName-options"
+ "id": "chatOpenAI_0-input-modelName-options"
},
{
"label": "Temperature",
@@ -266,7 +139,7 @@
"type": "number",
"default": 0.9,
"optional": true,
- "id": "chatOpenAI_1-input-temperature-number"
+ "id": "chatOpenAI_0-input-temperature-number"
},
{
"label": "Max Tokens",
@@ -274,7 +147,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-maxTokens-number"
+ "id": "chatOpenAI_0-input-maxTokens-number"
},
{
"label": "Top Probability",
@@ -282,7 +155,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-topP-number"
+ "id": "chatOpenAI_0-input-topP-number"
},
{
"label": "Frequency Penalty",
@@ -290,7 +163,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-frequencyPenalty-number"
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
},
{
"label": "Presence Penalty",
@@ -298,7 +171,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-presencePenalty-number"
+ "id": "chatOpenAI_0-input-presencePenalty-number"
},
{
"label": "Timeout",
@@ -306,7 +179,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-timeout-number"
+ "id": "chatOpenAI_0-input-timeout-number"
},
{
"label": "BasePath",
@@ -314,131 +187,262 @@
"type": "string",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-basepath-string"
+ "id": "chatOpenAI_0-input-basepath-string"
}
],
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
- "temperature": "0",
+ "temperature": 0.9,
"maxTokens": "",
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
"selected": false
},
"selected": false,
- "dragging": false,
"positionAbsolute": {
- "x": 590.3367401418911,
- "y": -374.0329977259934
- }
+ "x": 587.1798180512677,
+ "y": -355.9845878719703
+ },
+ "dragging": false
},
{
"width": 300,
- "height": 380,
- "id": "babyAGI_1",
+ "height": 329,
+ "id": "openAIEmbeddings_0",
"position": {
- "x": 950.8042093214954,
- "y": 66.00028106865324
+ "x": -111.82510263637522,
+ "y": -224.88655030419665
},
"type": "customNode",
"data": {
- "id": "babyAGI_1",
- "label": "BabyAGI",
- "name": "babyAGI",
- "type": "BabyAGI",
- "baseClasses": ["BabyAGI"],
- "category": "Agents",
- "description": "Task Driven Autonomous Agent which creates new task and reprioritizes task list based on objective",
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
"inputParams": [
{
- "label": "Task Loop",
- "name": "taskLoop",
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
"type": "number",
- "default": 3,
- "id": "babyAGI_1-input-taskLoop-number"
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": -111.82510263637522,
+ "y": -224.88655030419665
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 505,
+ "id": "pineconeExistingIndex_0",
+ "position": {
+ "x": 241.78764591331816,
+ "y": -38.438460915613945
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeExistingIndex_0",
+ "label": "Pinecone Load Existing Index",
+ "name": "pineconeExistingIndex",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeExistingIndex_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Pinecone Metadata Filter",
+ "name": "pineconeMetadataFilter",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-topK-number"
}
],
"inputAnchors": [
{
- "label": "Chat Model",
- "name": "model",
- "type": "BaseChatModel",
- "id": "babyAGI_1-input-model-BaseChatModel"
- },
- {
- "label": "Vector Store",
- "name": "vectorStore",
- "type": "VectorStore",
- "id": "babyAGI_1-input-vectorStore-VectorStore"
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
}
],
"inputs": {
- "model": "{{chatOpenAI_1.data.instance}}",
- "vectorStore": "{{pineconeExistingIndex_1.data.instance}}",
- "taskLoop": 3
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "newindex",
+ "pineconeNamespace": "",
+ "pineconeMetadataFilter": "",
+ "topK": ""
},
"outputAnchors": [
{
- "id": "babyAGI_1-output-babyAGI-BabyAGI",
- "name": "babyAGI",
- "label": "BabyAGI",
- "type": "BabyAGI"
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
}
],
- "outputs": {},
+ "outputs": {
+ "output": "vectorStore"
+ },
"selected": false
},
"selected": false,
- "dragging": false,
"positionAbsolute": {
- "x": 950.8042093214954,
- "y": 66.00028106865324
- }
+ "x": 241.78764591331816,
+ "y": -38.438460915613945
+ },
+ "dragging": false
}
],
"edges": [
{
- "source": "openAIEmbeddings_1",
- "sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "pineconeExistingIndex_1",
- "targetHandle": "pineconeExistingIndex_1-input-embeddings-Embeddings",
- "type": "buttonedge",
- "id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_1-pineconeExistingIndex_1-input-embeddings-Embeddings",
- "data": {
- "label": ""
- }
- },
- {
- "source": "chatOpenAI_1",
- "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "babyAGI_1",
- "targetHandle": "babyAGI_1-input-model-BaseChatModel",
- "type": "buttonedge",
- "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-babyAGI_1-babyAGI_1-input-model-BaseChatModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "pineconeExistingIndex_1",
- "sourceHandle": "pineconeExistingIndex_1-output-vectorStore-Pinecone|VectorStore",
+ "source": "pineconeExistingIndex_0",
+ "sourceHandle": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
"target": "babyAGI_1",
"targetHandle": "babyAGI_1-input-vectorStore-VectorStore",
"type": "buttonedge",
- "id": "pineconeExistingIndex_1-pineconeExistingIndex_1-output-vectorStore-Pinecone|VectorStore-babyAGI_1-babyAGI_1-input-vectorStore-VectorStore",
+ "id": "pineconeExistingIndex_0-pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore-babyAGI_1-babyAGI_1-input-vectorStore-VectorStore",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "babyAGI_1",
+ "targetHandle": "babyAGI_1-input-model-BaseChatModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-babyAGI_1-babyAGI_1-input-model-BaseChatModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeExistingIndex_0",
+ "targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/chatflows/CSV Agent.json b/packages/server/marketplaces/chatflows/CSV Agent.json
new file mode 100644
index 00000000..1515fcad
--- /dev/null
+++ b/packages/server/marketplaces/chatflows/CSV Agent.json
@@ -0,0 +1,228 @@
+{
+ "description": "Analyse and summarize CSV data",
+ "nodes": [
+ {
+ "width": 300,
+ "height": 377,
+ "id": "csvAgent_0",
+ "position": {
+ "x": 1064.0780498701288,
+ "y": 284.44352695304724
+ },
+ "type": "customNode",
+ "data": {
+ "id": "csvAgent_0",
+ "label": "CSV Agent",
+ "name": "csvAgent",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain"],
+ "category": "Agents",
+ "description": "Agent used to to answer queries on CSV data",
+ "inputParams": [
+ {
+ "label": "Csv File",
+ "name": "csvFile",
+ "type": "file",
+ "fileType": ".csv",
+ "id": "csvAgent_0-input-csvFile-file"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "csvAgent_0-input-model-BaseLanguageModel"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "csvAgent_0-output-csvAgent-AgentExecutor|BaseChain",
+ "name": "csvAgent",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1064.0780498701288,
+ "y": 284.44352695304724
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 522,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 657.3762197414501,
+ "y": 220.2950766042332
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 657.3762197414501,
+ "y": 220.2950766042332
+ },
+ "dragging": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "csvAgent_0",
+ "targetHandle": "csvAgent_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-csvAgent_0-csvAgent_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ }
+ ]
+}
diff --git a/packages/server/marketplaces/ChatGPTPlugin.json b/packages/server/marketplaces/chatflows/ChatGPTPlugin.json
similarity index 93%
rename from packages/server/marketplaces/ChatGPTPlugin.json
rename to packages/server/marketplaces/chatflows/ChatGPTPlugin.json
index 76964a09..471853ba 100644
--- a/packages/server/marketplaces/ChatGPTPlugin.json
+++ b/packages/server/marketplaces/chatflows/ChatGPTPlugin.json
@@ -14,6 +14,7 @@
"id": "aiPlugin_0",
"label": "AI Plugin",
"name": "aiPlugin",
+ "version": 1,
"type": "AIPlugin",
"baseClasses": ["AIPlugin", "Tool"],
"category": "Tools",
@@ -60,6 +61,7 @@
"id": "requestsGet_0",
"label": "Requests Get",
"name": "requestsGet",
+ "version": 1,
"type": "RequestsGet",
"baseClasses": ["RequestsGet", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -131,6 +133,7 @@
"id": "requestsPost_0",
"label": "Requests Post",
"name": "requestsPost",
+ "version": 1,
"type": "RequestsPost",
"baseClasses": ["RequestsPost", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -201,82 +204,29 @@
},
{
"width": 300,
- "height": 280,
- "id": "mrklAgentChat_0",
- "position": {
- "x": 1416.2054860029416,
- "y": 451.43299014109715
- },
- "type": "customNode",
- "data": {
- "id": "mrklAgentChat_0",
- "label": "MRKL Agent for Chat Models",
- "name": "mrklAgentChat",
- "type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
- "category": "Agents",
- "description": "Agent that uses the ReAct Framework to decide what action to take, optimized to be used with Chat Models",
- "inputParams": [],
- "inputAnchors": [
- {
- "label": "Allowed Tools",
- "name": "tools",
- "type": "Tool",
- "list": true,
- "id": "mrklAgentChat_0-input-tools-Tool"
- },
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "mrklAgentChat_0-input-model-BaseLanguageModel"
- }
- ],
- "inputs": {
- "tools": ["{{requestsGet_0.data.instance}}", "{{requestsPost_0.data.instance}}", "{{aiPlugin_0.data.instance}}"],
- "model": "{{chatOpenAI_0.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "mrklAgentChat_0-output-mrklAgentChat-AgentExecutor|BaseChain|BaseLangChain",
- "name": "mrklAgentChat",
- "label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1416.2054860029416,
- "y": 451.43299014109715
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 524,
+ "height": 523,
"id": "chatOpenAI_0",
"position": {
- "x": 797.0574814814245,
- "y": 578.7641992971934
+ "x": 802.0103755177098,
+ "y": 576.0760341170851
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -385,14 +335,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -400,24 +351,69 @@
},
"selected": false,
"positionAbsolute": {
- "x": 797.0574814814245,
- "y": 578.7641992971934
+ "x": 802.0103755177098,
+ "y": 576.0760341170851
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 280,
+ "id": "mrklAgentChat_0",
+ "position": {
+ "x": 1425.5853300862047,
+ "y": 441.06218012993924
+ },
+ "type": "customNode",
+ "data": {
+ "id": "mrklAgentChat_0",
+ "label": "MRKL Agent for Chat Models",
+ "name": "mrklAgentChat",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain"],
+ "category": "Agents",
+ "description": "Agent that uses the ReAct Framework to decide what action to take, optimized to be used with Chat Models",
+ "inputParams": [],
+ "inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "mrklAgentChat_0-input-tools-Tool"
+ },
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "mrklAgentChat_0-input-model-BaseLanguageModel"
+ }
+ ],
+ "inputs": {
+ "tools": ["{{requestsGet_0.data.instance}}", "{{requestsPost_0.data.instance}}", "{{aiPlugin_0.data.instance}}"],
+ "model": "{{chatOpenAI_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "mrklAgentChat_0-output-mrklAgentChat-AgentExecutor|BaseChain",
+ "name": "mrklAgentChat",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1425.5853300862047,
+ "y": 441.06218012993924
},
"dragging": false
}
],
"edges": [
- {
- "source": "requestsGet_0",
- "sourceHandle": "requestsGet_0-output-requestsGet-RequestsGet|Tool|StructuredTool|BaseLangChain",
- "target": "mrklAgentChat_0",
- "targetHandle": "mrklAgentChat_0-input-tools-Tool",
- "type": "buttonedge",
- "id": "requestsGet_0-requestsGet_0-output-requestsGet-RequestsGet|Tool|StructuredTool|BaseLangChain-mrklAgentChat_0-mrklAgentChat_0-input-tools-Tool",
- "data": {
- "label": ""
- }
- },
{
"source": "aiPlugin_0",
"sourceHandle": "aiPlugin_0-output-aiPlugin-AIPlugin|Tool",
@@ -429,6 +425,17 @@
"label": ""
}
},
+ {
+ "source": "requestsGet_0",
+ "sourceHandle": "requestsGet_0-output-requestsGet-RequestsGet|Tool|StructuredTool|BaseLangChain",
+ "target": "mrklAgentChat_0",
+ "targetHandle": "mrklAgentChat_0-input-tools-Tool",
+ "type": "buttonedge",
+ "id": "requestsGet_0-requestsGet_0-output-requestsGet-RequestsGet|Tool|StructuredTool|BaseLangChain-mrklAgentChat_0-mrklAgentChat_0-input-tools-Tool",
+ "data": {
+ "label": ""
+ }
+ },
{
"source": "requestsPost_0",
"sourceHandle": "requestsPost_0-output-requestsPost-RequestsPost|Tool|StructuredTool|BaseLangChain",
@@ -442,11 +449,11 @@
},
{
"source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "mrklAgentChat_0",
"targetHandle": "mrklAgentChat_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-mrklAgentChat_0-mrklAgentChat_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-mrklAgentChat_0-mrklAgentChat_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/chatflows/Claude LLM.json b/packages/server/marketplaces/chatflows/Claude LLM.json
new file mode 100644
index 00000000..243d2600
--- /dev/null
+++ b/packages/server/marketplaces/chatflows/Claude LLM.json
@@ -0,0 +1,416 @@
+{
+ "description": "Use Anthropic Claude with 100k context window to ingest whole document for QnA",
+ "nodes": [
+ {
+ "width": 300,
+ "height": 376,
+ "id": "bufferMemory_0",
+ "position": {
+ "x": 451.4449437285705,
+ "y": 118.30026803362762
+ },
+ "type": "customNode",
+ "data": {
+ "id": "bufferMemory_0",
+ "label": "Buffer Memory",
+ "name": "bufferMemory",
+ "version": 1,
+ "type": "BufferMemory",
+ "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Remembers previous conversational back and forths directly",
+ "inputParams": [
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "id": "bufferMemory_0-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "id": "bufferMemory_0-input-inputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "memoryKey": "chat_history",
+ "inputKey": "input"
+ },
+ "outputAnchors": [
+ {
+ "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "name": "bufferMemory",
+ "label": "BufferMemory",
+ "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 451.4449437285705,
+ "y": 118.30026803362762
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 383,
+ "id": "conversationChain_0",
+ "position": {
+ "x": 1176.1569322079652,
+ "y": 303.56879146735974
+ },
+ "type": "customNode",
+ "data": {
+ "id": "conversationChain_0",
+ "label": "Conversation Chain",
+ "name": "conversationChain",
+ "version": 1,
+ "type": "ConversationChain",
+ "baseClasses": ["ConversationChain", "LLMChain", "BaseChain"],
+ "category": "Chains",
+ "description": "Chat models specific conversational chain with memory",
+ "inputParams": [
+ {
+ "label": "System Message",
+ "name": "systemMessagePrompt",
+ "type": "string",
+ "rows": 4,
+ "additionalParams": true,
+ "optional": true,
+ "placeholder": "You are a helpful assistant that write codes",
+ "id": "conversationChain_0-input-systemMessagePrompt-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseChatModel",
+ "id": "conversationChain_0-input-model-BaseChatModel"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "id": "conversationChain_0-input-memory-BaseMemory"
+ },
+ {
+ "label": "Document",
+ "name": "document",
+ "type": "Document",
+ "description": "Include whole document into the context window",
+ "optional": true,
+ "list": true,
+ "id": "conversationChain_0-input-document-Document"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatAnthropic_0.data.instance}}",
+ "memory": "{{bufferMemory_0.data.instance}}",
+ "document": ["{{pdfFile_0.data.instance}}"],
+ "systemMessagePrompt": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "conversationChain_0-output-conversationChain-ConversationChain|LLMChain|BaseChain",
+ "name": "conversationChain",
+ "label": "ConversationChain",
+ "type": "ConversationChain | LLMChain | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1176.1569322079652,
+ "y": 303.56879146735974
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatAnthropic_0",
+ "position": {
+ "x": 800.5525382783799,
+ "y": -76.7988221837009
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatAnthropic_0",
+ "label": "ChatAnthropic",
+ "name": "chatAnthropic",
+ "version": 1,
+ "type": "ChatAnthropic",
+ "baseClasses": ["ChatAnthropic", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around ChatAnthropic large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["anthropicApi"],
+ "id": "chatAnthropic_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "claude-2",
+ "name": "claude-2",
+ "description": "Claude 2 latest major version, automatically get updates to the model as they are released"
+ },
+ {
+ "label": "claude-instant-1",
+ "name": "claude-instant-1",
+ "description": "Claude Instant latest major version, automatically get updates to the model as they are released"
+ },
+ {
+ "label": "claude-v1",
+ "name": "claude-v1"
+ },
+ {
+ "label": "claude-v1-100k",
+ "name": "claude-v1-100k"
+ },
+ {
+ "label": "claude-v1.0",
+ "name": "claude-v1.0"
+ },
+ {
+ "label": "claude-v1.2",
+ "name": "claude-v1.2"
+ },
+ {
+ "label": "claude-v1.3",
+ "name": "claude-v1.3"
+ },
+ {
+ "label": "claude-v1.3-100k",
+ "name": "claude-v1.3-100k"
+ },
+ {
+ "label": "claude-instant-v1",
+ "name": "claude-instant-v1"
+ },
+ {
+ "label": "claude-instant-v1-100k",
+ "name": "claude-instant-v1-100k"
+ },
+ {
+ "label": "claude-instant-v1.0",
+ "name": "claude-instant-v1.0"
+ },
+ {
+ "label": "claude-instant-v1.1",
+ "name": "claude-instant-v1.1"
+ },
+ {
+ "label": "claude-instant-v1.1-100k",
+ "name": "claude-instant-v1.1-100k"
+ }
+ ],
+ "default": "claude-v1",
+ "optional": true,
+ "id": "chatAnthropic_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatAnthropic_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokensToSample",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatAnthropic_0-input-maxTokensToSample-number"
+ },
+ {
+ "label": "Top P",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatAnthropic_0-input-topP-number"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatAnthropic_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "claude-2",
+ "temperature": 0.9,
+ "maxTokensToSample": "",
+ "topP": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatAnthropic_0-output-chatAnthropic-ChatAnthropic|BaseChatModel|BaseLanguageModel",
+ "name": "chatAnthropic",
+ "label": "ChatAnthropic",
+ "type": "ChatAnthropic | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 800.5525382783799,
+ "y": -76.7988221837009
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 507,
+ "id": "pdfFile_0",
+ "position": {
+ "x": 94.16886576108482,
+ "y": 37.12056504707391
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pdfFile_0",
+ "label": "Pdf File",
+ "name": "pdfFile",
+ "version": 1,
+ "type": "Document",
+ "baseClasses": ["Document"],
+ "category": "Document Loaders",
+ "description": "Load data from PDF files",
+ "inputParams": [
+ {
+ "label": "Pdf File",
+ "name": "pdfFile",
+ "type": "file",
+ "fileType": ".pdf",
+ "id": "pdfFile_0-input-pdfFile-file"
+ },
+ {
+ "label": "Usage",
+ "name": "usage",
+ "type": "options",
+ "options": [
+ {
+ "label": "One document per page",
+ "name": "perPage"
+ },
+ {
+ "label": "One document per file",
+ "name": "perFile"
+ }
+ ],
+ "default": "perPage",
+ "id": "pdfFile_0-input-usage-options"
+ },
+ {
+ "label": "Use Legacy Build",
+ "name": "legacyBuild",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pdfFile_0-input-legacyBuild-boolean"
+ },
+ {
+ "label": "Metadata",
+ "name": "metadata",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pdfFile_0-input-metadata-json"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Text Splitter",
+ "name": "textSplitter",
+ "type": "TextSplitter",
+ "optional": true,
+ "id": "pdfFile_0-input-textSplitter-TextSplitter"
+ }
+ ],
+ "inputs": {
+ "textSplitter": "",
+ "usage": "perPage",
+ "legacyBuild": "",
+ "metadata": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "pdfFile_0-output-pdfFile-Document",
+ "name": "pdfFile",
+ "label": "Document",
+ "type": "Document"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 94.16886576108482,
+ "y": 37.12056504707391
+ },
+ "dragging": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "bufferMemory_0",
+ "sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "target": "conversationChain_0",
+ "targetHandle": "conversationChain_0-input-memory-BaseMemory",
+ "type": "buttonedge",
+ "id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-conversationChain_0-conversationChain_0-input-memory-BaseMemory",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatAnthropic_0",
+ "sourceHandle": "chatAnthropic_0-output-chatAnthropic-ChatAnthropic|BaseChatModel|BaseLanguageModel",
+ "target": "conversationChain_0",
+ "targetHandle": "conversationChain_0-input-model-BaseChatModel",
+ "type": "buttonedge",
+ "id": "chatAnthropic_0-chatAnthropic_0-output-chatAnthropic-ChatAnthropic|BaseChatModel|BaseLanguageModel-conversationChain_0-conversationChain_0-input-model-BaseChatModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "pdfFile_0",
+ "sourceHandle": "pdfFile_0-output-pdfFile-Document",
+ "target": "conversationChain_0",
+ "targetHandle": "conversationChain_0-input-document-Document",
+ "type": "buttonedge",
+ "id": "pdfFile_0-pdfFile_0-output-pdfFile-Document-conversationChain_0-conversationChain_0-input-document-Document",
+ "data": {
+ "label": ""
+ }
+ }
+ ]
+}
diff --git a/packages/server/marketplaces/Conversational Agent.json b/packages/server/marketplaces/chatflows/Conversational Agent.json
similarity index 70%
rename from packages/server/marketplaces/Conversational Agent.json
rename to packages/server/marketplaces/chatflows/Conversational Agent.json
index b0295fd6..55475b3e 100644
--- a/packages/server/marketplaces/Conversational Agent.json
+++ b/packages/server/marketplaces/chatflows/Conversational Agent.json
@@ -3,27 +3,172 @@
"nodes": [
{
"width": 300,
- "height": 524,
- "id": "chatOpenAI_1",
+ "height": 143,
+ "id": "calculator_1",
"position": {
- "x": 56.646518061018355,
- "y": 71.07043412525425
+ "x": 800.5125025564965,
+ "y": 72.40592063242738
},
"type": "customNode",
"data": {
- "id": "chatOpenAI_1",
+ "id": "calculator_1",
+ "label": "Calculator",
+ "name": "calculator",
+ "version": 1,
+ "type": "Calculator",
+ "baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Perform calculations on response",
+ "inputParams": [],
+ "inputAnchors": [],
+ "inputs": {},
+ "outputAnchors": [
+ {
+ "id": "calculator_1-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain",
+ "name": "calculator",
+ "label": "Calculator",
+ "type": "Calculator | Tool | StructuredTool | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 800.5125025564965,
+ "y": 72.40592063242738
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 376,
+ "id": "bufferMemory_1",
+ "position": {
+ "x": 607.6260576768354,
+ "y": 584.7920541862369
+ },
+ "type": "customNode",
+ "data": {
+ "id": "bufferMemory_1",
+ "label": "Buffer Memory",
+ "name": "bufferMemory",
+ "version": 1,
+ "type": "BufferMemory",
+ "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Remembers previous conversational back and forths directly",
+ "inputParams": [
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "id": "bufferMemory_1-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "id": "bufferMemory_1-input-inputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "memoryKey": "chat_history",
+ "inputKey": "input"
+ },
+ "outputAnchors": [
+ {
+ "id": "bufferMemory_1-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "name": "bufferMemory",
+ "label": "BufferMemory",
+ "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 607.6260576768354,
+ "y": 584.7920541862369
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 277,
+ "id": "serpAPI_0",
+ "position": {
+ "x": 451.83740798447855,
+ "y": 53.2843022150486
+ },
+ "type": "customNode",
+ "data": {
+ "id": "serpAPI_0",
+ "label": "Serp API",
+ "name": "serpAPI",
+ "version": 1,
+ "type": "SerpAPI",
+ "baseClasses": ["SerpAPI", "Tool", "StructuredTool"],
+ "category": "Tools",
+ "description": "Wrapper around SerpAPI - a real-time API to access Google search results",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["serpApi"],
+ "id": "serpAPI_0-input-credential-credential"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {},
+ "outputAnchors": [
+ {
+ "id": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool",
+ "name": "serpAPI",
+ "label": "SerpAPI",
+ "type": "SerpAPI | Tool | StructuredTool"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 451.83740798447855,
+ "y": 53.2843022150486
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 97.01321406237057,
+ "y": 63.67664262280914
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_1-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -65,7 +210,7 @@
],
"default": "gpt-3.5-turbo",
"optional": true,
- "id": "chatOpenAI_1-input-modelName-options"
+ "id": "chatOpenAI_0-input-modelName-options"
},
{
"label": "Temperature",
@@ -73,7 +218,7 @@
"type": "number",
"default": 0.9,
"optional": true,
- "id": "chatOpenAI_1-input-temperature-number"
+ "id": "chatOpenAI_0-input-temperature-number"
},
{
"label": "Max Tokens",
@@ -81,7 +226,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-maxTokens-number"
+ "id": "chatOpenAI_0-input-maxTokens-number"
},
{
"label": "Top Probability",
@@ -89,7 +234,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-topP-number"
+ "id": "chatOpenAI_0-input-topP-number"
},
{
"label": "Frequency Penalty",
@@ -97,7 +242,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-frequencyPenalty-number"
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
},
{
"label": "Presence Penalty",
@@ -105,7 +250,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-presencePenalty-number"
+ "id": "chatOpenAI_0-input-presencePenalty-number"
},
{
"label": "Timeout",
@@ -113,7 +258,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-timeout-number"
+ "id": "chatOpenAI_0-input-timeout-number"
},
{
"label": "BasePath",
@@ -121,25 +266,26 @@
"type": "string",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-basepath-string"
+ "id": "chatOpenAI_0-input-basepath-string"
}
],
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
- "temperature": "0",
+ "temperature": 0.9,
"maxTokens": "",
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -147,165 +293,27 @@
},
"selected": false,
"positionAbsolute": {
- "x": 56.646518061018355,
- "y": 71.07043412525425
+ "x": 97.01321406237057,
+ "y": 63.67664262280914
},
"dragging": false
},
- {
- "width": 300,
- "height": 278,
- "id": "serpAPI_1",
- "position": {
- "x": 436.94138168947336,
- "y": 39.517825311262044
- },
- "type": "customNode",
- "data": {
- "id": "serpAPI_1",
- "label": "Serp API",
- "name": "serpAPI",
- "type": "SerpAPI",
- "baseClasses": ["SerpAPI", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Wrapper around SerpAPI - a real-time API to access Google search results",
- "inputParams": [
- {
- "label": "Serp Api Key",
- "name": "apiKey",
- "type": "password",
- "id": "serpAPI_1-input-apiKey-password"
- }
- ],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "serpAPI_1-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
- "name": "serpAPI",
- "label": "SerpAPI",
- "type": "SerpAPI | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 436.94138168947336,
- "y": 39.517825311262044
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 143,
- "id": "calculator_1",
- "position": {
- "x": 800.5125025564965,
- "y": 72.40592063242738
- },
- "type": "customNode",
- "data": {
- "id": "calculator_1",
- "label": "Calculator",
- "name": "calculator",
- "type": "Calculator",
- "baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Perform calculations on response",
- "inputParams": [],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "calculator_1-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain",
- "name": "calculator",
- "label": "Calculator",
- "type": "Calculator | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 800.5125025564965,
- "y": 72.40592063242738
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 376,
- "id": "bufferMemory_1",
- "position": {
- "x": 573.479796337051,
- "y": 575.8843338367278
- },
- "type": "customNode",
- "data": {
- "id": "bufferMemory_1",
- "label": "Buffer Memory",
- "name": "bufferMemory",
- "type": "BufferMemory",
- "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
- "category": "Memory",
- "description": "Remembers previous conversational back and forths directly",
- "inputParams": [
- {
- "label": "Memory Key",
- "name": "memoryKey",
- "type": "string",
- "default": "chat_history",
- "id": "bufferMemory_1-input-memoryKey-string"
- },
- {
- "label": "Input Key",
- "name": "inputKey",
- "type": "string",
- "default": "input",
- "id": "bufferMemory_1-input-inputKey-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "memoryKey": "chat_history",
- "inputKey": "input"
- },
- "outputAnchors": [
- {
- "id": "bufferMemory_1-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
- "name": "bufferMemory",
- "label": "BufferMemory",
- "type": "BufferMemory | BaseChatMemory | BaseMemory"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 573.479796337051,
- "y": 575.8843338367278
- },
- "selected": false,
- "dragging": false
- },
{
"width": 300,
"height": 383,
"id": "conversationalAgent_0",
"position": {
- "x": 1206.1996037716035,
- "y": 227.39579577603587
+ "x": 1164.4550359451973,
+ "y": 283.40041124403075
},
"type": "customNode",
"data": {
"id": "conversationalAgent_0",
"label": "Conversational Agent",
"name": "conversationalAgent",
+ "version": 1,
"type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
+ "baseClasses": ["AgentExecutor", "BaseChain"],
"category": "Agents",
"description": "Conversational agent for a chat model. It will utilize chat specific prompts",
"inputParams": [
@@ -314,18 +322,10 @@
"name": "systemMessage",
"type": "string",
"rows": 4,
+ "default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
"optional": true,
"additionalParams": true,
"id": "conversationalAgent_0-input-systemMessage-string"
- },
- {
- "label": "Human Message",
- "name": "humanMessage",
- "type": "string",
- "rows": 4,
- "optional": true,
- "additionalParams": true,
- "id": "conversationalAgent_0-input-humanMessage-string"
}
],
"inputAnchors": [
@@ -350,18 +350,17 @@
}
],
"inputs": {
- "tools": ["{{calculator_1.data.instance}}", "{{serpAPI_1.data.instance}}"],
- "model": "{{chatOpenAI_1.data.instance}}",
+ "tools": ["{{calculator_1.data.instance}}", "{{serpAPI_0.data.instance}}"],
+ "model": "{{chatOpenAI_0.data.instance}}",
"memory": "{{bufferMemory_1.data.instance}}",
- "systemMessage": "",
- "humanMessage": ""
+ "systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
},
"outputAnchors": [
{
- "id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|BaseLangChain",
+ "id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain",
"name": "conversationalAgent",
"label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain | BaseLangChain"
+ "type": "AgentExecutor | BaseChain"
}
],
"outputs": {},
@@ -369,8 +368,8 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1206.1996037716035,
- "y": 227.39579577603587
+ "x": 1164.4550359451973,
+ "y": 283.40041124403075
},
"dragging": false
}
@@ -388,23 +387,23 @@
}
},
{
- "source": "serpAPI_1",
- "sourceHandle": "serpAPI_1-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
+ "source": "serpAPI_0",
+ "sourceHandle": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-tools-Tool",
"type": "buttonedge",
- "id": "serpAPI_1-serpAPI_1-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain-conversationalAgent_0-conversationalAgent_0-input-tools-Tool",
+ "id": "serpAPI_0-serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool-conversationalAgent_0-conversationalAgent_0-input-tools-Tool",
"data": {
"label": ""
}
},
{
- "source": "chatOpenAI_1",
- "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalAgent_0",
"targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Conversational Retrieval QA Chain.json b/packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json
similarity index 76%
rename from packages/server/marketplaces/Conversational Retrieval QA Chain.json
rename to packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json
index ed190cdc..bf27e443 100644
--- a/packages/server/marketplaces/Conversational Retrieval QA Chain.json
+++ b/packages/server/marketplaces/chatflows/Conversational Retrieval QA Chain.json
@@ -3,341 +3,29 @@
"nodes": [
{
"width": 300,
- "height": 376,
- "id": "recursiveCharacterTextSplitter_1",
- "position": {
- "x": 422.81091375202413,
- "y": 122.99825010325736
- },
- "type": "customNode",
- "data": {
- "id": "recursiveCharacterTextSplitter_1",
- "label": "Recursive Character Text Splitter",
- "name": "recursiveCharacterTextSplitter",
- "type": "RecursiveCharacterTextSplitter",
- "baseClasses": ["RecursiveCharacterTextSplitter", "TextSplitter"],
- "category": "Text Splitters",
- "description": "Split documents recursively by different characters - starting with \"\n\n\", then \"\n\", then \" \"",
- "inputParams": [
- {
- "label": "Chunk Size",
- "name": "chunkSize",
- "type": "number",
- "default": 1000,
- "optional": true,
- "id": "recursiveCharacterTextSplitter_1-input-chunkSize-number"
- },
- {
- "label": "Chunk Overlap",
- "name": "chunkOverlap",
- "type": "number",
- "optional": true,
- "id": "recursiveCharacterTextSplitter_1-input-chunkOverlap-number"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "chunkSize": 1000,
- "chunkOverlap": ""
- },
- "outputAnchors": [
- {
- "id": "recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
- "name": "recursiveCharacterTextSplitter",
- "label": "RecursiveCharacterTextSplitter",
- "type": "RecursiveCharacterTextSplitter | TextSplitter"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 422.81091375202413,
- "y": 122.99825010325736
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 392,
- "id": "textFile_1",
- "position": {
- "x": 810.6456923854021,
- "y": 61.45989039390216
- },
- "type": "customNode",
- "data": {
- "id": "textFile_1",
- "label": "Text File",
- "name": "textFile",
- "type": "Document",
- "baseClasses": ["Document"],
- "category": "Document Loaders",
- "description": "Load data from text files",
- "inputParams": [
- {
- "label": "Txt File",
- "name": "txtFile",
- "type": "file",
- "fileType": ".txt",
- "id": "textFile_1-input-txtFile-file"
- },
- {
- "label": "Metadata",
- "name": "metadata",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "textFile_1-input-metadata-json"
- }
- ],
- "inputAnchors": [
- {
- "label": "Text Splitter",
- "name": "textSplitter",
- "type": "TextSplitter",
- "optional": true,
- "id": "textFile_1-input-textSplitter-TextSplitter"
- }
- ],
- "inputs": {
- "textSplitter": "{{recursiveCharacterTextSplitter_1.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "textFile_1-output-textFile-Document",
- "name": "textFile",
- "label": "Document",
- "type": "Document"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 810.6456923854021,
- "y": 61.45989039390216
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 330,
- "id": "openAIEmbeddings_1",
- "position": {
- "x": 817.2208258595176,
- "y": 586.8095386455508
- },
- "type": "customNode",
- "data": {
- "id": "openAIEmbeddings_1",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_1-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 817.2208258595176,
- "y": 586.8095386455508
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 702,
- "id": "pineconeUpsert_1",
- "position": {
- "x": 1201.3427203075867,
- "y": 545.1800202023215
- },
- "type": "customNode",
- "data": {
- "id": "pineconeUpsert_1",
- "label": "Pinecone Upsert Document",
- "name": "pineconeUpsert",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Upsert documents to Pinecone",
- "inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeUpsert_1-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeUpsert_1-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeUpsert_1-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeUpsert_1-input-pineconeNamespace-string"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "pineconeUpsert_1-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Document",
- "name": "document",
- "type": "Document",
- "list": true,
- "id": "pineconeUpsert_1-input-document-Document"
- },
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "pineconeUpsert_1-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "document": ["{{textFile_1.data.instance}}"],
- "embeddings": "{{openAIEmbeddings_1.data.instance}}",
- "pineconeEnv": "us-west4-gcp",
- "pineconeIndex": "myindex",
- "pineconeNamespace": "mynamespace"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "pineconeUpsert_1-output-vectorStore-Pinecone|VectorStore",
- "name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "retriever"
- },
- "selected": false
- },
- "selected": false,
- "dragging": false,
- "positionAbsolute": {
- "x": 1201.3427203075867,
- "y": 545.1800202023215
- }
- },
- {
- "width": 300,
- "height": 524,
+ "height": 522,
"id": "chatOpenAI_0",
"position": {
- "x": 1200.565568471151,
- "y": -33.648143275380406
+ "x": 1184.1176114500388,
+ "y": -44.15535835370571
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -441,19 +129,104 @@
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
- "temperature": "0.5",
+ "temperature": "0",
"maxTokens": "",
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 1184.1176114500388,
+ "y": -44.15535835370571
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 328,
+ "id": "openAIEmbeddings_0",
+ "position": {
+ "x": 795.6162477805387,
+ "y": 603.260214150876
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
}
],
"outputs": {},
@@ -461,26 +234,259 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1200.565568471151,
- "y": -33.648143275380406
+ "x": 795.6162477805387,
+ "y": 603.260214150876
},
"dragging": false
},
{
"width": 300,
- "height": 280,
+ "height": 554,
+ "id": "pineconeUpsert_0",
+ "position": {
+ "x": 1191.1792786926865,
+ "y": 514.2126330994578
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeUpsert_0",
+ "label": "Pinecone Upsert Document",
+ "name": "pineconeUpsert",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Upsert documents to Pinecone",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeUpsert_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeUpsert_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeUpsert_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeUpsert_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Document",
+ "name": "document",
+ "type": "Document",
+ "list": true,
+ "id": "pineconeUpsert_0-input-document-Document"
+ },
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeUpsert_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "document": ["{{textFile_0.data.instance}}"],
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeUpsert_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "retriever"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1191.1792786926865,
+ "y": 514.2126330994578
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 376,
+ "id": "recursiveCharacterTextSplitter_0",
+ "position": {
+ "x": 406.08456707531263,
+ "y": 197.66460328693972
+ },
+ "type": "customNode",
+ "data": {
+ "id": "recursiveCharacterTextSplitter_0",
+ "label": "Recursive Character Text Splitter",
+ "name": "recursiveCharacterTextSplitter",
+ "version": 1,
+ "type": "RecursiveCharacterTextSplitter",
+ "baseClasses": ["RecursiveCharacterTextSplitter", "TextSplitter"],
+ "category": "Text Splitters",
+ "description": "Split documents recursively by different characters - starting with \"\\n\\n\", then \"\\n\", then \" \"",
+ "inputParams": [
+ {
+ "label": "Chunk Size",
+ "name": "chunkSize",
+ "type": "number",
+ "default": 1000,
+ "optional": true,
+ "id": "recursiveCharacterTextSplitter_0-input-chunkSize-number"
+ },
+ {
+ "label": "Chunk Overlap",
+ "name": "chunkOverlap",
+ "type": "number",
+ "optional": true,
+ "id": "recursiveCharacterTextSplitter_0-input-chunkOverlap-number"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "chunkSize": 1000,
+ "chunkOverlap": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
+ "name": "recursiveCharacterTextSplitter",
+ "label": "RecursiveCharacterTextSplitter",
+ "type": "RecursiveCharacterTextSplitter | TextSplitter"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 406.08456707531263,
+ "y": 197.66460328693972
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 410,
+ "id": "textFile_0",
+ "position": {
+ "x": 786.5497697231324,
+ "y": 140.09563157584407
+ },
+ "type": "customNode",
+ "data": {
+ "id": "textFile_0",
+ "label": "Text File",
+ "name": "textFile",
+ "version": 1,
+ "type": "Document",
+ "baseClasses": ["Document"],
+ "category": "Document Loaders",
+ "description": "Load data from text files",
+ "inputParams": [
+ {
+ "label": "Txt File",
+ "name": "txtFile",
+ "type": "file",
+ "fileType": ".txt",
+ "id": "textFile_0-input-txtFile-file"
+ },
+ {
+ "label": "Metadata",
+ "name": "metadata",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "textFile_0-input-metadata-json"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Text Splitter",
+ "name": "textSplitter",
+ "type": "TextSplitter",
+ "optional": true,
+ "id": "textFile_0-input-textSplitter-TextSplitter"
+ }
+ ],
+ "inputs": {
+ "textSplitter": "{{recursiveCharacterTextSplitter_0.data.instance}}",
+ "metadata": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "textFile_0-output-textFile-Document",
+ "name": "textFile",
+ "label": "Document",
+ "type": "Document"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 786.5497697231324,
+ "y": 140.09563157584407
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 479,
"id": "conversationalRetrievalQAChain_0",
"position": {
- "x": 1627.1855024401737,
- "y": 394.42287890442145
+ "x": 1558.6564094656787,
+ "y": 386.60217819991124
},
"type": "customNode",
"data": {
"id": "conversationalRetrievalQAChain_0",
"label": "Conversational Retrieval QA Chain",
"name": "conversationalRetrievalQAChain",
+ "version": 1,
"type": "ConversationalRetrievalQAChain",
- "baseClasses": ["ConversationalRetrievalQAChain", "BaseChain", "BaseLangChain"],
+ "baseClasses": ["ConversationalRetrievalQAChain", "BaseChain"],
"category": "Chains",
"description": "Document QA - built on RetrievalQAChain to provide a chat history component",
"inputParams": [
@@ -539,83 +545,94 @@
"name": "vectorStoreRetriever",
"type": "BaseRetriever",
"id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
}
],
"inputs": {
"model": "{{chatOpenAI_0.data.instance}}",
- "vectorStoreRetriever": "{{pineconeUpsert_1.data.instance}}"
+ "vectorStoreRetriever": "{{pineconeUpsert_0.data.instance}}",
+ "memory": "",
+ "returnSourceDocuments": "",
+ "systemMessagePrompt": "",
+ "chainOption": ""
},
"outputAnchors": [
{
- "id": "conversationalRetrievalQAChain_0-output-conversationalRetrievalQAChain-ConversationalRetrievalQAChain|BaseChain|BaseLangChain",
+ "id": "conversationalRetrievalQAChain_0-output-conversationalRetrievalQAChain-ConversationalRetrievalQAChain|BaseChain",
"name": "conversationalRetrievalQAChain",
"label": "ConversationalRetrievalQAChain",
- "type": "ConversationalRetrievalQAChain | BaseChain | BaseLangChain"
+ "type": "ConversationalRetrievalQAChain | BaseChain"
}
],
"outputs": {},
"selected": false
},
- "selected": false,
"positionAbsolute": {
- "x": 1627.1855024401737,
- "y": 394.42287890442145
+ "x": 1558.6564094656787,
+ "y": 386.60217819991124
},
- "dragging": false
+ "selected": false
}
],
"edges": [
{
- "source": "openAIEmbeddings_1",
- "sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "pineconeUpsert_1",
- "targetHandle": "pineconeUpsert_1-input-embeddings-Embeddings",
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeUpsert_0",
+ "targetHandle": "pineconeUpsert_0-input-embeddings-Embeddings",
"type": "buttonedge",
- "id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_1-pineconeUpsert_1-input-embeddings-Embeddings",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_0-pineconeUpsert_0-input-embeddings-Embeddings",
"data": {
"label": ""
}
},
{
- "source": "textFile_1",
- "sourceHandle": "textFile_1-output-textFile-Document",
- "target": "pineconeUpsert_1",
- "targetHandle": "pineconeUpsert_1-input-document-Document",
+ "source": "recursiveCharacterTextSplitter_0",
+ "sourceHandle": "recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
+ "target": "textFile_0",
+ "targetHandle": "textFile_0-input-textSplitter-TextSplitter",
"type": "buttonedge",
- "id": "textFile_1-textFile_1-output-textFile-Document-pineconeUpsert_1-pineconeUpsert_1-input-document-Document",
+ "id": "recursiveCharacterTextSplitter_0-recursiveCharacterTextSplitter_0-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter-textFile_0-textFile_0-input-textSplitter-TextSplitter",
"data": {
"label": ""
}
},
{
- "source": "recursiveCharacterTextSplitter_1",
- "sourceHandle": "recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
- "target": "textFile_1",
- "targetHandle": "textFile_1-input-textSplitter-TextSplitter",
+ "source": "textFile_0",
+ "sourceHandle": "textFile_0-output-textFile-Document",
+ "target": "pineconeUpsert_0",
+ "targetHandle": "pineconeUpsert_0-input-document-Document",
"type": "buttonedge",
- "id": "recursiveCharacterTextSplitter_1-recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter-textFile_1-textFile_1-input-textSplitter-TextSplitter",
+ "id": "textFile_0-textFile_0-output-textFile-Document-pineconeUpsert_0-pineconeUpsert_0-input-document-Document",
"data": {
"label": ""
}
},
{
"source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalRetrievalQAChain_0",
"targetHandle": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
},
{
- "source": "pineconeUpsert_1",
- "sourceHandle": "pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "source": "pineconeUpsert_0",
+ "sourceHandle": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
"target": "conversationalRetrievalQAChain_0",
"targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
"type": "buttonedge",
- "id": "pineconeUpsert_1-pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "id": "pineconeUpsert_0-pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Github Repo QnA.json b/packages/server/marketplaces/chatflows/Flowise Docs QnA.json
similarity index 68%
rename from packages/server/marketplaces/Github Repo QnA.json
rename to packages/server/marketplaces/chatflows/Flowise Docs QnA.json
index 92867957..6d11f3d2 100644
--- a/packages/server/marketplaces/Github Repo QnA.json
+++ b/packages/server/marketplaces/chatflows/Flowise Docs QnA.json
@@ -1,23 +1,24 @@
{
- "description": "Github repo QnA using conversational retrieval QA chain",
+ "description": "Flowise Docs Github QnA using conversational retrieval QA chain",
"nodes": [
{
"width": 300,
"height": 376,
- "id": "recursiveCharacterTextSplitter_1",
+ "id": "markdownTextSplitter_0",
"position": {
- "x": 447.1038086695898,
- "y": 126.52301921543597
+ "x": 1081.1540334344143,
+ "y": -113.73571627207801
},
"type": "customNode",
"data": {
- "id": "recursiveCharacterTextSplitter_1",
- "label": "Recursive Character Text Splitter",
- "name": "recursiveCharacterTextSplitter",
- "type": "RecursiveCharacterTextSplitter",
- "baseClasses": ["RecursiveCharacterTextSplitter", "TextSplitter"],
+ "id": "markdownTextSplitter_0",
+ "label": "Markdown Text Splitter",
+ "name": "markdownTextSplitter",
+ "version": 1,
+ "type": "MarkdownTextSplitter",
+ "baseClasses": ["MarkdownTextSplitter", "RecursiveCharacterTextSplitter", "TextSplitter", "BaseDocumentTransformer"],
"category": "Text Splitters",
- "description": "Split documents recursively by different characters - starting with \"\n\n\", then \"\n\", then \" \"",
+ "description": "Split your content into documents based on the Markdown headers",
"inputParams": [
{
"label": "Chunk Size",
@@ -25,108 +26,27 @@
"type": "number",
"default": 1000,
"optional": true,
- "id": "recursiveCharacterTextSplitter_1-input-chunkSize-number"
+ "id": "markdownTextSplitter_0-input-chunkSize-number"
},
{
"label": "Chunk Overlap",
"name": "chunkOverlap",
"type": "number",
"optional": true,
- "id": "recursiveCharacterTextSplitter_1-input-chunkOverlap-number"
+ "id": "markdownTextSplitter_0-input-chunkOverlap-number"
}
],
"inputAnchors": [],
"inputs": {
- "chunkSize": 1000,
+ "chunkSize": "4000",
"chunkOverlap": ""
},
"outputAnchors": [
{
- "id": "recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
- "name": "recursiveCharacterTextSplitter",
- "label": "RecursiveCharacterTextSplitter",
- "type": "RecursiveCharacterTextSplitter | TextSplitter"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 447.1038086695898,
- "y": 126.52301921543597
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 578,
- "id": "github_1",
- "position": {
- "x": 836.9660489009947,
- "y": -44.04171088580361
- },
- "type": "customNode",
- "data": {
- "id": "github_1",
- "label": "Github",
- "name": "github",
- "type": "Document",
- "baseClasses": ["Document"],
- "category": "Document Loaders",
- "description": "Load data from a GitHub repository",
- "inputParams": [
- {
- "label": "Repo Link",
- "name": "repoLink",
- "type": "string",
- "placeholder": "https://github.com/FlowiseAI/Flowise",
- "id": "github_1-input-repoLink-string"
- },
- {
- "label": "Branch",
- "name": "branch",
- "type": "string",
- "default": "main",
- "id": "github_1-input-branch-string"
- },
- {
- "label": "Access Token",
- "name": "accessToken",
- "type": "password",
- "placeholder": "",
- "optional": true,
- "id": "github_1-input-accessToken-password"
- },
- {
- "label": "Metadata",
- "name": "metadata",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "github_1-input-metadata-json"
- }
- ],
- "inputAnchors": [
- {
- "label": "Text Splitter",
- "name": "textSplitter",
- "type": "TextSplitter",
- "optional": true,
- "id": "github_1-input-textSplitter-TextSplitter"
- }
- ],
- "inputs": {
- "repoLink": "",
- "branch": "main",
- "textSplitter": "{{recursiveCharacterTextSplitter_1.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "github_1-output-github-Document",
- "name": "github",
- "label": "Document",
- "type": "Document"
+ "id": "markdownTextSplitter_0-output-markdownTextSplitter-MarkdownTextSplitter|RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer",
+ "name": "markdownTextSplitter",
+ "label": "MarkdownTextSplitter",
+ "type": "MarkdownTextSplitter | RecursiveCharacterTextSplitter | TextSplitter | BaseDocumentTransformer"
}
],
"outputs": {},
@@ -134,146 +54,38 @@
},
"selected": false,
"positionAbsolute": {
- "x": 836.9660489009947,
- "y": -44.04171088580361
+ "x": 1081.1540334344143,
+ "y": -113.73571627207801
},
"dragging": false
},
{
"width": 300,
- "height": 330,
- "id": "openAIEmbeddings_1",
+ "height": 405,
+ "id": "memoryVectorStore_0",
"position": {
- "x": 833.4085562012468,
- "y": 541.7875676090047
+ "x": 1844.88052464165,
+ "y": 484.60473328470243
},
"type": "customNode",
"data": {
- "id": "openAIEmbeddings_1",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_1-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 833.4085562012468,
- "y": 541.7875676090047
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 702,
- "id": "pineconeUpsert_1",
- "position": {
- "x": 1268.7946529279823,
- "y": 382.77997896801634
- },
- "type": "customNode",
- "data": {
- "id": "pineconeUpsert_1",
- "label": "Pinecone Upsert Document",
- "name": "pineconeUpsert",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "id": "memoryVectorStore_0",
+ "label": "In-Memory Vector Store",
+ "name": "memoryVectorStore",
+ "version": 1,
+ "type": "Memory",
+ "baseClasses": ["Memory", "VectorStoreRetriever", "BaseRetriever"],
"category": "Vector Stores",
- "description": "Upsert documents to Pinecone",
+ "description": "In-memory vectorstore that stores embeddings and does an exact, linear search for the most similar embeddings.",
"inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeUpsert_1-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeUpsert_1-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeUpsert_1-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeUpsert_1-input-pineconeNamespace-string"
- },
{
"label": "Top K",
"name": "topK",
"description": "Number of top results to fetch. Default to 4",
"placeholder": "4",
"type": "number",
- "additionalParams": true,
"optional": true,
- "id": "pineconeUpsert_1-input-topK-number"
+ "id": "memoryVectorStore_0-input-topK-number"
}
],
"inputAnchors": [
@@ -282,21 +94,19 @@
"name": "document",
"type": "Document",
"list": true,
- "id": "pineconeUpsert_1-input-document-Document"
+ "id": "memoryVectorStore_0-input-document-Document"
},
{
"label": "Embeddings",
"name": "embeddings",
"type": "Embeddings",
- "id": "pineconeUpsert_1-input-embeddings-Embeddings"
+ "id": "memoryVectorStore_0-input-embeddings-Embeddings"
}
],
"inputs": {
- "document": ["{{github_1.data.instance}}"],
- "embeddings": "{{openAIEmbeddings_1.data.instance}}",
- "pineconeEnv": "us-west4-gcp",
- "pineconeIndex": "myindex",
- "pineconeNamespace": "mynamespace"
+ "document": ["{{github_0.data.instance}}"],
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "topK": ""
},
"outputAnchors": [
{
@@ -305,16 +115,16 @@
"type": "options",
"options": [
{
- "id": "pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "id": "memoryVectorStore_0-output-retriever-Memory|VectorStoreRetriever|BaseRetriever",
"name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ "label": "Memory Retriever",
+ "type": "Memory | VectorStoreRetriever | BaseRetriever"
},
{
- "id": "pineconeUpsert_1-output-vectorStore-Pinecone|VectorStore",
+ "id": "memoryVectorStore_0-output-vectorStore-Memory|VectorStore",
"name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
+ "label": "Memory Vector Store",
+ "type": "Memory | VectorStore"
}
],
"default": "retriever"
@@ -326,35 +136,239 @@
"selected": false
},
"selected": false,
+ "positionAbsolute": {
+ "x": 1844.88052464165,
+ "y": 484.60473328470243
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 479,
+ "id": "conversationalRetrievalQAChain_0",
+ "position": {
+ "x": 2311.697827287373,
+ "y": 228.14841720207832
+ },
+ "type": "customNode",
+ "data": {
+ "id": "conversationalRetrievalQAChain_0",
+ "label": "Conversational Retrieval QA Chain",
+ "name": "conversationalRetrievalQAChain",
+ "version": 1,
+ "type": "ConversationalRetrievalQAChain",
+ "baseClasses": ["ConversationalRetrievalQAChain", "BaseChain"],
+ "category": "Chains",
+ "description": "Document QA - built on RetrievalQAChain to provide a chat history component",
+ "inputParams": [
+ {
+ "label": "Return Source Documents",
+ "name": "returnSourceDocuments",
+ "type": "boolean",
+ "optional": true,
+ "id": "conversationalRetrievalQAChain_0-input-returnSourceDocuments-boolean"
+ },
+ {
+ "label": "System Message",
+ "name": "systemMessagePrompt",
+ "type": "string",
+ "rows": 4,
+ "additionalParams": true,
+ "optional": true,
+ "placeholder": "I want you to act as a document that I am having a conversation with. Your name is \"AI Assistant\". You will provide me with answers from the given info. If the answer is not included, say exactly \"Hmm, I am not sure.\" and stop after that. Refuse to answer any question not about the info. Never break character.",
+ "id": "conversationalRetrievalQAChain_0-input-systemMessagePrompt-string"
+ },
+ {
+ "label": "Chain Option",
+ "name": "chainOption",
+ "type": "options",
+ "options": [
+ {
+ "label": "MapReduceDocumentsChain",
+ "name": "map_reduce",
+ "description": "Suitable for QA tasks over larger documents and can run the preprocessing step in parallel, reducing the running time"
+ },
+ {
+ "label": "RefineDocumentsChain",
+ "name": "refine",
+ "description": "Suitable for QA tasks over a large number of documents."
+ },
+ {
+ "label": "StuffDocumentsChain",
+ "name": "stuff",
+ "description": "Suitable for QA tasks over a small number of documents."
+ }
+ ],
+ "additionalParams": true,
+ "optional": true,
+ "id": "conversationalRetrievalQAChain_0-input-chainOption-options"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Vector Store Retriever",
+ "name": "vectorStoreRetriever",
+ "type": "BaseRetriever",
+ "id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "vectorStoreRetriever": "{{memoryVectorStore_0.data.instance}}",
+ "memory": "",
+ "returnSourceDocuments": true,
+ "systemMessagePrompt": "",
+ "chainOption": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "conversationalRetrievalQAChain_0-output-conversationalRetrievalQAChain-ConversationalRetrievalQAChain|BaseChain",
+ "name": "conversationalRetrievalQAChain",
+ "label": "ConversationalRetrievalQAChain",
+ "type": "ConversationalRetrievalQAChain | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
"dragging": false,
"positionAbsolute": {
- "x": 1268.7946529279823,
- "y": 382.77997896801634
+ "x": 2311.697827287373,
+ "y": 228.14841720207832
}
},
{
"width": 300,
- "height": 524,
+ "height": 673,
+ "id": "github_0",
+ "position": {
+ "x": 1460.1858988997,
+ "y": -137.83585695472374
+ },
+ "type": "customNode",
+ "data": {
+ "id": "github_0",
+ "label": "Github",
+ "name": "github",
+ "version": 1,
+ "type": "Document",
+ "baseClasses": ["Document"],
+ "category": "Document Loaders",
+ "description": "Load data from a GitHub repository",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "description": "Only needed when accessing private repo",
+ "optional": true,
+ "credentialNames": ["githubApi"],
+ "id": "github_0-input-credential-credential"
+ },
+ {
+ "label": "Repo Link",
+ "name": "repoLink",
+ "type": "string",
+ "placeholder": "https://github.com/FlowiseAI/Flowise",
+ "id": "github_0-input-repoLink-string"
+ },
+ {
+ "label": "Branch",
+ "name": "branch",
+ "type": "string",
+ "default": "main",
+ "id": "github_0-input-branch-string"
+ },
+ {
+ "label": "Recursive",
+ "name": "recursive",
+ "type": "boolean",
+ "optional": true,
+ "id": "github_0-input-recursive-boolean"
+ },
+ {
+ "label": "Metadata",
+ "name": "metadata",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "github_0-input-metadata-json"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Text Splitter",
+ "name": "textSplitter",
+ "type": "TextSplitter",
+ "optional": true,
+ "id": "github_0-input-textSplitter-TextSplitter"
+ }
+ ],
+ "inputs": {
+ "repoLink": "https://github.com/FlowiseAI/FlowiseDocs",
+ "branch": "main",
+ "recursive": true,
+ "textSplitter": "{{markdownTextSplitter_0.data.instance}}",
+ "metadata": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "github_0-output-github-Document",
+ "name": "github",
+ "label": "Document",
+ "type": "Document"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1460.1858988997,
+ "y": -137.83585695472374
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 522,
"id": "chatOpenAI_0",
"position": {
- "x": 1271.1300438358664,
- "y": -169.75707425097968
+ "x": 1857.367353502965,
+ "y": -104.25095383414119
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -458,19 +472,20 @@
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
- "temperature": "0.5",
+ "temperature": 0.9,
"maxTokens": "",
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -478,161 +493,148 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1271.1300438358664,
- "y": -169.75707425097968
+ "x": 1857.367353502965,
+ "y": -104.25095383414119
},
"dragging": false
},
{
"width": 300,
- "height": 280,
- "id": "conversationalRetrievalQAChain_0",
+ "height": 328,
+ "id": "openAIEmbeddings_0",
"position": {
- "x": 1653.6177539108153,
- "y": 266.4856653480158
+ "x": 1299.9983863833309,
+ "y": 581.8406384863323
},
"type": "customNode",
"data": {
- "id": "conversationalRetrievalQAChain_0",
- "label": "Conversational Retrieval QA Chain",
- "name": "conversationalRetrievalQAChain",
- "type": "ConversationalRetrievalQAChain",
- "baseClasses": ["ConversationalRetrievalQAChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "Document QA - built on RetrievalQAChain to provide a chat history component",
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
"inputParams": [
{
- "label": "Return Source Documents",
- "name": "returnSourceDocuments",
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
"type": "boolean",
"optional": true,
- "id": "conversationalRetrievalQAChain_0-input-returnSourceDocuments-boolean"
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
},
{
- "label": "System Message",
- "name": "systemMessagePrompt",
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
"type": "string",
- "rows": 4,
- "additionalParams": true,
"optional": true,
- "placeholder": "I want you to act as a document that I am having a conversation with. Your name is \"AI Assistant\". You will provide me with answers from the given info. If the answer is not included, say exactly \"Hmm, I am not sure.\" and stop after that. Refuse to answer any question not about the info. Never break character.",
- "id": "conversationalRetrievalQAChain_0-input-systemMessagePrompt-string"
- },
- {
- "label": "Chain Option",
- "name": "chainOption",
- "type": "options",
- "options": [
- {
- "label": "MapReduceDocumentsChain",
- "name": "map_reduce",
- "description": "Suitable for QA tasks over larger documents and can run the preprocessing step in parallel, reducing the running time"
- },
- {
- "label": "RefineDocumentsChain",
- "name": "refine",
- "description": "Suitable for QA tasks over a large number of documents."
- },
- {
- "label": "StuffDocumentsChain",
- "name": "stuff",
- "description": "Suitable for QA tasks over a small number of documents."
- }
- ],
"additionalParams": true,
- "optional": true,
- "id": "conversationalRetrievalQAChain_0-input-chainOption-options"
- }
- ],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel"
- },
- {
- "label": "Vector Store Retriever",
- "name": "vectorStoreRetriever",
- "type": "BaseRetriever",
- "id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ "id": "openAIEmbeddings_0-input-basepath-string"
}
],
+ "inputAnchors": [],
"inputs": {
- "model": "{{chatOpenAI_0.data.instance}}",
- "vectorStoreRetriever": "{{pineconeUpsert_1.data.instance}}"
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "conversationalRetrievalQAChain_0-output-conversationalRetrievalQAChain-ConversationalRetrievalQAChain|BaseChain|BaseLangChain",
- "name": "conversationalRetrievalQAChain",
- "label": "ConversationalRetrievalQAChain",
- "type": "ConversationalRetrievalQAChain | BaseChain | BaseLangChain"
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
}
],
"outputs": {},
"selected": false
},
"selected": false,
+ "dragging": false,
"positionAbsolute": {
- "x": 1653.6177539108153,
- "y": 266.4856653480158
- },
- "dragging": false
+ "x": 1299.9983863833309,
+ "y": 581.8406384863323
+ }
}
],
"edges": [
{
- "source": "github_1",
- "sourceHandle": "github_1-output-github-Document",
- "target": "pineconeUpsert_1",
- "targetHandle": "pineconeUpsert_1-input-document-Document",
+ "source": "memoryVectorStore_0",
+ "sourceHandle": "memoryVectorStore_0-output-retriever-Memory|VectorStoreRetriever|BaseRetriever",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
"type": "buttonedge",
- "id": "github_1-github_1-output-github-Document-pineconeUpsert_1-pineconeUpsert_1-input-document-Document",
+ "id": "memoryVectorStore_0-memoryVectorStore_0-output-retriever-Memory|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
"data": {
"label": ""
}
},
{
- "source": "openAIEmbeddings_1",
- "sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "pineconeUpsert_1",
- "targetHandle": "pineconeUpsert_1-input-embeddings-Embeddings",
+ "source": "markdownTextSplitter_0",
+ "sourceHandle": "markdownTextSplitter_0-output-markdownTextSplitter-MarkdownTextSplitter|RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer",
+ "target": "github_0",
+ "targetHandle": "github_0-input-textSplitter-TextSplitter",
"type": "buttonedge",
- "id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_1-pineconeUpsert_1-input-embeddings-Embeddings",
+ "id": "markdownTextSplitter_0-markdownTextSplitter_0-output-markdownTextSplitter-MarkdownTextSplitter|RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer-github_0-github_0-input-textSplitter-TextSplitter",
"data": {
"label": ""
}
},
{
- "source": "recursiveCharacterTextSplitter_1",
- "sourceHandle": "recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter",
- "target": "github_1",
- "targetHandle": "github_1-input-textSplitter-TextSplitter",
+ "source": "github_0",
+ "sourceHandle": "github_0-output-github-Document",
+ "target": "memoryVectorStore_0",
+ "targetHandle": "memoryVectorStore_0-input-document-Document",
"type": "buttonedge",
- "id": "recursiveCharacterTextSplitter_1-recursiveCharacterTextSplitter_1-output-recursiveCharacterTextSplitter-RecursiveCharacterTextSplitter|TextSplitter-github_1-github_1-input-textSplitter-TextSplitter",
+ "id": "github_0-github_0-output-github-Document-memoryVectorStore_0-memoryVectorStore_0-input-document-Document",
"data": {
"label": ""
}
},
{
"source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalRetrievalQAChain_0",
"targetHandle": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
},
{
- "source": "pineconeUpsert_1",
- "sourceHandle": "pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "target": "conversationalRetrievalQAChain_0",
- "targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "memoryVectorStore_0",
+ "targetHandle": "memoryVectorStore_0-input-embeddings-Embeddings",
"type": "buttonedge",
- "id": "pineconeUpsert_1-pineconeUpsert_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-memoryVectorStore_0-memoryVectorStore_0-input-embeddings-Embeddings",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/HuggingFace LLM Chain.json b/packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json
similarity index 82%
rename from packages/server/marketplaces/HuggingFace LLM Chain.json
rename to packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json
index 9d3492c6..6e159a28 100644
--- a/packages/server/marketplaces/HuggingFace LLM Chain.json
+++ b/packages/server/marketplaces/chatflows/HuggingFace LLM Chain.json
@@ -1,67 +1,6 @@
{
"description": "Simple LLM Chain using HuggingFace Inference API on falcon-7b-instruct model",
"nodes": [
- {
- "width": 300,
- "height": 532,
- "id": "promptTemplate_1",
- "position": {
- "x": 514.5434056794296,
- "y": 507.47798128037107
- },
- "type": "customNode",
- "data": {
- "id": "promptTemplate_1",
- "label": "Prompt Template",
- "name": "promptTemplate",
- "type": "PromptTemplate",
- "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
- "category": "Prompts",
- "description": "Schema to represent a basic prompt for an LLM",
- "inputParams": [
- {
- "label": "Template",
- "name": "template",
- "type": "string",
- "rows": 4,
- "placeholder": "What is a good name for a company that makes {product}?",
- "id": "promptTemplate_1-input-template-string"
- },
- {
- "label": "Format Prompt Values",
- "name": "promptValues",
- "type": "string",
- "rows": 4,
- "placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
- "optional": true,
- "acceptVariable": true,
- "list": true,
- "id": "promptTemplate_1-input-promptValues-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "template": "Question: {question}\n\nAnswer: Let's think step by step.",
- "promptValues": ""
- },
- "outputAnchors": [
- {
- "id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "name": "promptTemplate",
- "label": "PromptTemplate",
- "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 514.5434056794296,
- "y": 507.47798128037107
- },
- "dragging": false
- },
{
"width": 300,
"height": 405,
@@ -75,6 +14,7 @@
"id": "llmChain_1",
"label": "LLM Chain",
"name": "llmChain",
+ "version": 1,
"type": "LLMChain",
"baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -105,7 +45,7 @@
],
"inputs": {
"model": "{{huggingFaceInference_LLMs_0.data.instance}}",
- "prompt": "{{promptTemplate_1.data.instance}}",
+ "prompt": "{{promptTemplate_0.data.instance}}",
"chainName": ""
},
"outputAnchors": [
@@ -121,10 +61,10 @@
"type": "LLMChain | BaseChain | BaseLangChain"
},
{
- "id": "llmChain_1-output-outputPrediction-string",
+ "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction",
"label": "Output Prediction",
- "type": "string"
+ "type": "string | json"
}
],
"default": "llmChain"
@@ -144,34 +84,107 @@
},
{
"width": 300,
- "height": 427,
+ "height": 475,
+ "id": "promptTemplate_0",
+ "position": {
+ "x": 506.50436294210306,
+ "y": 504.50766458127396
+ },
+ "type": "customNode",
+ "data": {
+ "id": "promptTemplate_0",
+ "label": "Prompt Template",
+ "name": "promptTemplate",
+ "version": 1,
+ "type": "PromptTemplate",
+ "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
+ "category": "Prompts",
+ "description": "Schema to represent a basic prompt for an LLM",
+ "inputParams": [
+ {
+ "label": "Template",
+ "name": "template",
+ "type": "string",
+ "rows": 4,
+ "placeholder": "What is a good name for a company that makes {product}?",
+ "id": "promptTemplate_0-input-template-string"
+ },
+ {
+ "label": "Format Prompt Values",
+ "name": "promptValues",
+ "type": "json",
+ "optional": true,
+ "acceptVariable": true,
+ "list": true,
+ "id": "promptTemplate_0-input-promptValues-json"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "template": "Question: {question}\n\nAnswer: Let's think step by step.",
+ "promptValues": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "name": "promptTemplate",
+ "label": "PromptTemplate",
+ "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 506.50436294210306,
+ "y": 504.50766458127396
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 526,
"id": "huggingFaceInference_LLMs_0",
"position": {
- "x": 503.5630827259226,
- "y": 50.79125094823999
+ "x": 498.8594464193537,
+ "y": -44.91050256311678
},
"type": "customNode",
"data": {
"id": "huggingFaceInference_LLMs_0",
"label": "HuggingFace Inference",
"name": "huggingFaceInference_LLMs",
+ "version": 1,
"type": "HuggingFaceInference",
- "baseClasses": ["HuggingFaceInference", "LLM", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["HuggingFaceInference", "LLM", "BaseLLM", "BaseLanguageModel"],
"category": "LLMs",
"description": "Wrapper around HuggingFace large language models",
"inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["huggingFaceApi"],
+ "id": "huggingFaceInference_LLMs_0-input-credential-credential"
+ },
{
"label": "Model",
"name": "model",
"type": "string",
+ "description": "If using own inference endpoint, leave this blank",
"placeholder": "gpt2",
+ "optional": true,
"id": "huggingFaceInference_LLMs_0-input-model-string"
},
{
- "label": "HuggingFace Api Key",
- "name": "apiKey",
- "type": "password",
- "id": "huggingFaceInference_LLMs_0-input-apiKey-password"
+ "label": "Endpoint",
+ "name": "endpoint",
+ "type": "string",
+ "placeholder": "https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2",
+ "description": "Using your own inference endpoint",
+ "optional": true,
+ "id": "huggingFaceInference_LLMs_0-input-endpoint-string"
},
{
"label": "Temperature",
@@ -222,18 +235,19 @@
"inputAnchors": [],
"inputs": {
"model": "tiiuae/falcon-7b-instruct",
+ "endpoint": "",
"temperature": "",
- "maxTokens": "200",
+ "maxTokens": "",
"topP": "",
- "hfTopK": "10",
+ "hfTopK": "",
"frequencyPenalty": ""
},
"outputAnchors": [
{
- "id": "huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "id": "huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel",
"name": "huggingFaceInference_LLMs",
"label": "HuggingFaceInference",
- "type": "HuggingFaceInference | LLM | BaseLLM | BaseLanguageModel | BaseLangChain"
+ "type": "HuggingFaceInference | LLM | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
@@ -241,31 +255,31 @@
},
"selected": false,
"positionAbsolute": {
- "x": 503.5630827259226,
- "y": 50.79125094823999
+ "x": 498.8594464193537,
+ "y": -44.91050256311678
},
"dragging": false
}
],
"edges": [
{
- "source": "promptTemplate_1",
- "sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "source": "promptTemplate_0",
+ "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_1",
"targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge",
- "id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
+ "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
},
{
"source": "huggingFaceInference_LLMs_0",
- "sourceHandle": "huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel",
"target": "llmChain_1",
"targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "huggingFaceInference_LLMs_0-huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
+ "id": "huggingFaceInference_LLMs_0-huggingFaceInference_LLMs_0-output-huggingFaceInference_LLMs-HuggingFaceInference|LLM|BaseLLM|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Local QnA.json b/packages/server/marketplaces/chatflows/Local QnA.json
similarity index 97%
rename from packages/server/marketplaces/Local QnA.json
rename to packages/server/marketplaces/chatflows/Local QnA.json
index 9cfba954..9d9f5ec8 100644
--- a/packages/server/marketplaces/Local QnA.json
+++ b/packages/server/marketplaces/chatflows/Local QnA.json
@@ -14,6 +14,7 @@
"id": "recursiveCharacterTextSplitter_1",
"label": "Recursive Character Text Splitter",
"name": "recursiveCharacterTextSplitter",
+ "version": 1,
"type": "RecursiveCharacterTextSplitter",
"baseClasses": ["RecursiveCharacterTextSplitter", "TextSplitter"],
"category": "Text Splitters",
@@ -71,6 +72,7 @@
"id": "conversationalRetrievalQAChain_0",
"label": "Conversational Retrieval QA Chain",
"name": "conversationalRetrievalQAChain",
+ "version": 1,
"type": "ConversationalRetrievalQAChain",
"baseClasses": ["ConversationalRetrievalQAChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -131,11 +133,20 @@
"name": "vectorStoreRetriever",
"type": "BaseRetriever",
"id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
}
],
"inputs": {
"model": "{{chatLocalAI_0.data.instance}}",
- "vectorStoreRetriever": "{{faissUpsert_0.data.instance}}"
+ "vectorStoreRetriever": "{{faissUpsert_0.data.instance}}",
+ "memory": ""
},
"outputAnchors": [
{
@@ -168,6 +179,7 @@
"id": "faissUpsert_0",
"label": "Faiss Upsert Document",
"name": "faissUpsert",
+ "version": 1,
"type": "Faiss",
"baseClasses": ["Faiss", "VectorStoreRetriever", "BaseRetriever"],
"category": "Vector Stores",
@@ -260,6 +272,7 @@
"id": "chatLocalAI_0",
"label": "ChatLocalAI",
"name": "chatLocalAI",
+ "version": 1,
"type": "ChatLocalAI",
"baseClasses": ["ChatLocalAI", "BaseChatModel", "LLM", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
"category": "Chat Models",
@@ -352,6 +365,7 @@
"id": "textFile_0",
"label": "Text File",
"name": "textFile",
+ "version": 1,
"type": "Document",
"baseClasses": ["Document"],
"category": "Document Loaders",
@@ -417,6 +431,7 @@
"id": "localAIEmbeddings_0",
"label": "LocalAI Embeddings",
"name": "localAIEmbeddings",
+ "version": 1,
"type": "LocalAI Embeddings",
"baseClasses": ["LocalAI Embeddings", "Embeddings"],
"category": "Embeddings",
diff --git a/packages/server/marketplaces/chatflows/Long Term Memory.json b/packages/server/marketplaces/chatflows/Long Term Memory.json
new file mode 100644
index 00000000..07669f82
--- /dev/null
+++ b/packages/server/marketplaces/chatflows/Long Term Memory.json
@@ -0,0 +1,647 @@
+{
+ "description": "Use long term memory Zep to differentiate conversations between users with sessionId",
+ "nodes": [
+ {
+ "width": 300,
+ "height": 480,
+ "id": "conversationalRetrievalQAChain_0",
+ "position": {
+ "x": 1999.7302950816731,
+ "y": 365.33064907894243
+ },
+ "type": "customNode",
+ "data": {
+ "id": "conversationalRetrievalQAChain_0",
+ "label": "Conversational Retrieval QA Chain",
+ "name": "conversationalRetrievalQAChain",
+ "version": 1,
+ "type": "ConversationalRetrievalQAChain",
+ "baseClasses": ["ConversationalRetrievalQAChain", "BaseChain", "BaseLangChain"],
+ "category": "Chains",
+ "description": "Document QA - built on RetrievalQAChain to provide a chat history component",
+ "inputParams": [
+ {
+ "label": "Return Source Documents",
+ "name": "returnSourceDocuments",
+ "type": "boolean",
+ "optional": true,
+ "id": "conversationalRetrievalQAChain_0-input-returnSourceDocuments-boolean"
+ },
+ {
+ "label": "System Message",
+ "name": "systemMessagePrompt",
+ "type": "string",
+ "rows": 4,
+ "additionalParams": true,
+ "optional": true,
+ "placeholder": "I want you to act as a document that I am having a conversation with. Your name is \"AI Assistant\". You will provide me with answers from the given info. If the answer is not included, say exactly \"Hmm, I am not sure.\" and stop after that. Refuse to answer any question not about the info. Never break character.",
+ "id": "conversationalRetrievalQAChain_0-input-systemMessagePrompt-string"
+ },
+ {
+ "label": "Chain Option",
+ "name": "chainOption",
+ "type": "options",
+ "options": [
+ {
+ "label": "MapReduceDocumentsChain",
+ "name": "map_reduce",
+ "description": "Suitable for QA tasks over larger documents and can run the preprocessing step in parallel, reducing the running time"
+ },
+ {
+ "label": "RefineDocumentsChain",
+ "name": "refine",
+ "description": "Suitable for QA tasks over a large number of documents."
+ },
+ {
+ "label": "StuffDocumentsChain",
+ "name": "stuff",
+ "description": "Suitable for QA tasks over a small number of documents."
+ }
+ ],
+ "additionalParams": true,
+ "optional": true,
+ "id": "conversationalRetrievalQAChain_0-input-chainOption-options"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Vector Store Retriever",
+ "name": "vectorStoreRetriever",
+ "type": "BaseRetriever",
+ "id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "vectorStoreRetriever": "{{pineconeExistingIndex_0.data.instance}}",
+ "memory": "{{ZepMemory_0.data.instance}}",
+ "returnSourceDocuments": true
+ },
+ "outputAnchors": [
+ {
+ "id": "conversationalRetrievalQAChain_0-output-conversationalRetrievalQAChain-ConversationalRetrievalQAChain|BaseChain|BaseLangChain",
+ "name": "conversationalRetrievalQAChain",
+ "label": "ConversationalRetrievalQAChain",
+ "type": "ConversationalRetrievalQAChain | BaseChain | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1999.7302950816731,
+ "y": 365.33064907894243
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 1554.3875781165111,
+ "y": -14.792508259787212
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": "0",
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1554.3875781165111,
+ "y": -14.792508259787212
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 329,
+ "id": "openAIEmbeddings_0",
+ "position": {
+ "x": 789.6839176356616,
+ "y": 167.70165941305987
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 789.6839176356616,
+ "y": 167.70165941305987
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 505,
+ "id": "pineconeExistingIndex_0",
+ "position": {
+ "x": 1167.128201355349,
+ "y": 71.89355115516406
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeExistingIndex_0",
+ "label": "Pinecone Load Existing Index",
+ "name": "pineconeExistingIndex",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeExistingIndex_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Pinecone Metadata Filter",
+ "name": "pineconeMetadataFilter",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "pineconeMetadataFilter": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "retriever"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1167.128201355349,
+ "y": 71.89355115516406
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 623,
+ "id": "ZepMemory_0",
+ "position": {
+ "x": 1552.2067611642792,
+ "y": 560.8352147865392
+ },
+ "type": "customNode",
+ "data": {
+ "id": "ZepMemory_0",
+ "label": "Zep Memory",
+ "name": "ZepMemory",
+ "version": 1,
+ "type": "ZepMemory",
+ "baseClasses": ["ZepMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Summarizes the conversation and stores the memory in zep server",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "optional": true,
+ "description": "Configure JWT authentication on your Zep instance (Optional)",
+ "credentialNames": ["zepMemoryApi"],
+ "id": "ZepMemory_0-input-credential-credential"
+ },
+ {
+ "label": "Base URL",
+ "name": "baseURL",
+ "type": "string",
+ "default": "http://127.0.0.1:8000",
+ "id": "ZepMemory_0-input-baseURL-string"
+ },
+ {
+ "label": "Auto Summary",
+ "name": "autoSummary",
+ "type": "boolean",
+ "default": true,
+ "id": "ZepMemory_0-input-autoSummary-boolean"
+ },
+ {
+ "label": "Session Id",
+ "name": "sessionId",
+ "type": "string",
+ "description": "if empty, chatId will be used automatically",
+ "default": "",
+ "additionalParams": true,
+ "optional": true,
+ "id": "ZepMemory_0-input-sessionId-string"
+ },
+ {
+ "label": "Size",
+ "name": "k",
+ "type": "number",
+ "default": "10",
+ "step": 1,
+ "description": "Window of size k to surface the last k back-and-forths to use as memory.",
+ "id": "ZepMemory_0-input-k-number"
+ },
+ {
+ "label": "Auto Summary Template",
+ "name": "autoSummaryTemplate",
+ "type": "string",
+ "default": "This is the summary of the following conversation:\n{summary}",
+ "additionalParams": true,
+ "id": "ZepMemory_0-input-autoSummaryTemplate-string"
+ },
+ {
+ "label": "AI Prefix",
+ "name": "aiPrefix",
+ "type": "string",
+ "default": "ai",
+ "additionalParams": true,
+ "id": "ZepMemory_0-input-aiPrefix-string"
+ },
+ {
+ "label": "Human Prefix",
+ "name": "humanPrefix",
+ "type": "string",
+ "default": "human",
+ "additionalParams": true,
+ "id": "ZepMemory_0-input-humanPrefix-string"
+ },
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "additionalParams": true,
+ "id": "ZepMemory_0-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "additionalParams": true,
+ "id": "ZepMemory_0-input-inputKey-string"
+ },
+ {
+ "label": "Output Key",
+ "name": "outputKey",
+ "type": "string",
+ "default": "text",
+ "additionalParams": true,
+ "id": "ZepMemory_0-input-outputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "baseURL": "http://127.0.0.1:8000",
+ "autoSummary": true,
+ "sessionId": "",
+ "k": "10",
+ "autoSummaryTemplate": "This is the summary of the following conversation:\n{summary}",
+ "aiPrefix": "ai",
+ "humanPrefix": "human",
+ "memoryKey": "chat_history",
+ "inputKey": "input",
+ "outputKey": "text"
+ },
+ "outputAnchors": [
+ {
+ "id": "ZepMemory_0-output-ZepMemory-ZepMemory|BaseChatMemory|BaseMemory",
+ "name": "ZepMemory",
+ "label": "ZepMemory",
+ "type": "ZepMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1552.2067611642792,
+ "y": 560.8352147865392
+ },
+ "dragging": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeExistingIndex_0",
+ "targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "pineconeExistingIndex_0",
+ "sourceHandle": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "type": "buttonedge",
+ "id": "pineconeExistingIndex_0-pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "ZepMemory_0",
+ "sourceHandle": "ZepMemory_0-output-ZepMemory-ZepMemory|BaseChatMemory|BaseMemory",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-memory-BaseMemory",
+ "type": "buttonedge",
+ "id": "ZepMemory_0-ZepMemory_0-output-ZepMemory-ZepMemory|BaseChatMemory|BaseMemory-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-memory-BaseMemory",
+ "data": {
+ "label": ""
+ }
+ }
+ ]
+}
diff --git a/packages/server/marketplaces/MRKLAgent.json b/packages/server/marketplaces/chatflows/MRKLAgent.json
similarity index 63%
rename from packages/server/marketplaces/MRKLAgent.json
rename to packages/server/marketplaces/chatflows/MRKLAgent.json
index 257123e0..f851b0ed 100644
--- a/packages/server/marketplaces/MRKLAgent.json
+++ b/packages/server/marketplaces/chatflows/MRKLAgent.json
@@ -1,51 +1,6 @@
{
"description": "An agent that uses the React Framework to decide what action to take",
"nodes": [
- {
- "width": 300,
- "height": 278,
- "id": "serpAPI_1",
- "position": {
- "x": 312.0655985817535,
- "y": 112.09909989842703
- },
- "type": "customNode",
- "data": {
- "id": "serpAPI_1",
- "label": "Serp API",
- "name": "serpAPI",
- "type": "SerpAPI",
- "baseClasses": ["SerpAPI", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Wrapper around SerpAPI - a real-time API to access Google search results",
- "inputParams": [
- {
- "label": "Serp Api Key",
- "name": "apiKey",
- "type": "password",
- "id": "serpAPI_1-input-apiKey-password"
- }
- ],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "serpAPI_1-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
- "name": "serpAPI",
- "label": "SerpAPI",
- "type": "SerpAPI | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 312.0655985817535,
- "y": 112.09909989842703
- },
- "dragging": false
- },
{
"width": 300,
"height": 143,
@@ -59,6 +14,7 @@
"id": "calculator_1",
"label": "Calculator",
"name": "calculator",
+ "version": 1,
"type": "Calculator",
"baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain"],
"category": "Tools",
@@ -84,159 +40,6 @@
"selected": false,
"dragging": false
},
- {
- "width": 300,
- "height": 524,
- "id": "openAI_1",
- "position": {
- "x": 663.1307301893027,
- "y": 394.7618562930441
- },
- "type": "customNode",
- "data": {
- "id": "openAI_1",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": 0.7,
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 663.1307301893027,
- "y": 394.7618562930441
- },
- "dragging": false
- },
{
"width": 300,
"height": 280,
@@ -250,6 +53,7 @@
"id": "mrklAgentLLM_0",
"label": "MRKL Agent for LLMs",
"name": "mrklAgentLLM",
+ "version": 1,
"type": "AgentExecutor",
"baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
"category": "Agents",
@@ -271,8 +75,8 @@
}
],
"inputs": {
- "tools": ["{{calculator_1.data.instance}}", "{{serpAPI_1.data.instance}}"],
- "model": "{{openAI_1.data.instance}}"
+ "tools": ["{{calculator_1.data.instance}}", "{{serper_0.data.instance}}"],
+ "model": "{{chatOpenAI_0.data.instance}}"
},
"outputAnchors": [
{
@@ -291,6 +95,207 @@
"y": 245.36098016819074
},
"dragging": false
+ },
+ {
+ "width": 300,
+ "height": 277,
+ "id": "serper_0",
+ "position": {
+ "x": 330.964079024626,
+ "y": 109.83185250619351
+ },
+ "type": "customNode",
+ "data": {
+ "id": "serper_0",
+ "label": "Serper",
+ "name": "serper",
+ "version": 1,
+ "type": "Serper",
+ "baseClasses": ["Serper", "Tool", "StructuredTool"],
+ "category": "Tools",
+ "description": "Wrapper around Serper.dev - Google Search API",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["serperApi"],
+ "id": "serper_0-input-credential-credential"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {},
+ "outputAnchors": [
+ {
+ "id": "serper_0-output-serper-Serper|Tool|StructuredTool",
+ "name": "serper",
+ "label": "Serper",
+ "type": "Serper | Tool | StructuredTool"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 330.964079024626,
+ "y": 109.83185250619351
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 333.58931284721206,
+ "y": 416.98420974875927
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 333.58931284721206,
+ "y": 416.98420974875927
+ },
+ "dragging": false
}
],
"edges": [
@@ -306,23 +311,23 @@
}
},
{
- "source": "serpAPI_1",
- "sourceHandle": "serpAPI_1-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
+ "source": "serper_0",
+ "sourceHandle": "serper_0-output-serper-Serper|Tool|StructuredTool",
"target": "mrklAgentLLM_0",
"targetHandle": "mrklAgentLLM_0-input-tools-Tool",
"type": "buttonedge",
- "id": "serpAPI_1-serpAPI_1-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain-mrklAgentLLM_0-mrklAgentLLM_0-input-tools-Tool",
+ "id": "serper_0-serper_0-output-serper-Serper|Tool|StructuredTool-mrklAgentLLM_0-mrklAgentLLM_0-input-tools-Tool",
"data": {
"label": ""
}
},
{
- "source": "openAI_1",
- "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "mrklAgentLLM_0",
"targetHandle": "mrklAgentLLM_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-mrklAgentLLM_0-mrklAgentLLM_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-mrklAgentLLM_0-mrklAgentLLM_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Metadata Filter Load.json b/packages/server/marketplaces/chatflows/Metadata Filter Load.json
similarity index 72%
rename from packages/server/marketplaces/Metadata Filter Load.json
rename to packages/server/marketplaces/chatflows/Metadata Filter Load.json
index dfc6d6fb..b6ca91e3 100644
--- a/packages/server/marketplaces/Metadata Filter Load.json
+++ b/packages/server/marketplaces/chatflows/Metadata Filter Load.json
@@ -3,364 +3,18 @@
"nodes": [
{
"width": 300,
- "height": 524,
- "id": "openAI_1",
- "position": {
- "x": 1195.6182217299724,
- "y": -12.958591115085468
- },
- "type": "customNode",
- "data": {
- "id": "openAI_1",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": "0",
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 1195.6182217299724,
- "y": -12.958591115085468
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 330,
- "id": "openAIEmbeddings_1",
- "position": {
- "x": 777.5098693425334,
- "y": 308.4221448953297
- },
- "type": "customNode",
- "data": {
- "id": "openAIEmbeddings_1",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_1-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 777.5098693425334,
- "y": 308.4221448953297
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 703,
- "id": "pineconeExistingIndex_0",
- "position": {
- "x": 1187.519066203033,
- "y": 542.6635399602128
- },
- "type": "customNode",
- "data": {
- "id": "pineconeExistingIndex_0",
- "label": "Pinecone Load Existing Index",
- "name": "pineconeExistingIndex",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeExistingIndex_0-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeExistingIndex_0-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
- },
- {
- "label": "Pinecone Metadata Filter",
- "name": "pineconeMetadataFilter",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "pineconeExistingIndex_0-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_1.data.instance}}",
- "pineconeEnv": "northamerica-northeast1-gcp",
- "pineconeIndex": "myindex",
- "pineconeNamespace": "my-namespace",
- "pineconeMetadataFilter": "{\"id\":\"doc1\"}"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
- "name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "retriever"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1187.519066203033,
- "y": 542.6635399602128
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 280,
+ "height": 480,
"id": "conversationalRetrievalQAChain_0",
"position": {
- "x": 1585.900129303412,
- "y": 405.9784391258126
+ "x": 1643.035168558474,
+ "y": 360.96295365212774
},
"type": "customNode",
"data": {
"id": "conversationalRetrievalQAChain_0",
"label": "Conversational Retrieval QA Chain",
"name": "conversationalRetrievalQAChain",
+ "version": 1,
"type": "ConversationalRetrievalQAChain",
"baseClasses": ["ConversationalRetrievalQAChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -421,10 +75,18 @@
"name": "vectorStoreRetriever",
"type": "BaseRetriever",
"id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
}
],
"inputs": {
- "model": "{{openAI_1.data.instance}}",
+ "model": "{{chatOpenAI_0.data.instance}}",
"vectorStoreRetriever": "{{pineconeExistingIndex_0.data.instance}}"
},
"outputAnchors": [
@@ -440,31 +102,378 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1585.900129303412,
- "y": 405.9784391258126
+ "x": 1643.035168558474,
+ "y": 360.96295365212774
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 1197.7264239788542,
+ "y": -16.177600120515933
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": "0",
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1197.7264239788542,
+ "y": -16.177600120515933
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 329,
+ "id": "openAIEmbeddings_0",
+ "position": {
+ "x": 805.2662010688601,
+ "y": 389.3163571296623
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 805.2662010688601,
+ "y": 389.3163571296623
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 505,
+ "id": "pineconeExistingIndex_0",
+ "position": {
+ "x": 1194.8300385699242,
+ "y": 542.8247838029442
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeExistingIndex_0",
+ "label": "Pinecone Load Existing Index",
+ "name": "pineconeExistingIndex",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeExistingIndex_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Pinecone Metadata Filter",
+ "name": "pineconeMetadataFilter",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "pineconeMetadataFilter": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "retriever"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1194.8300385699242,
+ "y": 542.8247838029442
},
"dragging": false
}
],
"edges": [
{
- "source": "openAIEmbeddings_1",
- "sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
"target": "pineconeExistingIndex_0",
"targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
"type": "buttonedge",
- "id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
"data": {
"label": ""
}
},
{
- "source": "openAI_1",
- "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalRetrievalQAChain_0",
"targetHandle": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Metadata Filter Upsert.json b/packages/server/marketplaces/chatflows/Metadata Filter Upsert.json
similarity index 81%
rename from packages/server/marketplaces/Metadata Filter Upsert.json
rename to packages/server/marketplaces/chatflows/Metadata Filter Upsert.json
index 87336654..e70b11f7 100644
--- a/packages/server/marketplaces/Metadata Filter Upsert.json
+++ b/packages/server/marketplaces/chatflows/Metadata Filter Upsert.json
@@ -14,6 +14,7 @@
"id": "recursiveCharacterTextSplitter_1",
"label": "Recursive Character Text Splitter",
"name": "recursiveCharacterTextSplitter",
+ "version": 1,
"type": "RecursiveCharacterTextSplitter",
"baseClasses": ["RecursiveCharacterTextSplitter", "TextSplitter"],
"category": "Text Splitters",
@@ -58,240 +59,6 @@
},
"dragging": false
},
- {
- "width": 300,
- "height": 524,
- "id": "openAI_1",
- "position": {
- "x": 1159.184721109528,
- "y": -38.76565405456694
- },
- "type": "customNode",
- "data": {
- "id": "openAI_1",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": "0",
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 1159.184721109528,
- "y": -38.76565405456694
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 330,
- "id": "openAIEmbeddings_1",
- "position": {
- "x": 749.4044250705479,
- "y": 858.4858399327618
- },
- "type": "customNode",
- "data": {
- "id": "openAIEmbeddings_1",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_1-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 749.4044250705479,
- "y": 858.4858399327618
- },
- "dragging": false
- },
{
"width": 300,
"height": 392,
@@ -305,6 +72,7 @@
"id": "textFile_0",
"label": "Text File",
"name": "textFile",
+ "version": 1,
"type": "Document",
"baseClasses": ["Document"],
"category": "Document Loaders",
@@ -370,6 +138,7 @@
"id": "pdfFile_0",
"label": "Pdf File",
"name": "pdfFile",
+ "version": 1,
"type": "Document",
"baseClasses": ["Document"],
"category": "Document Loaders",
@@ -442,119 +211,7 @@
},
{
"width": 300,
- "height": 702,
- "id": "pineconeUpsert_0",
- "position": {
- "x": 1161.8813042660154,
- "y": 537.0216614326227
- },
- "type": "customNode",
- "data": {
- "id": "pineconeUpsert_0",
- "label": "Pinecone Upsert Document",
- "name": "pineconeUpsert",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Upsert documents to Pinecone",
- "inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeUpsert_0-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeUpsert_0-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeUpsert_0-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeUpsert_0-input-pineconeNamespace-string"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "pineconeUpsert_0-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Document",
- "name": "document",
- "type": "Document",
- "list": true,
- "id": "pineconeUpsert_0-input-document-Document"
- },
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "pineconeUpsert_0-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "document": ["{{pdfFile_0.data.instance}}", "{{textFile_0.data.instance}}"],
- "embeddings": "{{openAIEmbeddings_1.data.instance}}",
- "pineconeEnv": "northamerica-northeast1-gcp",
- "pineconeIndex": "myindex",
- "pineconeNamespace": "my-namespace"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "pineconeUpsert_0-output-vectorStore-Pinecone|VectorStore",
- "name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "retriever"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1161.8813042660154,
- "y": 537.0216614326227
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 280,
+ "height": 480,
"id": "conversationalRetrievalQAChain_0",
"position": {
"x": 1570.3859788160953,
@@ -565,6 +222,7 @@
"id": "conversationalRetrievalQAChain_0",
"label": "Conversational Retrieval QA Chain",
"name": "conversationalRetrievalQAChain",
+ "version": 1,
"type": "ConversationalRetrievalQAChain",
"baseClasses": ["ConversationalRetrievalQAChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -625,10 +283,18 @@
"name": "vectorStoreRetriever",
"type": "BaseRetriever",
"id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
}
],
"inputs": {
- "model": "{{openAI_1.data.instance}}",
+ "model": "{{chatOpenAI_0.data.instance}}",
"vectorStoreRetriever": "{{pineconeUpsert_0.data.instance}}"
},
"outputAnchors": [
@@ -648,6 +314,352 @@
"y": 423.6687850109136
},
"dragging": false
+ },
+ {
+ "width": 300,
+ "height": 555,
+ "id": "pineconeUpsert_0",
+ "position": {
+ "x": 1161.2426252201622,
+ "y": 549.7917156049002
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeUpsert_0",
+ "label": "Pinecone Upsert Document",
+ "name": "pineconeUpsert",
+ "type": "Pinecone",
+ "version": 1,
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Upsert documents to Pinecone",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeUpsert_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeUpsert_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeUpsert_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeUpsert_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Document",
+ "name": "document",
+ "type": "Document",
+ "list": true,
+ "id": "pineconeUpsert_0-input-document-Document"
+ },
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeUpsert_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "document": ["{{textFile_0.data.instance}}", "{{pdfFile_0.data.instance}}"],
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeUpsert_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "retriever"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1161.2426252201622,
+ "y": 549.7917156049002
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 1164.9667590264419,
+ "y": -44.2076264967032
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": 0.9,
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1164.9667590264419,
+ "y": -44.2076264967032
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 329,
+ "id": "openAIEmbeddings_0",
+ "position": {
+ "x": 772.0706424639393,
+ "y": 862.6189553323906
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 772.0706424639393,
+ "y": 862.6189553323906
+ },
+ "dragging": false
}
],
"edges": [
@@ -674,23 +686,12 @@
}
},
{
- "source": "openAIEmbeddings_1",
- "sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
"target": "pineconeUpsert_0",
"targetHandle": "pineconeUpsert_0-input-embeddings-Embeddings",
"type": "buttonedge",
- "id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_0-pineconeUpsert_0-input-embeddings-Embeddings",
- "data": {
- "label": ""
- }
- },
- {
- "source": "pdfFile_0",
- "sourceHandle": "pdfFile_0-output-pdfFile-Document",
- "target": "pineconeUpsert_0",
- "targetHandle": "pineconeUpsert_0-input-document-Document",
- "type": "buttonedge",
- "id": "pdfFile_0-pdfFile_0-output-pdfFile-Document-pineconeUpsert_0-pineconeUpsert_0-input-document-Document",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_0-pineconeUpsert_0-input-embeddings-Embeddings",
"data": {
"label": ""
}
@@ -707,12 +708,23 @@
}
},
{
- "source": "openAI_1",
- "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "source": "pdfFile_0",
+ "sourceHandle": "pdfFile_0-output-pdfFile-Document",
+ "target": "pineconeUpsert_0",
+ "targetHandle": "pineconeUpsert_0-input-document-Document",
+ "type": "buttonedge",
+ "id": "pdfFile_0-pdfFile_0-output-pdfFile-Document-pineconeUpsert_0-pineconeUpsert_0-input-document-Document",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationalRetrievalQAChain_0",
"targetHandle": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Multi Prompt Chain.json b/packages/server/marketplaces/chatflows/Multi Prompt Chain.json
similarity index 95%
rename from packages/server/marketplaces/Multi Prompt Chain.json
rename to packages/server/marketplaces/chatflows/Multi Prompt Chain.json
index 339476e7..cf86df5b 100644
--- a/packages/server/marketplaces/Multi Prompt Chain.json
+++ b/packages/server/marketplaces/chatflows/Multi Prompt Chain.json
@@ -14,6 +14,7 @@
"id": "promptRetriever_0",
"label": "Prompt Retriever",
"name": "promptRetriever",
+ "version": 1,
"type": "PromptRetriever",
"baseClasses": ["PromptRetriever"],
"category": "Retrievers",
@@ -81,6 +82,7 @@
"id": "multiPromptChain_0",
"label": "Multi Prompt Chain",
"name": "multiPromptChain",
+ "version": 1,
"type": "MultiPromptChain",
"baseClasses": ["MultiPromptChain", "MultiRouteChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -140,6 +142,7 @@
"id": "promptRetriever_1",
"label": "Prompt Retriever",
"name": "promptRetriever",
+ "version": 1,
"type": "PromptRetriever",
"baseClasses": ["PromptRetriever"],
"category": "Retrievers",
@@ -207,6 +210,7 @@
"id": "promptRetriever_2",
"label": "Prompt Retriever",
"name": "promptRetriever",
+ "version": 1,
"type": "PromptRetriever",
"baseClasses": ["PromptRetriever"],
"category": "Retrievers",
@@ -263,27 +267,29 @@
},
{
"width": 300,
- "height": 524,
+ "height": 523,
"id": "chatOpenAI_0",
"position": {
- "x": 1230.07368145571,
- "y": -296.44522826934826
+ "x": 1228.4059611466973,
+ "y": -326.46419383157513
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -392,14 +398,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -407,8 +414,8 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1230.07368145571,
- "y": -296.44522826934826
+ "x": 1228.4059611466973,
+ "y": -326.46419383157513
},
"dragging": false
}
@@ -449,11 +456,11 @@
},
{
"source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "multiPromptChain_0",
"targetHandle": "multiPromptChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-multiPromptChain_0-multiPromptChain_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-multiPromptChain_0-multiPromptChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Multi Retrieval QA Chain.json b/packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json
similarity index 92%
rename from packages/server/marketplaces/Multi Retrieval QA Chain.json
rename to packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json
index 04df2fee..f5604bf6 100644
--- a/packages/server/marketplaces/Multi Retrieval QA Chain.json
+++ b/packages/server/marketplaces/chatflows/Multi Retrieval QA Chain.json
@@ -3,7 +3,7 @@
"nodes": [
{
"width": 300,
- "height": 504,
+ "height": 505,
"id": "vectorStoreRetriever_0",
"position": {
"x": 712.9322670298264,
@@ -14,6 +14,7 @@
"id": "vectorStoreRetriever_0",
"label": "Vector Store Retriever",
"name": "vectorStoreRetriever",
+ "version": 1,
"type": "VectorStoreRetriever",
"baseClasses": ["VectorStoreRetriever"],
"category": "Retrievers",
@@ -69,7 +70,7 @@
},
{
"width": 300,
- "height": 279,
+ "height": 377,
"id": "multiRetrievalQAChain_0",
"position": {
"x": 1563.0150452201099,
@@ -80,6 +81,7 @@
"id": "multiRetrievalQAChain_0",
"label": "Multi Retrieval QA Chain",
"name": "multiRetrievalQAChain",
+ "version": 1,
"type": "MultiRetrievalQAChain",
"baseClasses": ["MultiRetrievalQAChain", "MultiRouteChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -135,7 +137,7 @@
},
{
"width": 300,
- "height": 504,
+ "height": 505,
"id": "vectorStoreRetriever_1",
"position": {
"x": 711.4902931206071,
@@ -146,6 +148,7 @@
"id": "vectorStoreRetriever_1",
"label": "Vector Store Retriever",
"name": "vectorStoreRetriever",
+ "version": 1,
"type": "VectorStoreRetriever",
"baseClasses": ["VectorStoreRetriever"],
"category": "Retrievers",
@@ -201,7 +204,7 @@
},
{
"width": 300,
- "height": 504,
+ "height": 505,
"id": "vectorStoreRetriever_2",
"position": {
"x": 706.0716220151372,
@@ -212,6 +215,7 @@
"id": "vectorStoreRetriever_2",
"label": "Vector Store Retriever",
"name": "vectorStoreRetriever",
+ "version": 1,
"type": "VectorStoreRetriever",
"baseClasses": ["VectorStoreRetriever"],
"category": "Retrievers",
@@ -265,29 +269,428 @@
},
"dragging": false
},
+ {
+ "width": 300,
+ "height": 505,
+ "id": "pineconeExistingIndex_0",
+ "position": {
+ "x": 267.45589163840236,
+ "y": -300.13817634747346
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeExistingIndex_0",
+ "label": "Pinecone Load Existing Index",
+ "name": "pineconeExistingIndex",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeExistingIndex_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Pinecone Metadata Filter",
+ "name": "pineconeMetadataFilter",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "pineconeMetadataFilter": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "vectorStore"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 267.45589163840236,
+ "y": -300.13817634747346
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 506,
+ "id": "chromaExistingIndex_0",
+ "position": {
+ "x": 264.5271545331116,
+ "y": 246.32716342844174
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chromaExistingIndex_0",
+ "label": "Chroma Load Existing Index",
+ "name": "chromaExistingIndex",
+ "version": 1,
+ "type": "Chroma",
+ "baseClasses": ["Chroma", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Chroma (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Collection Name",
+ "name": "collectionName",
+ "type": "string",
+ "id": "chromaExistingIndex_0-input-collectionName-string"
+ },
+ {
+ "label": "Chroma URL",
+ "name": "chromaURL",
+ "type": "string",
+ "optional": true,
+ "id": "chromaExistingIndex_0-input-chromaURL-string"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "chromaExistingIndex_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "chromaExistingIndex_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "collectionName": "",
+ "chromaURL": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "chromaExistingIndex_0-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Chroma Retriever",
+ "type": "Chroma | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "chromaExistingIndex_0-output-vectorStore-Chroma|VectorStore",
+ "name": "vectorStore",
+ "label": "Chroma Vector Store",
+ "type": "Chroma | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "vectorStore"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 264.5271545331116,
+ "y": 246.32716342844174
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 329,
+ "id": "openAIEmbeddings_0",
+ "position": {
+ "x": -212.46977797044045,
+ "y": 252.45726960585722
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": -212.46977797044045,
+ "y": 252.45726960585722
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 702,
+ "id": "supabaseExistingIndex_0",
+ "position": {
+ "x": 270.90499551102573,
+ "y": 783.5053782099461
+ },
+ "type": "customNode",
+ "data": {
+ "id": "supabaseExistingIndex_0",
+ "label": "Supabase Load Existing Index",
+ "name": "supabaseExistingIndex",
+ "version": 1,
+ "type": "Supabase",
+ "baseClasses": ["Supabase", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Supabase (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["supabaseApi"],
+ "id": "supabaseExistingIndex_0-input-credential-credential"
+ },
+ {
+ "label": "Supabase Project URL",
+ "name": "supabaseProjUrl",
+ "type": "string",
+ "id": "supabaseExistingIndex_0-input-supabaseProjUrl-string"
+ },
+ {
+ "label": "Table Name",
+ "name": "tableName",
+ "type": "string",
+ "id": "supabaseExistingIndex_0-input-tableName-string"
+ },
+ {
+ "label": "Query Name",
+ "name": "queryName",
+ "type": "string",
+ "id": "supabaseExistingIndex_0-input-queryName-string"
+ },
+ {
+ "label": "Supabase Metadata Filter",
+ "name": "supabaseMetadataFilter",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "supabaseExistingIndex_0-input-supabaseMetadataFilter-json"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "supabaseExistingIndex_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "supabaseExistingIndex_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "supabaseProjUrl": "",
+ "tableName": "",
+ "queryName": "",
+ "supabaseMetadataFilter": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "supabaseExistingIndex_0-output-retriever-Supabase|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Supabase Retriever",
+ "type": "Supabase | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "supabaseExistingIndex_0-output-vectorStore-Supabase|VectorStore",
+ "name": "vectorStore",
+ "label": "Supabase Vector Store",
+ "type": "Supabase | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "vectorStore"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 270.90499551102573,
+ "y": 783.5053782099461
+ },
+ "dragging": false
+ },
{
"width": 300,
"height": 523,
"id": "chatOpenAI_0",
"position": {
- "x": 1206.027762600755,
- "y": -212.35338654620222
+ "x": 1154.0989175770958,
+ "y": -255.77769163789395
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -396,14 +799,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -411,401 +815,8 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1206.027762600755,
- "y": -212.35338654620222
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 329,
- "id": "openAIEmbeddings_0",
- "position": {
- "x": -254.88737984323413,
- "y": 279.72801937636154
- },
- "type": "customNode",
- "data": {
- "id": "openAIEmbeddings_0",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_0-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_0-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_0-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_0-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": -254.88737984323413,
- "y": 279.72801937636154
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 603,
- "id": "pineconeExistingIndex_0",
- "position": {
- "x": 271.2513182410521,
- "y": -410.32709109501735
- },
- "type": "customNode",
- "data": {
- "id": "pineconeExistingIndex_0",
- "label": "Pinecone Load Existing Index",
- "name": "pineconeExistingIndex",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeExistingIndex_0-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeExistingIndex_0-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
- },
- {
- "label": "Pinecone Metadata Filter",
- "name": "pineconeMetadataFilter",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "pineconeExistingIndex_0-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_0.data.instance}}",
- "pineconeEnv": "",
- "pineconeIndex": "",
- "pineconeNamespace": "",
- "pineconeMetadataFilter": ""
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
- "name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "vectorStore"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 271.2513182410521,
- "y": -410.32709109501735
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 505,
- "id": "chromaExistingIndex_0",
- "position": {
- "x": 269.2940530300552,
- "y": 262.41814510537796
- },
- "type": "customNode",
- "data": {
- "id": "chromaExistingIndex_0",
- "label": "Chroma Load Existing Index",
- "name": "chromaExistingIndex",
- "type": "Chroma",
- "baseClasses": ["Chroma", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Chroma (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Collection Name",
- "name": "collectionName",
- "type": "string",
- "id": "chromaExistingIndex_0-input-collectionName-string"
- },
- {
- "label": "Chroma URL",
- "name": "chromaURL",
- "type": "string",
- "optional": true,
- "id": "chromaExistingIndex_0-input-chromaURL-string"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "chromaExistingIndex_0-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "chromaExistingIndex_0-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_0.data.instance}}",
- "collectionName": "",
- "chromaURL": ""
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "chromaExistingIndex_0-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Chroma Retriever",
- "type": "Chroma | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "chromaExistingIndex_0-output-vectorStore-Chroma|VectorStore",
- "name": "vectorStore",
- "label": "Chroma Vector Store",
- "type": "Chroma | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "vectorStore"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 269.2940530300552,
- "y": 262.41814510537796
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 702,
- "id": "supabaseExistingIndex_0",
- "position": {
- "x": 273.7097153973373,
- "y": 821.872758974335
- },
- "type": "customNode",
- "data": {
- "id": "supabaseExistingIndex_0",
- "label": "Supabase Load Existing Index",
- "name": "supabaseExistingIndex",
- "type": "Supabase",
- "baseClasses": ["Supabase", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Supabase (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Supabase API Key",
- "name": "supabaseApiKey",
- "type": "password",
- "id": "supabaseExistingIndex_0-input-supabaseApiKey-password"
- },
- {
- "label": "Supabase Project URL",
- "name": "supabaseProjUrl",
- "type": "string",
- "id": "supabaseExistingIndex_0-input-supabaseProjUrl-string"
- },
- {
- "label": "Table Name",
- "name": "tableName",
- "type": "string",
- "id": "supabaseExistingIndex_0-input-tableName-string"
- },
- {
- "label": "Query Name",
- "name": "queryName",
- "type": "string",
- "id": "supabaseExistingIndex_0-input-queryName-string"
- },
- {
- "label": "Supabase Metadata Filter",
- "name": "supabaseMetadataFilter",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "supabaseExistingIndex_0-input-supabaseMetadataFilter-json"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "supabaseExistingIndex_0-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "supabaseExistingIndex_0-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_0.data.instance}}",
- "supabaseProjUrl": "",
- "tableName": "",
- "queryName": "",
- "supabaseMetadataFilter": ""
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "supabaseExistingIndex_0-output-retriever-Supabase|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Supabase Retriever",
- "type": "Supabase | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "supabaseExistingIndex_0-output-vectorStore-Supabase|VectorStore",
- "name": "vectorStore",
- "label": "Supabase Vector Store",
- "type": "Supabase | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "vectorStore"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 273.7097153973373,
- "y": 821.872758974335
+ "x": 1154.0989175770958,
+ "y": -255.77769163789395
},
"dragging": false
}
@@ -844,17 +855,6 @@
"label": ""
}
},
- {
- "source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "multiRetrievalQAChain_0",
- "targetHandle": "multiRetrievalQAChain_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-multiRetrievalQAChain_0-multiRetrievalQAChain_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
{
"source": "pineconeExistingIndex_0",
"sourceHandle": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
@@ -866,17 +866,6 @@
"label": ""
}
},
- {
- "source": "openAIEmbeddings_0",
- "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "pineconeExistingIndex_0",
- "targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
- "type": "buttonedge",
- "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
- "data": {
- "label": ""
- }
- },
{
"source": "chromaExistingIndex_0",
"sourceHandle": "chromaExistingIndex_0-output-vectorStore-Chroma|VectorStore",
@@ -888,6 +877,17 @@
"label": ""
}
},
+ {
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeExistingIndex_0",
+ "targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "data": {
+ "label": ""
+ }
+ },
{
"source": "openAIEmbeddings_0",
"sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
@@ -920,6 +920,17 @@
"data": {
"label": ""
}
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "multiRetrievalQAChain_0",
+ "targetHandle": "multiRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-multiRetrievalQAChain_0-multiRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
}
]
}
diff --git a/packages/server/marketplaces/Multiple VectorDB.json b/packages/server/marketplaces/chatflows/Multiple VectorDB.json
similarity index 79%
rename from packages/server/marketplaces/Multiple VectorDB.json
rename to packages/server/marketplaces/chatflows/Multiple VectorDB.json
index 05f7ca5e..101a683b 100644
--- a/packages/server/marketplaces/Multiple VectorDB.json
+++ b/packages/server/marketplaces/chatflows/Multiple VectorDB.json
@@ -3,27 +3,674 @@
"nodes": [
{
"width": 300,
- "height": 329,
- "id": "openAIEmbeddings_2",
+ "height": 602,
+ "id": "chainTool_2",
"position": {
- "x": 155.07832615625986,
- "y": -778.383353751991
+ "x": 1251.240972921597,
+ "y": -922.9180420195128
},
"type": "customNode",
"data": {
- "id": "openAIEmbeddings_2",
+ "id": "chainTool_2",
+ "label": "Chain Tool",
+ "name": "chainTool",
+ "version": 1,
+ "type": "ChainTool",
+ "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Use a chain as allowed tool for agent",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "name",
+ "type": "string",
+ "placeholder": "state-of-union-qa",
+ "id": "chainTool_2-input-name-string"
+ },
+ {
+ "label": "Chain Description",
+ "name": "description",
+ "type": "string",
+ "rows": 3,
+ "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
+ "id": "chainTool_2-input-description-string"
+ },
+ {
+ "label": "Return Direct",
+ "name": "returnDirect",
+ "type": "boolean",
+ "optional": true,
+ "id": "chainTool_2-input-returnDirect-boolean"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Base Chain",
+ "name": "baseChain",
+ "type": "BaseChain",
+ "id": "chainTool_2-input-baseChain-BaseChain"
+ }
+ ],
+ "inputs": {
+ "name": "ai-paper-qa",
+ "description": "AI Paper QA - useful for when you need to ask questions about the AI-Generated Content paper.",
+ "returnDirect": "",
+ "baseChain": "{{retrievalQAChain_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "chainTool_2-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
+ "name": "chainTool",
+ "label": "ChainTool",
+ "type": "ChainTool | DynamicTool | Tool | StructuredTool | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1251.240972921597,
+ "y": -922.9180420195128
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 602,
+ "id": "chainTool_3",
+ "position": {
+ "x": 1267.7142132085273,
+ "y": -85.7749282485849
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chainTool_3",
+ "label": "Chain Tool",
+ "name": "chainTool",
+ "version": 1,
+ "type": "ChainTool",
+ "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Use a chain as allowed tool for agent",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "name",
+ "type": "string",
+ "placeholder": "state-of-union-qa",
+ "id": "chainTool_3-input-name-string"
+ },
+ {
+ "label": "Chain Description",
+ "name": "description",
+ "type": "string",
+ "rows": 3,
+ "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
+ "id": "chainTool_3-input-description-string"
+ },
+ {
+ "label": "Return Direct",
+ "name": "returnDirect",
+ "type": "boolean",
+ "optional": true,
+ "id": "chainTool_3-input-returnDirect-boolean"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Base Chain",
+ "name": "baseChain",
+ "type": "BaseChain",
+ "id": "chainTool_3-input-baseChain-BaseChain"
+ }
+ ],
+ "inputs": {
+ "name": "state-of-union-qa",
+ "description": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
+ "returnDirect": "",
+ "baseChain": "{{retrievalQAChain_1.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "chainTool_3-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
+ "name": "chainTool",
+ "label": "ChainTool",
+ "type": "ChainTool | DynamicTool | Tool | StructuredTool | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "dragging": false,
+ "positionAbsolute": {
+ "x": 1267.7142132085273,
+ "y": -85.7749282485849
+ }
+ },
+ {
+ "width": 300,
+ "height": 280,
+ "id": "mrklAgentLLM_0",
+ "position": {
+ "x": 2061.891333395338,
+ "y": -140.0694021759809
+ },
+ "type": "customNode",
+ "data": {
+ "id": "mrklAgentLLM_0",
+ "label": "MRKL Agent for LLMs",
+ "name": "mrklAgentLLM",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
+ "category": "Agents",
+ "description": "Agent that uses the ReAct Framework to decide what action to take, optimized to be used with LLMs",
+ "inputParams": [],
+ "inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "mrklAgentLLM_0-input-tools-Tool"
+ },
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "mrklAgentLLM_0-input-model-BaseLanguageModel"
+ }
+ ],
+ "inputs": {
+ "tools": ["{{chainTool_2.data.instance}}", "{{chainTool_3.data.instance}}"],
+ "model": "{{openAI_4.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "mrklAgentLLM_0-output-mrklAgentLLM-AgentExecutor|BaseChain|BaseLangChain",
+ "name": "mrklAgentLLM",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 2061.891333395338,
+ "y": -140.0694021759809
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 280,
+ "id": "retrievalQAChain_0",
+ "position": {
+ "x": 898.1253096948574,
+ "y": -859.1174013418433
+ },
+ "type": "customNode",
+ "data": {
+ "id": "retrievalQAChain_0",
+ "label": "Retrieval QA Chain",
+ "name": "retrievalQAChain",
+ "version": 1,
+ "type": "RetrievalQAChain",
+ "baseClasses": ["RetrievalQAChain", "BaseChain", "BaseLangChain"],
+ "category": "Chains",
+ "description": "QA chain to answer a question based on the retrieved documents",
+ "inputParams": [],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "retrievalQAChain_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Vector Store Retriever",
+ "name": "vectorStoreRetriever",
+ "type": "BaseRetriever",
+ "id": "retrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ }
+ ],
+ "inputs": {
+ "model": "{{openAI_2.data.instance}}",
+ "vectorStoreRetriever": "{{chromaExistingIndex_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "retrievalQAChain_0-output-retrievalQAChain-RetrievalQAChain|BaseChain|BaseLangChain",
+ "name": "retrievalQAChain",
+ "label": "RetrievalQAChain",
+ "type": "RetrievalQAChain | BaseChain | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 898.1253096948574,
+ "y": -859.1174013418433
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 280,
+ "id": "retrievalQAChain_1",
+ "position": {
+ "x": 895.4349543765911,
+ "y": 166.60331503487222
+ },
+ "type": "customNode",
+ "data": {
+ "id": "retrievalQAChain_1",
+ "label": "Retrieval QA Chain",
+ "name": "retrievalQAChain",
+ "version": 1,
+ "type": "RetrievalQAChain",
+ "baseClasses": ["RetrievalQAChain", "BaseChain", "BaseLangChain"],
+ "category": "Chains",
+ "description": "QA chain to answer a question based on the retrieved documents",
+ "inputParams": [],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "retrievalQAChain_1-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Vector Store Retriever",
+ "name": "vectorStoreRetriever",
+ "type": "BaseRetriever",
+ "id": "retrievalQAChain_1-input-vectorStoreRetriever-BaseRetriever"
+ }
+ ],
+ "inputs": {
+ "model": "{{openAI_3.data.instance}}",
+ "vectorStoreRetriever": "{{pineconeExistingIndex_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "retrievalQAChain_1-output-retrievalQAChain-RetrievalQAChain|BaseChain|BaseLangChain",
+ "name": "retrievalQAChain",
+ "label": "RetrievalQAChain",
+ "type": "RetrievalQAChain | BaseChain | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 895.4349543765911,
+ "y": 166.60331503487222
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "openAI_2",
+ "position": {
+ "x": 520.8471510168988,
+ "y": -1282.1183473852964
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAI_2",
+ "label": "OpenAI",
+ "name": "openAI",
+ "version": 1,
+ "type": "OpenAI",
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
+ "category": "LLMs",
+ "description": "Wrapper around OpenAI large language models",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_2-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "text-davinci-003",
+ "name": "text-davinci-003"
+ },
+ {
+ "label": "text-davinci-002",
+ "name": "text-davinci-002"
+ },
+ {
+ "label": "text-curie-001",
+ "name": "text-curie-001"
+ },
+ {
+ "label": "text-babbage-001",
+ "name": "text-babbage-001"
+ }
+ ],
+ "default": "text-davinci-003",
+ "optional": true,
+ "id": "openAI_2-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.7,
+ "optional": true,
+ "id": "openAI_2-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-topP-number"
+ },
+ {
+ "label": "Best Of",
+ "name": "bestOf",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-bestOf-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-presencePenalty-number"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_2-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "text-davinci-003",
+ "temperature": 0.7,
+ "maxTokens": "",
+ "topP": "",
+ "bestOf": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "name": "openAI",
+ "label": "OpenAI",
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 520.8471510168988,
+ "y": -1282.1183473852964
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 329,
+ "id": "openAIEmbeddings_1",
+ "position": {
+ "x": 148.65789308409916,
+ "y": -915.1982675859331
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_1",
"label": "OpenAI Embeddings",
"name": "openAIEmbeddings",
+ "version": 1,
"type": "OpenAIEmbeddings",
"baseClasses": ["OpenAIEmbeddings", "Embeddings"],
"category": "Embeddings",
"description": "OpenAI API to generate embeddings for a given text",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_2-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_1-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_1-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_1-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_1-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_1-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 148.65789308409916,
+ "y": -915.1982675859331
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 506,
+ "id": "chromaExistingIndex_0",
+ "position": {
+ "x": 509.55198017578016,
+ "y": -732.42003311752
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chromaExistingIndex_0",
+ "label": "Chroma Load Existing Index",
+ "name": "chromaExistingIndex",
+ "version": 1,
+ "type": "Chroma",
+ "baseClasses": ["Chroma", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Chroma (i.e: Document has been upserted)",
+ "inputParams": [
+ {
+ "label": "Collection Name",
+ "name": "collectionName",
+ "type": "string",
+ "id": "chromaExistingIndex_0-input-collectionName-string"
+ },
+ {
+ "label": "Chroma URL",
+ "name": "chromaURL",
+ "type": "string",
+ "optional": true,
+ "id": "chromaExistingIndex_0-input-chromaURL-string"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "chromaExistingIndex_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "chromaExistingIndex_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "embeddings": "{{openAIEmbeddings_1.data.instance}}",
+ "collectionName": "",
+ "chromaURL": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "chromaExistingIndex_0-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Chroma Retriever",
+ "type": "Chroma | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "chromaExistingIndex_0-output-vectorStore-Chroma|VectorStore",
+ "name": "vectorStore",
+ "label": "Chroma Vector Store",
+ "type": "Chroma | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "retriever"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 509.55198017578016,
+ "y": -732.42003311752
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 329,
+ "id": "openAIEmbeddings_2",
+ "position": {
+ "x": 128.85404348918783,
+ "y": 155.96043384682295
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_2",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_2-input-credential-credential"
},
{
"label": "Strip New Lines",
@@ -62,7 +709,8 @@
"inputs": {
"stripNewLines": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
@@ -77,122 +725,36 @@
},
"selected": false,
"positionAbsolute": {
- "x": 155.07832615625986,
- "y": -778.383353751991
+ "x": 128.85404348918783,
+ "y": 155.96043384682295
},
"dragging": false
},
- {
- "width": 300,
- "height": 505,
- "id": "chromaExistingIndex_1",
- "position": {
- "x": 522.8177328694987,
- "y": -723.8834555183237
- },
- "type": "customNode",
- "data": {
- "id": "chromaExistingIndex_1",
- "label": "Chroma Load Existing Index",
- "name": "chromaExistingIndex",
- "type": "Chroma",
- "baseClasses": ["Chroma", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Chroma (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Collection Name",
- "name": "collectionName",
- "type": "string",
- "id": "chromaExistingIndex_1-input-collectionName-string"
- },
- {
- "label": "Chroma URL",
- "name": "chromaURL",
- "type": "string",
- "optional": true,
- "id": "chromaExistingIndex_1-input-chromaURL-string"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "chromaExistingIndex_1-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "chromaExistingIndex_1-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_2.data.instance}}",
- "collectionName": "ai-paper"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "chromaExistingIndex_1-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Chroma Retriever",
- "type": "Chroma | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "chromaExistingIndex_1-output-vectorStore-Chroma|VectorStore",
- "name": "vectorStore",
- "label": "Chroma Vector Store",
- "type": "Chroma | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "retriever"
- },
- "selected": false
- },
- "positionAbsolute": {
- "x": 522.8177328694987,
- "y": -723.8834555183237
- },
- "selected": false,
- "dragging": false
- },
{
"width": 300,
"height": 523,
"id": "openAI_3",
"position": {
- "x": 527.7101375911075,
- "y": -1290.6752949922043
+ "x": 504.808358369027,
+ "y": -197.78194663790197
},
"type": "customNode",
"data": {
"id": "openAI_3",
"label": "OpenAI",
"name": "openAI",
+ "version": 1,
"type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
"category": "LLMs",
"description": "Wrapper around OpenAI large language models",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_3-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_3-input-credential-credential"
},
{
"label": "Model Name",
@@ -303,260 +865,133 @@
"frequencyPenalty": "",
"presencePenalty": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "id": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"name": "openAI",
"label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
"selected": false
},
- "positionAbsolute": {
- "x": 527.7101375911075,
- "y": -1290.6752949922043
- },
"selected": false,
+ "positionAbsolute": {
+ "x": 504.808358369027,
+ "y": -197.78194663790197
+ },
"dragging": false
},
{
"width": 300,
- "height": 601,
- "id": "chainTool_2",
+ "height": 505,
+ "id": "pineconeExistingIndex_0",
"position": {
- "x": 1251.240972921597,
- "y": -922.9180420195128
+ "x": 507.5206146177215,
+ "y": 343.07818128024616
},
"type": "customNode",
"data": {
- "id": "chainTool_2",
- "label": "Chain Tool",
- "name": "chainTool",
- "type": "ChainTool",
- "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Use a chain as allowed tool for agent",
+ "id": "pineconeExistingIndex_0",
+ "label": "Pinecone Load Existing Index",
+ "name": "pineconeExistingIndex",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
"inputParams": [
{
- "label": "Chain Name",
- "name": "name",
- "type": "string",
- "placeholder": "state-of-union-qa",
- "id": "chainTool_2-input-name-string"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeExistingIndex_0-input-credential-credential"
},
{
- "label": "Chain Description",
- "name": "description",
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
"type": "string",
- "rows": 3,
- "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
- "id": "chainTool_2-input-description-string"
+ "id": "pineconeExistingIndex_0-input-pineconeIndex-string"
},
{
- "label": "Return Direct",
- "name": "returnDirect",
- "type": "boolean",
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
"optional": true,
- "id": "chainTool_2-input-returnDirect-boolean"
+ "id": "pineconeExistingIndex_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Pinecone Metadata Filter",
+ "name": "pineconeMetadataFilter",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "pineconeExistingIndex_0-input-pineconeMetadataFilter-json"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeExistingIndex_0-input-topK-number"
}
],
"inputAnchors": [
{
- "label": "Base Chain",
- "name": "baseChain",
- "type": "BaseChain",
- "id": "chainTool_2-input-baseChain-BaseChain"
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeExistingIndex_0-input-embeddings-Embeddings"
}
],
"inputs": {
- "name": "ai-paper-qa",
- "description": "AI Paper QA - useful for when you need to ask questions about the AI-Generated Content paper.",
- "returnDirect": "",
- "baseChain": "{{retrievalQAChain_0.data.instance}}"
+ "embeddings": "{{openAIEmbeddings_2.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "pineconeMetadataFilter": "",
+ "topK": ""
},
"outputAnchors": [
{
- "id": "chainTool_2-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
- "name": "chainTool",
- "label": "ChainTool",
- "type": "ChainTool | DynamicTool | Tool | StructuredTool | BaseLangChain"
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeExistingIndex_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
}
],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1251.240972921597,
- "y": -922.9180420195128
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 142,
- "id": "calculator_1",
- "position": {
- "x": 1649.5389102641816,
- "y": -835.8729983638877
- },
- "type": "customNode",
- "data": {
- "id": "calculator_1",
- "label": "Calculator",
- "name": "calculator",
- "type": "Calculator",
- "baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Perform calculations on response",
- "inputParams": [],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "calculator_1-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain",
- "name": "calculator",
- "label": "Calculator",
- "type": "Calculator | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 1649.5389102641816,
- "y": -835.8729983638877
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 277,
- "id": "serpAPI_0",
- "position": {
- "x": 1654.5273488033688,
- "y": -622.1607096176143
- },
- "type": "customNode",
- "data": {
- "id": "serpAPI_0",
- "label": "Serp API",
- "name": "serpAPI",
- "type": "SerpAPI",
- "baseClasses": ["SerpAPI", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Wrapper around SerpAPI - a real-time API to access Google search results",
- "inputParams": [
- {
- "label": "Serp Api Key",
- "name": "apiKey",
- "type": "password",
- "id": "serpAPI_0-input-apiKey-password"
- }
- ],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
- "name": "serpAPI",
- "label": "SerpAPI",
- "type": "SerpAPI | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1654.5273488033688,
- "y": -622.1607096176143
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 329,
- "id": "openAIEmbeddings_3",
- "position": {
- "x": 163.902196956619,
- "y": 318.66096921035574
- },
- "type": "customNode",
- "data": {
- "id": "openAIEmbeddings_3",
- "label": "OpenAI Embeddings",
- "name": "openAIEmbeddings",
- "type": "OpenAIEmbeddings",
- "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
- "category": "Embeddings",
- "description": "OpenAI API to generate embeddings for a given text",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_3-input-openAIApiKey-password"
- },
- {
- "label": "Strip New Lines",
- "name": "stripNewLines",
- "type": "boolean",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_3-input-stripNewLines-boolean"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_3-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_3-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAIEmbeddings_3-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "stripNewLines": "",
- "batchSize": "",
- "timeout": ""
+ "outputs": {
+ "output": "retriever"
},
- "outputAnchors": [
- {
- "id": "openAIEmbeddings_3-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "name": "openAIEmbeddings",
- "label": "OpenAIEmbeddings",
- "type": "OpenAIEmbeddings | Embeddings"
- }
- ],
- "outputs": {},
"selected": false
},
"selected": false,
"positionAbsolute": {
- "x": 163.902196956619,
- "y": 318.66096921035574
+ "x": 507.5206146177215,
+ "y": 343.07818128024616
},
"dragging": false
},
@@ -565,24 +1000,26 @@
"height": 523,
"id": "openAI_4",
"position": {
- "x": 529.8870809493459,
- "y": -137.8839994127831
+ "x": 1619.5346765785587,
+ "y": 292.29615581180684
},
"type": "customNode",
"data": {
"id": "openAI_4",
"label": "OpenAI",
"name": "openAI",
+ "version": 1,
"type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
"category": "LLMs",
"description": "Wrapper around OpenAI large language models",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_4-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_4-input-credential-credential"
},
{
"label": "Model Name",
@@ -693,412 +1130,15 @@
"frequencyPenalty": "",
"presencePenalty": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "openAI_4-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "id": "openAI_4-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"name": "openAI",
"label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 529.8870809493459,
- "y": -137.8839994127831
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 603,
- "id": "pineconeExistingIndex_1",
- "position": {
- "x": 525.6644489497978,
- "y": 420.1233379157454
- },
- "type": "customNode",
- "data": {
- "id": "pineconeExistingIndex_1",
- "label": "Pinecone Load Existing Index",
- "name": "pineconeExistingIndex",
- "type": "Pinecone",
- "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
- "category": "Vector Stores",
- "description": "Load existing index from Pinecone (i.e: Document has been upserted)",
- "inputParams": [
- {
- "label": "Pinecone Api Key",
- "name": "pineconeApiKey",
- "type": "password",
- "id": "pineconeExistingIndex_1-input-pineconeApiKey-password"
- },
- {
- "label": "Pinecone Environment",
- "name": "pineconeEnv",
- "type": "string",
- "id": "pineconeExistingIndex_1-input-pineconeEnv-string"
- },
- {
- "label": "Pinecone Index",
- "name": "pineconeIndex",
- "type": "string",
- "id": "pineconeExistingIndex_1-input-pineconeIndex-string"
- },
- {
- "label": "Pinecone Namespace",
- "name": "pineconeNamespace",
- "type": "string",
- "placeholder": "my-first-namespace",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_1-input-pineconeNamespace-string"
- },
- {
- "label": "Pinecone Metadata Filter",
- "name": "pineconeMetadataFilter",
- "type": "json",
- "optional": true,
- "additionalParams": true,
- "id": "pineconeExistingIndex_1-input-pineconeMetadataFilter-json"
- },
- {
- "label": "Top K",
- "name": "topK",
- "description": "Number of top results to fetch. Default to 4",
- "placeholder": "4",
- "type": "number",
- "additionalParams": true,
- "optional": true,
- "id": "pineconeExistingIndex_1-input-topK-number"
- }
- ],
- "inputAnchors": [
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "pineconeExistingIndex_1-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "embeddings": "{{openAIEmbeddings_3.data.instance}}",
- "pineconeEnv": "us-west4-gcp",
- "pineconeIndex": "state-of-union",
- "pineconeNamespace": ""
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "name": "retriever",
- "label": "Pinecone Retriever",
- "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
- },
- {
- "id": "pineconeExistingIndex_1-output-vectorStore-Pinecone|VectorStore",
- "name": "vectorStore",
- "label": "Pinecone Vector Store",
- "type": "Pinecone | VectorStore"
- }
- ],
- "default": "retriever"
- }
- ],
- "outputs": {
- "output": "retriever"
- },
- "selected": false
- },
- "selected": false,
- "dragging": false,
- "positionAbsolute": {
- "x": 525.6644489497978,
- "y": 420.1233379157454
- }
- },
- {
- "width": 300,
- "height": 601,
- "id": "chainTool_3",
- "position": {
- "x": 1267.7142132085273,
- "y": -85.7749282485849
- },
- "type": "customNode",
- "data": {
- "id": "chainTool_3",
- "label": "Chain Tool",
- "name": "chainTool",
- "type": "ChainTool",
- "baseClasses": ["ChainTool", "DynamicTool", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Use a chain as allowed tool for agent",
- "inputParams": [
- {
- "label": "Chain Name",
- "name": "name",
- "type": "string",
- "placeholder": "state-of-union-qa",
- "id": "chainTool_3-input-name-string"
- },
- {
- "label": "Chain Description",
- "name": "description",
- "type": "string",
- "rows": 3,
- "placeholder": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
- "id": "chainTool_3-input-description-string"
- },
- {
- "label": "Return Direct",
- "name": "returnDirect",
- "type": "boolean",
- "optional": true,
- "id": "chainTool_3-input-returnDirect-boolean"
- }
- ],
- "inputAnchors": [
- {
- "label": "Base Chain",
- "name": "baseChain",
- "type": "BaseChain",
- "id": "chainTool_3-input-baseChain-BaseChain"
- }
- ],
- "inputs": {
- "name": "state-of-union-qa",
- "description": "State of the Union QA - useful for when you need to ask questions about the most recent state of the union address.",
- "returnDirect": "",
- "baseChain": "{{retrievalQAChain_1.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "chainTool_3-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
- "name": "chainTool",
- "label": "ChainTool",
- "type": "ChainTool | DynamicTool | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "dragging": false,
- "positionAbsolute": {
- "x": 1267.7142132085273,
- "y": -85.7749282485849
- }
- },
- {
- "width": 300,
- "height": 523,
- "id": "openAI_5",
- "position": {
- "x": 1683.95439713088,
- "y": 329.0556949149878
- },
- "type": "customNode",
- "data": {
- "id": "openAI_5",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_5-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_5-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_5-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_5-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": "0",
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_5-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 1683.95439713088,
- "y": 329.0556949149878
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 279,
- "id": "mrklAgentLLM_0",
- "position": {
- "x": 2061.891333395338,
- "y": -140.0694021759809
- },
- "type": "customNode",
- "data": {
- "id": "mrklAgentLLM_0",
- "label": "MRKL Agent for LLMs",
- "name": "mrklAgentLLM",
- "type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
- "category": "Agents",
- "description": "Agent that uses the ReAct Framework to decide what action to take, optimized to be used with LLMs",
- "inputParams": [],
- "inputAnchors": [
- {
- "label": "Allowed Tools",
- "name": "tools",
- "type": "Tool",
- "list": true,
- "id": "mrklAgentLLM_0-input-tools-Tool"
- },
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "mrklAgentLLM_0-input-model-BaseLanguageModel"
- }
- ],
- "inputs": {
- "tools": [
- "{{serpAPI_0.data.instance}}",
- "{{calculator_1.data.instance}}",
- "{{chainTool_2.data.instance}}",
- "{{chainTool_3.data.instance}}"
- ],
- "model": "{{openAI_5.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "mrklAgentLLM_0-output-mrklAgentLLM-AgentExecutor|BaseChain|BaseLangChain",
- "name": "mrklAgentLLM",
- "label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain | BaseLangChain"
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
@@ -1106,165 +1146,13 @@
},
"selected": false,
"positionAbsolute": {
- "x": 2061.891333395338,
- "y": -140.0694021759809
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 279,
- "id": "retrievalQAChain_0",
- "position": {
- "x": 898.1253096948574,
- "y": -859.1174013418433
- },
- "type": "customNode",
- "data": {
- "id": "retrievalQAChain_0",
- "label": "Retrieval QA Chain",
- "name": "retrievalQAChain",
- "type": "RetrievalQAChain",
- "baseClasses": ["RetrievalQAChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "QA chain to answer a question based on the retrieved documents",
- "inputParams": [],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "retrievalQAChain_0-input-model-BaseLanguageModel"
- },
- {
- "label": "Vector Store Retriever",
- "name": "vectorStoreRetriever",
- "type": "BaseRetriever",
- "id": "retrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
- }
- ],
- "inputs": {
- "model": "{{openAI_3.data.instance}}",
- "vectorStoreRetriever": "{{chromaExistingIndex_1.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "retrievalQAChain_0-output-retrievalQAChain-RetrievalQAChain|BaseChain|BaseLangChain",
- "name": "retrievalQAChain",
- "label": "RetrievalQAChain",
- "type": "RetrievalQAChain | BaseChain | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 898.1253096948574,
- "y": -859.1174013418433
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 279,
- "id": "retrievalQAChain_1",
- "position": {
- "x": 895.4349543765911,
- "y": 166.60331503487222
- },
- "type": "customNode",
- "data": {
- "id": "retrievalQAChain_1",
- "label": "Retrieval QA Chain",
- "name": "retrievalQAChain",
- "type": "RetrievalQAChain",
- "baseClasses": ["RetrievalQAChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "QA chain to answer a question based on the retrieved documents",
- "inputParams": [],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "retrievalQAChain_1-input-model-BaseLanguageModel"
- },
- {
- "label": "Vector Store Retriever",
- "name": "vectorStoreRetriever",
- "type": "BaseRetriever",
- "id": "retrievalQAChain_1-input-vectorStoreRetriever-BaseRetriever"
- }
- ],
- "inputs": {
- "model": "{{openAI_4.data.instance}}",
- "vectorStoreRetriever": "{{pineconeExistingIndex_1.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "retrievalQAChain_1-output-retrievalQAChain-RetrievalQAChain|BaseChain|BaseLangChain",
- "name": "retrievalQAChain",
- "label": "RetrievalQAChain",
- "type": "RetrievalQAChain | BaseChain | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 895.4349543765911,
- "y": 166.60331503487222
+ "x": 1619.5346765785587,
+ "y": 292.29615581180684
},
"dragging": false
}
],
"edges": [
- {
- "source": "openAIEmbeddings_2",
- "sourceHandle": "openAIEmbeddings_2-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "chromaExistingIndex_1",
- "targetHandle": "chromaExistingIndex_1-input-embeddings-Embeddings",
- "type": "buttonedge",
- "id": "openAIEmbeddings_2-openAIEmbeddings_2-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-chromaExistingIndex_1-chromaExistingIndex_1-input-embeddings-Embeddings",
- "data": {
- "label": ""
- }
- },
- {
- "source": "openAIEmbeddings_3",
- "sourceHandle": "openAIEmbeddings_3-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
- "target": "pineconeExistingIndex_1",
- "targetHandle": "pineconeExistingIndex_1-input-embeddings-Embeddings",
- "type": "buttonedge",
- "id": "openAIEmbeddings_3-openAIEmbeddings_3-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_1-pineconeExistingIndex_1-input-embeddings-Embeddings",
- "data": {
- "label": ""
- }
- },
- {
- "source": "serpAPI_0",
- "sourceHandle": "serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain",
- "target": "mrklAgentLLM_0",
- "targetHandle": "mrklAgentLLM_0-input-tools-Tool",
- "type": "buttonedge",
- "id": "serpAPI_0-serpAPI_0-output-serpAPI-SerpAPI|Tool|StructuredTool|BaseLangChain-mrklAgentLLM_0-mrklAgentLLM_0-input-tools-Tool",
- "data": {
- "label": ""
- }
- },
- {
- "source": "calculator_1",
- "sourceHandle": "calculator_1-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain",
- "target": "mrklAgentLLM_0",
- "targetHandle": "mrklAgentLLM_0-input-tools-Tool",
- "type": "buttonedge",
- "id": "calculator_1-calculator_1-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain-mrklAgentLLM_0-mrklAgentLLM_0-input-tools-Tool",
- "data": {
- "label": ""
- }
- },
{
"source": "chainTool_2",
"sourceHandle": "chainTool_2-output-chainTool-ChainTool|DynamicTool|Tool|StructuredTool|BaseLangChain",
@@ -1287,39 +1175,6 @@
"label": ""
}
},
- {
- "source": "openAI_5",
- "sourceHandle": "openAI_5-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "target": "mrklAgentLLM_0",
- "targetHandle": "mrklAgentLLM_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "openAI_5-openAI_5-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-mrklAgentLLM_0-mrklAgentLLM_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "openAI_3",
- "sourceHandle": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "target": "retrievalQAChain_0",
- "targetHandle": "retrievalQAChain_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "openAI_3-openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-retrievalQAChain_0-retrievalQAChain_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "chromaExistingIndex_1",
- "sourceHandle": "chromaExistingIndex_1-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever",
- "target": "retrievalQAChain_0",
- "targetHandle": "retrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
- "type": "buttonedge",
- "id": "chromaExistingIndex_1-chromaExistingIndex_1-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever-retrievalQAChain_0-retrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
- "data": {
- "label": ""
- }
- },
{
"source": "retrievalQAChain_0",
"sourceHandle": "retrievalQAChain_0-output-retrievalQAChain-RetrievalQAChain|BaseChain|BaseLangChain",
@@ -1331,28 +1186,6 @@
"label": ""
}
},
- {
- "source": "openAI_4",
- "sourceHandle": "openAI_4-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "target": "retrievalQAChain_1",
- "targetHandle": "retrievalQAChain_1-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "openAI_4-openAI_4-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-retrievalQAChain_1-retrievalQAChain_1-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "pineconeExistingIndex_1",
- "sourceHandle": "pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
- "target": "retrievalQAChain_1",
- "targetHandle": "retrievalQAChain_1-input-vectorStoreRetriever-BaseRetriever",
- "type": "buttonedge",
- "id": "pineconeExistingIndex_1-pineconeExistingIndex_1-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-retrievalQAChain_1-retrievalQAChain_1-input-vectorStoreRetriever-BaseRetriever",
- "data": {
- "label": ""
- }
- },
{
"source": "retrievalQAChain_1",
"sourceHandle": "retrievalQAChain_1-output-retrievalQAChain-RetrievalQAChain|BaseChain|BaseLangChain",
@@ -1363,6 +1196,83 @@
"data": {
"label": ""
}
+ },
+ {
+ "source": "openAI_2",
+ "sourceHandle": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "target": "retrievalQAChain_0",
+ "targetHandle": "retrievalQAChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "openAI_2-openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-retrievalQAChain_0-retrievalQAChain_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAIEmbeddings_1",
+ "sourceHandle": "openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "chromaExistingIndex_0",
+ "targetHandle": "chromaExistingIndex_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_1-openAIEmbeddings_1-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-chromaExistingIndex_0-chromaExistingIndex_0-input-embeddings-Embeddings",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chromaExistingIndex_0",
+ "sourceHandle": "chromaExistingIndex_0-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever",
+ "target": "retrievalQAChain_0",
+ "targetHandle": "retrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "type": "buttonedge",
+ "id": "chromaExistingIndex_0-chromaExistingIndex_0-output-retriever-Chroma|VectorStoreRetriever|BaseRetriever-retrievalQAChain_0-retrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAIEmbeddings_2",
+ "sourceHandle": "openAIEmbeddings_2-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeExistingIndex_0",
+ "targetHandle": "pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_2-openAIEmbeddings_2-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeExistingIndex_0-pineconeExistingIndex_0-input-embeddings-Embeddings",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAI_3",
+ "sourceHandle": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "target": "retrievalQAChain_1",
+ "targetHandle": "retrievalQAChain_1-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "openAI_3-openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-retrievalQAChain_1-retrievalQAChain_1-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "pineconeExistingIndex_0",
+ "sourceHandle": "pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "target": "retrievalQAChain_1",
+ "targetHandle": "retrievalQAChain_1-input-vectorStoreRetriever-BaseRetriever",
+ "type": "buttonedge",
+ "id": "pineconeExistingIndex_0-pineconeExistingIndex_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-retrievalQAChain_1-retrievalQAChain_1-input-vectorStoreRetriever-BaseRetriever",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAI_4",
+ "sourceHandle": "openAI_4-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "target": "mrklAgentLLM_0",
+ "targetHandle": "mrklAgentLLM_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "openAI_4-openAI_4-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-mrklAgentLLM_0-mrklAgentLLM_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
}
]
}
diff --git a/packages/server/marketplaces/OpenAI Agent.json b/packages/server/marketplaces/chatflows/OpenAI Agent.json
similarity index 86%
rename from packages/server/marketplaces/OpenAI Agent.json
rename to packages/server/marketplaces/chatflows/OpenAI Agent.json
index 75dc1527..91d5d38c 100644
--- a/packages/server/marketplaces/OpenAI Agent.json
+++ b/packages/server/marketplaces/chatflows/OpenAI Agent.json
@@ -3,27 +3,296 @@
"nodes": [
{
"width": 300,
- "height": 524,
+ "height": 143,
+ "id": "calculator_0",
+ "position": {
+ "x": 288.06681362611545,
+ "y": 289.1385194199715
+ },
+ "type": "customNode",
+ "data": {
+ "id": "calculator_0",
+ "label": "Calculator",
+ "name": "calculator",
+ "version": 1,
+ "type": "Calculator",
+ "baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain", "Serializable"],
+ "category": "Tools",
+ "description": "Perform calculations on response",
+ "inputParams": [],
+ "inputAnchors": [],
+ "inputs": {},
+ "outputAnchors": [
+ {
+ "id": "calculator_0-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain|Serializable",
+ "name": "calculator",
+ "label": "Calculator",
+ "type": "Calculator | Tool | StructuredTool | BaseLangChain | Serializable"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 288.06681362611545,
+ "y": 289.1385194199715
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 376,
+ "id": "bufferMemory_0",
+ "position": {
+ "x": 285.7750469157585,
+ "y": 465.1140427303788
+ },
+ "type": "customNode",
+ "data": {
+ "id": "bufferMemory_0",
+ "label": "Buffer Memory",
+ "name": "bufferMemory",
+ "version": 1,
+ "type": "BufferMemory",
+ "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Remembers previous conversational back and forths directly",
+ "inputParams": [
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "id": "bufferMemory_0-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "id": "bufferMemory_0-input-inputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "memoryKey": "chat_history",
+ "inputKey": "input"
+ },
+ "outputAnchors": [
+ {
+ "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "name": "bufferMemory",
+ "label": "BufferMemory",
+ "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 285.7750469157585,
+ "y": 465.1140427303788
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 277,
+ "id": "customTool_0",
+ "position": {
+ "x": 883.9529939431576,
+ "y": -32.32503903826486
+ },
+ "type": "customNode",
+ "data": {
+ "id": "customTool_0",
+ "label": "Custom Tool",
+ "name": "customTool",
+ "version": 1,
+ "type": "CustomTool",
+ "baseClasses": ["CustomTool", "Tool", "StructuredTool"],
+ "category": "Tools",
+ "description": "Use custom tool you've created in Flowise within chatflow",
+ "inputParams": [
+ {
+ "label": "Select Tool",
+ "name": "selectedTool",
+ "type": "asyncOptions",
+ "loadMethod": "listTools",
+ "id": "customTool_0-input-selectedTool-asyncOptions"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "selectedTool": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "customTool_0-output-customTool-CustomTool|Tool|StructuredTool",
+ "name": "customTool",
+ "label": "CustomTool",
+ "type": "CustomTool | Tool | StructuredTool"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 883.9529939431576,
+ "y": -32.32503903826486
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 277,
+ "id": "serper_0",
+ "position": {
+ "x": 504.3508341937219,
+ "y": -10.324432507151982
+ },
+ "type": "customNode",
+ "data": {
+ "id": "serper_0",
+ "label": "Serper",
+ "name": "serper",
+ "version": 1,
+ "type": "Serper",
+ "baseClasses": ["Serper", "Tool", "StructuredTool"],
+ "category": "Tools",
+ "description": "Wrapper around Serper.dev - Google Search API",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["serperApi"],
+ "id": "serper_0-input-credential-credential"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {},
+ "outputAnchors": [
+ {
+ "id": "serper_0-output-serper-Serper|Tool|StructuredTool",
+ "name": "serper",
+ "label": "Serper",
+ "type": "Serper | Tool | StructuredTool"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 504.3508341937219,
+ "y": -10.324432507151982
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 383,
+ "id": "openAIFunctionAgent_0",
+ "position": {
+ "x": 1241.9739093293213,
+ "y": 359.3158950327101
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIFunctionAgent_0",
+ "label": "OpenAI Function Agent",
+ "name": "openAIFunctionAgent",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain"],
+ "category": "Agents",
+ "description": "An agent that uses OpenAI's Function Calling functionality to pick the tool and args to call",
+ "inputParams": [
+ {
+ "label": "System Message",
+ "name": "systemMessage",
+ "type": "string",
+ "rows": 4,
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIFunctionAgent_0-input-systemMessage-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "openAIFunctionAgent_0-input-tools-Tool"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseChatMemory",
+ "id": "openAIFunctionAgent_0-input-memory-BaseChatMemory"
+ },
+ {
+ "label": "OpenAI Chat Model",
+ "name": "model",
+ "description": "Only works with gpt-3.5-turbo-0613 and gpt-4-0613. Refer docs for more info",
+ "type": "BaseChatModel",
+ "id": "openAIFunctionAgent_0-input-model-BaseChatModel"
+ }
+ ],
+ "inputs": {
+ "tools": ["{{calculator_0.data.instance}}", "{{serper_0.data.instance}}", "{{customTool_0.data.instance}}"],
+ "memory": "{{bufferMemory_0.data.instance}}",
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "systemMessage": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIFunctionAgent_0-output-openAIFunctionAgent-AgentExecutor|BaseChain",
+ "name": "openAIFunctionAgent",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1241.9739093293213,
+ "y": 359.3158950327101
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
"id": "chatOpenAI_0",
"position": {
- "x": 648.7470970481406,
- "y": 462.3331811694268
+ "x": 817.8210275868742,
+ "y": 627.7677030233751
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain", "Serializable"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -34,29 +303,33 @@
"label": "gpt-4",
"name": "gpt-4"
},
- {
- "label": "gpt-4-0314",
- "name": "gpt-4-0314"
- },
- {
- "label": "gpt-4-32k-0314",
- "name": "gpt-4-32k-0314"
- },
{
"label": "gpt-4-0613",
"name": "gpt-4-0613"
},
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
{
"label": "gpt-3.5-turbo",
"name": "gpt-3.5-turbo"
},
- {
- "label": "gpt-3.5-turbo-0301",
- "name": "gpt-3.5-turbo-0301"
- },
{
"label": "gpt-3.5-turbo-0613",
"name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
}
],
"default": "gpt-3.5-turbo",
@@ -122,7 +395,7 @@
],
"inputAnchors": [],
"inputs": {
- "modelName": "gpt-3.5-turbo-0613",
+ "modelName": "gpt-3.5-turbo",
"temperature": 0.9,
"maxTokens": "",
"topP": "",
@@ -133,10 +406,10 @@
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain|Serializable",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain | Serializable"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -144,285 +417,13 @@
},
"selected": false,
"positionAbsolute": {
- "x": 648.7470970481406,
- "y": 462.3331811694268
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 278,
- "id": "serper_0",
- "position": {
- "x": 486.27248799490576,
- "y": 4.465900738576664
- },
- "type": "customNode",
- "data": {
- "id": "serper_0",
- "label": "Serper",
- "name": "serper",
- "type": "Serper",
- "baseClasses": ["Serper", "Tool", "StructuredTool", "BaseLangChain", "Serializable"],
- "category": "Tools",
- "description": "Wrapper around Serper.dev - Google Search API",
- "inputParams": [
- {
- "label": "Serper Api Key",
- "name": "apiKey",
- "type": "password",
- "id": "serper_0-input-apiKey-password"
- }
- ],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "serper_0-output-serper-Serper|Tool|StructuredTool|BaseLangChain|Serializable",
- "name": "serper",
- "label": "Serper",
- "type": "Serper | Tool | StructuredTool | BaseLangChain | Serializable"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 486.27248799490576,
- "y": 4.465900738576664
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 143,
- "id": "calculator_0",
- "position": {
- "x": 286.4092336819905,
- "y": 304.05673891709597
- },
- "type": "customNode",
- "data": {
- "id": "calculator_0",
- "label": "Calculator",
- "name": "calculator",
- "type": "Calculator",
- "baseClasses": ["Calculator", "Tool", "StructuredTool", "BaseLangChain", "Serializable"],
- "category": "Tools",
- "description": "Perform calculations on response",
- "inputParams": [],
- "inputAnchors": [],
- "inputs": {},
- "outputAnchors": [
- {
- "id": "calculator_0-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain|Serializable",
- "name": "calculator",
- "label": "Calculator",
- "type": "Calculator | Tool | StructuredTool | BaseLangChain | Serializable"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 286.4092336819905,
- "y": 304.05673891709597
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 383,
- "id": "openAIFunctionAgent_0",
- "position": {
- "x": 1341.2259105169032,
- "y": 318.35651549722945
- },
- "type": "customNode",
- "data": {
- "id": "openAIFunctionAgent_0",
- "label": "OpenAI Function Agent",
- "name": "openAIFunctionAgent",
- "type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain"],
- "category": "Agents",
- "description": "An agent that uses OpenAI's Function Calling functionality to pick the tool and args to call",
- "inputParams": [
- {
- "label": "System Message",
- "name": "systemMessage",
- "type": "string",
- "rows": 4,
- "optional": true,
- "additionalParams": true,
- "id": "openAIFunctionAgent_0-input-systemMessage-string"
- }
- ],
- "inputAnchors": [
- {
- "label": "Allowed Tools",
- "name": "tools",
- "type": "Tool",
- "list": true,
- "id": "openAIFunctionAgent_0-input-tools-Tool"
- },
- {
- "label": "Memory",
- "name": "memory",
- "type": "BaseChatMemory",
- "id": "openAIFunctionAgent_0-input-memory-BaseChatMemory"
- },
- {
- "label": "OpenAI Chat Model",
- "name": "model",
- "description": "Only works with gpt-3.5-turbo-0613 and gpt-4-0613. Refer docs for more info",
- "type": "BaseChatModel",
- "id": "openAIFunctionAgent_0-input-model-BaseChatModel"
- }
- ],
- "inputs": {
- "tools": ["{{serper_0.data.instance}}", "{{calculator_0.data.instance}}", "{{customTool_0.data.instance}}"],
- "memory": "{{bufferMemory_0.data.instance}}",
- "model": "{{chatOpenAI_0.data.instance}}",
- "systemMessage": ""
- },
- "outputAnchors": [
- {
- "id": "openAIFunctionAgent_0-output-openAIFunctionAgent-AgentExecutor|BaseChain",
- "name": "openAIFunctionAgent",
- "label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1341.2259105169032,
- "y": 318.35651549722945
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 376,
- "id": "bufferMemory_0",
- "position": {
- "x": 285.7750469157585,
- "y": 465.1140427303788
- },
- "type": "customNode",
- "data": {
- "id": "bufferMemory_0",
- "label": "Buffer Memory",
- "name": "bufferMemory",
- "type": "BufferMemory",
- "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
- "category": "Memory",
- "description": "Remembers previous conversational back and forths directly",
- "inputParams": [
- {
- "label": "Memory Key",
- "name": "memoryKey",
- "type": "string",
- "default": "chat_history",
- "id": "bufferMemory_0-input-memoryKey-string"
- },
- {
- "label": "Input Key",
- "name": "inputKey",
- "type": "string",
- "default": "input",
- "id": "bufferMemory_0-input-inputKey-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "memoryKey": "chat_history",
- "inputKey": "input"
- },
- "outputAnchors": [
- {
- "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
- "name": "bufferMemory",
- "label": "BufferMemory",
- "type": "BufferMemory | BaseChatMemory | BaseMemory"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 285.7750469157585,
- "y": 465.1140427303788
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 277,
- "id": "customTool_0",
- "position": {
- "x": 883.9529939431576,
- "y": -32.32503903826486
- },
- "type": "customNode",
- "data": {
- "id": "customTool_0",
- "label": "Custom Tool",
- "name": "customTool",
- "type": "CustomTool",
- "baseClasses": ["CustomTool", "Tool", "StructuredTool"],
- "category": "Tools",
- "description": "Use custom tool you've created in Flowise within chatflow",
- "inputParams": [
- {
- "label": "Select Tool",
- "name": "selectedTool",
- "type": "asyncOptions",
- "loadMethod": "listTools",
- "id": "customTool_0-input-selectedTool-asyncOptions"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "selectedTool": ""
- },
- "outputAnchors": [
- {
- "id": "customTool_0-output-customTool-CustomTool|Tool|StructuredTool",
- "name": "customTool",
- "label": "CustomTool",
- "type": "CustomTool | Tool | StructuredTool"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 883.9529939431576,
- "y": -32.32503903826486
+ "x": 817.8210275868742,
+ "y": 627.7677030233751
},
"dragging": false
}
],
"edges": [
- {
- "source": "serper_0",
- "sourceHandle": "serper_0-output-serper-Serper|Tool|StructuredTool|BaseLangChain|Serializable",
- "target": "openAIFunctionAgent_0",
- "targetHandle": "openAIFunctionAgent_0-input-tools-Tool",
- "type": "buttonedge",
- "id": "serper_0-serper_0-output-serper-Serper|Tool|StructuredTool|BaseLangChain|Serializable-openAIFunctionAgent_0-openAIFunctionAgent_0-input-tools-Tool",
- "data": {
- "label": ""
- }
- },
{
"source": "calculator_0",
"sourceHandle": "calculator_0-output-calculator-Calculator|Tool|StructuredTool|BaseLangChain|Serializable",
@@ -435,23 +436,12 @@
}
},
{
- "source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain|Serializable",
+ "source": "serper_0",
+ "sourceHandle": "serper_0-output-serper-Serper|Tool|StructuredTool",
"target": "openAIFunctionAgent_0",
- "targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
+ "targetHandle": "openAIFunctionAgent_0-input-tools-Tool",
"type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain|Serializable-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "bufferMemory_0",
- "sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
- "target": "openAIFunctionAgent_0",
- "targetHandle": "openAIFunctionAgent_0-input-memory-BaseChatMemory",
- "type": "buttonedge",
- "id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-openAIFunctionAgent_0-openAIFunctionAgent_0-input-memory-BaseChatMemory",
+ "id": "serper_0-serper_0-output-serper-Serper|Tool|StructuredTool-openAIFunctionAgent_0-openAIFunctionAgent_0-input-tools-Tool",
"data": {
"label": ""
}
@@ -466,6 +456,28 @@
"data": {
"label": ""
}
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "openAIFunctionAgent_0",
+ "targetHandle": "openAIFunctionAgent_0-input-model-BaseChatModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-openAIFunctionAgent_0-openAIFunctionAgent_0-input-model-BaseChatModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "bufferMemory_0",
+ "sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "target": "openAIFunctionAgent_0",
+ "targetHandle": "openAIFunctionAgent_0-input-memory-BaseChatMemory",
+ "type": "buttonedge",
+ "id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-openAIFunctionAgent_0-openAIFunctionAgent_0-input-memory-BaseChatMemory",
+ "data": {
+ "label": ""
+ }
}
]
}
diff --git a/packages/server/marketplaces/Prompt Chaining.json b/packages/server/marketplaces/chatflows/Prompt Chaining.json
similarity index 74%
rename from packages/server/marketplaces/Prompt Chaining.json
rename to packages/server/marketplaces/chatflows/Prompt Chaining.json
index 33a64081..e0491cc1 100644
--- a/packages/server/marketplaces/Prompt Chaining.json
+++ b/packages/server/marketplaces/chatflows/Prompt Chaining.json
@@ -3,27 +3,467 @@
"nodes": [
{
"width": 300,
- "height": 526,
+ "height": 475,
+ "id": "promptTemplate_0",
+ "position": {
+ "x": 792.9464838535649,
+ "y": 527.1718536712464
+ },
+ "type": "customNode",
+ "data": {
+ "id": "promptTemplate_0",
+ "label": "Prompt Template",
+ "name": "promptTemplate",
+ "version": 1,
+ "type": "PromptTemplate",
+ "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
+ "category": "Prompts",
+ "description": "Schema to represent a basic prompt for an LLM",
+ "inputParams": [
+ {
+ "label": "Template",
+ "name": "template",
+ "type": "string",
+ "rows": 4,
+ "placeholder": "What is a good name for a company that makes {product}?",
+ "id": "promptTemplate_0-input-template-string"
+ },
+ {
+ "label": "Format Prompt Values",
+ "name": "promptValues",
+ "type": "json",
+ "optional": true,
+ "acceptVariable": true,
+ "list": true,
+ "id": "promptTemplate_0-input-promptValues-json"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "template": "You are an AI who performs one task based on the following objective: {objective}.\nRespond with how you would complete this task:",
+ "promptValues": "{\"objective\":\"{{question}}\"}"
+ },
+ "outputAnchors": [
+ {
+ "id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "name": "promptTemplate",
+ "label": "PromptTemplate",
+ "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 792.9464838535649,
+ "y": 527.1718536712464
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 475,
+ "id": "promptTemplate_1",
+ "position": {
+ "x": 1571.0896874449775,
+ "y": 522.8455116403258
+ },
+ "type": "customNode",
+ "data": {
+ "id": "promptTemplate_1",
+ "label": "Prompt Template",
+ "name": "promptTemplate",
+ "version": 1,
+ "type": "PromptTemplate",
+ "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
+ "category": "Prompts",
+ "description": "Schema to represent a basic prompt for an LLM",
+ "inputParams": [
+ {
+ "label": "Template",
+ "name": "template",
+ "type": "string",
+ "rows": 4,
+ "placeholder": "What is a good name for a company that makes {product}?",
+ "id": "promptTemplate_1-input-template-string"
+ },
+ {
+ "label": "Format Prompt Values",
+ "name": "promptValues",
+ "type": "json",
+ "optional": true,
+ "acceptVariable": true,
+ "list": true,
+ "id": "promptTemplate_1-input-promptValues-json"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "template": "You are a task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}.\nThe last completed task has the result: {result}.\nBased on the result, create new tasks to be completed by the AI system that do not overlap with result.\nReturn the tasks as an array.",
+ "promptValues": "{\"objective\":\"{{question}}\",\"result\":\"{{llmChain_0.data.instance}}\"}"
+ },
+ "outputAnchors": [
+ {
+ "id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "name": "promptTemplate",
+ "label": "PromptTemplate",
+ "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 1571.0896874449775,
+ "y": 522.8455116403258
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 405,
+ "id": "llmChain_0",
+ "position": {
+ "x": 1192.835706086358,
+ "y": 367.49653955405995
+ },
+ "type": "customNode",
+ "data": {
+ "id": "llmChain_0",
+ "label": "LLM Chain",
+ "name": "llmChain",
+ "version": 1,
+ "type": "LLMChain",
+ "baseClasses": ["LLMChain", "BaseChain"],
+ "category": "Chains",
+ "description": "Chain to run queries against LLMs",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "chainName",
+ "type": "string",
+ "placeholder": "Name Your Chain",
+ "optional": true,
+ "id": "llmChain_0-input-chainName-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "llmChain_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Prompt",
+ "name": "prompt",
+ "type": "BasePromptTemplate",
+ "id": "llmChain_0-input-prompt-BasePromptTemplate"
+ }
+ ],
+ "inputs": {
+ "model": "{{openAI_1.data.instance}}",
+ "prompt": "{{promptTemplate_0.data.instance}}",
+ "chainName": "FirstChain"
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "llmChain_0-output-llmChain-LLMChain|BaseChain",
+ "name": "llmChain",
+ "label": "LLM Chain",
+ "type": "LLMChain | BaseChain"
+ },
+ {
+ "id": "llmChain_0-output-outputPrediction-string|json",
+ "name": "outputPrediction",
+ "label": "Output Prediction",
+ "type": "string | json"
+ }
+ ],
+ "default": "llmChain"
+ }
+ ],
+ "outputs": {
+ "output": "outputPrediction"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1192.835706086358,
+ "y": 367.49653955405995
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 405,
+ "id": "llmChain_1",
+ "position": {
+ "x": 1956.8236771865425,
+ "y": 359.10696865911547
+ },
+ "type": "customNode",
+ "data": {
+ "id": "llmChain_1",
+ "label": "LLM Chain",
+ "name": "llmChain",
+ "version": 1,
+ "type": "LLMChain",
+ "baseClasses": ["LLMChain", "BaseChain"],
+ "category": "Chains",
+ "description": "Chain to run queries against LLMs",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "chainName",
+ "type": "string",
+ "placeholder": "Name Your Chain",
+ "optional": true,
+ "id": "llmChain_1-input-chainName-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "llmChain_1-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Prompt",
+ "name": "prompt",
+ "type": "BasePromptTemplate",
+ "id": "llmChain_1-input-prompt-BasePromptTemplate"
+ }
+ ],
+ "inputs": {
+ "model": "{{openAI_2.data.instance}}",
+ "prompt": "{{promptTemplate_1.data.instance}}",
+ "chainName": "LastChain"
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "llmChain_1-output-llmChain-LLMChain|BaseChain",
+ "name": "llmChain",
+ "label": "LLM Chain",
+ "type": "LLMChain | BaseChain"
+ },
+ {
+ "id": "llmChain_1-output-outputPrediction-string|json",
+ "name": "outputPrediction",
+ "label": "Output Prediction",
+ "type": "string | json"
+ }
+ ],
+ "default": "llmChain"
+ }
+ ],
+ "outputs": {
+ "output": "llmChain"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1956.8236771865425,
+ "y": 359.10696865911547
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "openAI_1",
+ "position": {
+ "x": 791.6102007244282,
+ "y": -13.71386876566092
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAI_1",
+ "label": "OpenAI",
+ "name": "openAI",
+ "version": 1,
+ "type": "OpenAI",
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
+ "category": "LLMs",
+ "description": "Wrapper around OpenAI large language models",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_1-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "text-davinci-003",
+ "name": "text-davinci-003"
+ },
+ {
+ "label": "text-davinci-002",
+ "name": "text-davinci-002"
+ },
+ {
+ "label": "text-curie-001",
+ "name": "text-curie-001"
+ },
+ {
+ "label": "text-babbage-001",
+ "name": "text-babbage-001"
+ }
+ ],
+ "default": "text-davinci-003",
+ "optional": true,
+ "id": "openAI_1-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.7,
+ "optional": true,
+ "id": "openAI_1-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-topP-number"
+ },
+ {
+ "label": "Best Of",
+ "name": "bestOf",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-bestOf-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-presencePenalty-number"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_1-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "text-davinci-003",
+ "temperature": 0.7,
+ "maxTokens": "",
+ "topP": "",
+ "bestOf": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "name": "openAI",
+ "label": "OpenAI",
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 791.6102007244282,
+ "y": -13.71386876566092
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
"id": "openAI_2",
"position": {
- "x": 793.6674026500068,
- "y": -20.826430802683774
+ "x": 1571.148617508543,
+ "y": -20.372437481171687
},
"type": "customNode",
"data": {
"id": "openAI_2",
"label": "OpenAI",
"name": "openAI",
+ "version": 1,
"type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
"category": "LLMs",
"description": "Wrapper around OpenAI large language models",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_2-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_2-input-credential-credential"
},
{
"label": "Model Name",
@@ -134,75 +574,15 @@
"frequencyPenalty": "",
"presencePenalty": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "id": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"name": "openAI",
"label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 793.6674026500068,
- "y": -20.826430802683774
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 534,
- "id": "promptTemplate_2",
- "position": {
- "x": 796.3399644963663,
- "y": 512.349657546027
- },
- "type": "customNode",
- "data": {
- "id": "promptTemplate_2",
- "label": "Prompt Template",
- "name": "promptTemplate",
- "type": "PromptTemplate",
- "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
- "category": "Prompts",
- "description": "Schema to represent a basic prompt for an LLM",
- "inputParams": [
- {
- "label": "Template",
- "name": "template",
- "type": "string",
- "rows": 4,
- "placeholder": "What is a good name for a company that makes {product}?",
- "id": "promptTemplate_2-input-template-string"
- },
- {
- "label": "Format Prompt Values",
- "name": "promptValues",
- "type": "string",
- "rows": 4,
- "placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
- "optional": true,
- "acceptVariable": true,
- "list": true,
- "id": "promptTemplate_2-input-promptValues-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "template": "You are an AI who performs one task based on the following objective: {objective}.\nRespond with how you would complete this task:",
- "promptValues": "{\n \"objective\": \"{{question}}\"\n}"
- },
- "outputAnchors": [
- {
- "id": "promptTemplate_2-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "name": "promptTemplate",
- "label": "PromptTemplate",
- "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
@@ -210,438 +590,64 @@
},
"selected": false,
"positionAbsolute": {
- "x": 796.3399644963663,
- "y": 512.349657546027
+ "x": 1571.148617508543,
+ "y": -20.372437481171687
},
"dragging": false
- },
- {
- "width": 300,
- "height": 407,
- "id": "llmChain_2",
- "position": {
- "x": 1225.2861408370582,
- "y": 485.62403908243243
- },
- "type": "customNode",
- "data": {
- "id": "llmChain_2",
- "label": "LLM Chain",
- "name": "llmChain",
- "type": "LLMChain",
- "baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "Chain to run queries against LLMs",
- "inputParams": [
- {
- "label": "Chain Name",
- "name": "chainName",
- "type": "string",
- "placeholder": "Name Your Chain",
- "optional": true,
- "id": "llmChain_2-input-chainName-string"
- }
- ],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "llmChain_2-input-model-BaseLanguageModel"
- },
- {
- "label": "Prompt",
- "name": "prompt",
- "type": "BasePromptTemplate",
- "id": "llmChain_2-input-prompt-BasePromptTemplate"
- }
- ],
- "inputs": {
- "model": "{{openAI_2.data.instance}}",
- "prompt": "{{promptTemplate_2.data.instance}}",
- "chainName": "First Chain"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "llmChain_2-output-llmChain-LLMChain|BaseChain|BaseLangChain",
- "name": "llmChain",
- "label": "LLM Chain",
- "type": "LLMChain | BaseChain | BaseLangChain"
- },
- {
- "id": "llmChain_2-output-outputPrediction-string",
- "name": "outputPrediction",
- "label": "Output Prediction",
- "type": "string"
- }
- ],
- "default": "llmChain"
- }
- ],
- "outputs": {
- "output": "outputPrediction"
- },
- "selected": false
- },
- "selected": false,
- "dragging": false,
- "positionAbsolute": {
- "x": 1225.2861408370582,
- "y": 485.62403908243243
- }
- },
- {
- "width": 300,
- "height": 534,
- "id": "promptTemplate_3",
- "position": {
- "x": 1589.206555911206,
- "y": 460.23470154201766
- },
- "type": "customNode",
- "data": {
- "id": "promptTemplate_3",
- "label": "Prompt Template",
- "name": "promptTemplate",
- "type": "PromptTemplate",
- "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
- "category": "Prompts",
- "description": "Schema to represent a basic prompt for an LLM",
- "inputParams": [
- {
- "label": "Template",
- "name": "template",
- "type": "string",
- "rows": 4,
- "placeholder": "What is a good name for a company that makes {product}?",
- "id": "promptTemplate_3-input-template-string"
- },
- {
- "label": "Format Prompt Values",
- "name": "promptValues",
- "type": "string",
- "rows": 4,
- "placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
- "optional": true,
- "acceptVariable": true,
- "list": true,
- "id": "promptTemplate_3-input-promptValues-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "template": "You are a task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}.\nThe last completed task has the result: {result}.\nBased on the result, create new tasks to be completed by the AI system that do not overlap with result.\nReturn the tasks as an array.",
- "promptValues": "{\n \"objective\": \"{{question}}\",\n \"result\": \"\"\n}"
- },
- "outputAnchors": [
- {
- "id": "promptTemplate_3-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "name": "promptTemplate",
- "label": "PromptTemplate",
- "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1589.206555911206,
- "y": 460.23470154201766
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 526,
- "id": "openAI_3",
- "position": {
- "x": 1225.2861408370586,
- "y": -62.7856517905272
- },
- "type": "customNode",
- "data": {
- "id": "openAI_3",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_3-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_3-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_3-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_3-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": 0.7,
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 1225.2861408370586,
- "y": -62.7856517905272
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 407,
- "id": "llmChain_3",
- "position": {
- "x": 1972.2671768945252,
- "y": 142.73435419451476
- },
- "type": "customNode",
- "data": {
- "id": "llmChain_3",
- "label": "LLM Chain",
- "name": "llmChain",
- "type": "LLMChain",
- "baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "Chain to run queries against LLMs",
- "inputParams": [
- {
- "label": "Chain Name",
- "name": "chainName",
- "type": "string",
- "placeholder": "Name Your Chain",
- "optional": true,
- "id": "llmChain_3-input-chainName-string"
- }
- ],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "llmChain_3-input-model-BaseLanguageModel"
- },
- {
- "label": "Prompt",
- "name": "prompt",
- "type": "BasePromptTemplate",
- "id": "llmChain_3-input-prompt-BasePromptTemplate"
- }
- ],
- "inputs": {
- "model": "{{openAI_3.data.instance}}",
- "prompt": "{{promptTemplate_3.data.instance}}",
- "chainName": "LastChain"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "llmChain_3-output-llmChain-LLMChain|BaseChain|BaseLangChain",
- "name": "llmChain",
- "label": "LLM Chain",
- "type": "LLMChain | BaseChain | BaseLangChain"
- },
- {
- "id": "llmChain_3-output-outputPrediction-string",
- "name": "outputPrediction",
- "label": "Output Prediction",
- "type": "string"
- }
- ],
- "default": "llmChain"
- }
- ],
- "outputs": {
- "output": "llmChain"
- },
- "selected": false
- },
- "selected": false,
- "dragging": false,
- "positionAbsolute": {
- "x": 1972.2671768945252,
- "y": 142.73435419451476
- }
}
],
"edges": [
{
- "source": "llmChain_2",
- "sourceHandle": "llmChain_2-output-outputPrediction-string",
- "target": "promptTemplate_3",
- "targetHandle": "promptTemplate_3-input-promptValues-string",
+ "source": "promptTemplate_0",
+ "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "target": "llmChain_0",
+ "targetHandle": "llmChain_0-input-prompt-BasePromptTemplate",
"type": "buttonedge",
- "id": "llmChain_2-llmChain_2-output-outputPrediction-string-promptTemplate_3-promptTemplate_3-input-promptValues-string",
+ "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_0-llmChain_0-input-prompt-BasePromptTemplate",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "llmChain_0",
+ "sourceHandle": "llmChain_0-output-outputPrediction-string|json",
+ "target": "promptTemplate_1",
+ "targetHandle": "promptTemplate_1-input-promptValues-json",
+ "type": "buttonedge",
+ "id": "llmChain_0-llmChain_0-output-outputPrediction-string|json-promptTemplate_1-promptTemplate_1-input-promptValues-json",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "promptTemplate_1",
+ "sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "target": "llmChain_1",
+ "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
+ "type": "buttonedge",
+ "id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "openAI_1",
+ "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "target": "llmChain_0",
+ "targetHandle": "llmChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-llmChain_0-llmChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
},
{
"source": "openAI_2",
- "sourceHandle": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "target": "llmChain_2",
- "targetHandle": "llmChain_2-input-model-BaseLanguageModel",
+ "sourceHandle": "openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "target": "llmChain_1",
+ "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_2-openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_2-llmChain_2-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "promptTemplate_2",
- "sourceHandle": "promptTemplate_2-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "target": "llmChain_2",
- "targetHandle": "llmChain_2-input-prompt-BasePromptTemplate",
- "type": "buttonedge",
- "id": "promptTemplate_2-promptTemplate_2-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_2-llmChain_2-input-prompt-BasePromptTemplate",
- "data": {
- "label": ""
- }
- },
- {
- "source": "openAI_3",
- "sourceHandle": "openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "target": "llmChain_3",
- "targetHandle": "llmChain_3-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "openAI_3-openAI_3-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_3-llmChain_3-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
- {
- "source": "promptTemplate_3",
- "sourceHandle": "promptTemplate_3-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "target": "llmChain_3",
- "targetHandle": "llmChain_3-input-prompt-BasePromptTemplate",
- "type": "buttonedge",
- "id": "promptTemplate_3-promptTemplate_3-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_3-llmChain_3-input-prompt-BasePromptTemplate",
+ "id": "openAI_2-openAI_2-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/chatflows/Replicate LLM.json b/packages/server/marketplaces/chatflows/Replicate LLM.json
new file mode 100644
index 00000000..5a57b2e7
--- /dev/null
+++ b/packages/server/marketplaces/chatflows/Replicate LLM.json
@@ -0,0 +1,276 @@
+{
+ "description": "Use Replicate API that runs Llama 13b v2 model with LLMChain",
+ "nodes": [
+ {
+ "width": 300,
+ "height": 405,
+ "id": "llmChain_1",
+ "position": {
+ "x": 967.581544453458,
+ "y": 320.56761595884564
+ },
+ "type": "customNode",
+ "data": {
+ "id": "llmChain_1",
+ "label": "LLM Chain",
+ "name": "llmChain",
+ "version": 1,
+ "type": "LLMChain",
+ "baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
+ "category": "Chains",
+ "description": "Chain to run queries against LLMs",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "chainName",
+ "type": "string",
+ "placeholder": "Name Your Chain",
+ "optional": true,
+ "id": "llmChain_1-input-chainName-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "llmChain_1-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Prompt",
+ "name": "prompt",
+ "type": "BasePromptTemplate",
+ "id": "llmChain_1-input-prompt-BasePromptTemplate"
+ }
+ ],
+ "inputs": {
+ "model": "{{replicate_0.data.instance}}",
+ "prompt": "{{promptTemplate_0.data.instance}}",
+ "chainName": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "llmChain_1-output-llmChain-LLMChain|BaseChain|BaseLangChain",
+ "name": "llmChain",
+ "label": "LLM Chain",
+ "type": "LLMChain | BaseChain | BaseLangChain"
+ },
+ {
+ "id": "llmChain_1-output-outputPrediction-string|json",
+ "name": "outputPrediction",
+ "label": "Output Prediction",
+ "type": "string | json"
+ }
+ ],
+ "default": "llmChain"
+ }
+ ],
+ "outputs": {
+ "output": "llmChain"
+ },
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 967.581544453458,
+ "y": 320.56761595884564
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 475,
+ "id": "promptTemplate_0",
+ "position": {
+ "x": 269.2203229225663,
+ "y": 129.02909641085535
+ },
+ "type": "customNode",
+ "data": {
+ "id": "promptTemplate_0",
+ "label": "Prompt Template",
+ "name": "promptTemplate",
+ "version": 1,
+ "type": "PromptTemplate",
+ "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
+ "category": "Prompts",
+ "description": "Schema to represent a basic prompt for an LLM",
+ "inputParams": [
+ {
+ "label": "Template",
+ "name": "template",
+ "type": "string",
+ "rows": 4,
+ "placeholder": "What is a good name for a company that makes {product}?",
+ "id": "promptTemplate_0-input-template-string"
+ },
+ {
+ "label": "Format Prompt Values",
+ "name": "promptValues",
+ "type": "json",
+ "optional": true,
+ "acceptVariable": true,
+ "list": true,
+ "id": "promptTemplate_0-input-promptValues-json"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "template": "Assistant: You are a helpful assistant. You do not respond as 'User' or pretend to be 'User'. You only respond once as Assistant.\nUser: {query}\nAssistant:",
+ "promptValues": "{\"query\":\"{{question}}\"}"
+ },
+ "outputAnchors": [
+ {
+ "id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "name": "promptTemplate",
+ "label": "PromptTemplate",
+ "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 269.2203229225663,
+ "y": 129.02909641085535
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 527,
+ "id": "replicate_0",
+ "position": {
+ "x": 607.4915400488668,
+ "y": -60.643337207007804
+ },
+ "type": "customNode",
+ "data": {
+ "id": "replicate_0",
+ "label": "Replicate",
+ "name": "replicate",
+ "version": 1,
+ "type": "Replicate",
+ "baseClasses": ["Replicate", "LLM", "BaseLLM", "BaseLanguageModel"],
+ "category": "LLMs",
+ "description": "Use Replicate to run open source models on cloud",
+ "inputParams": [
+ {
+ "label": "Replicate Api Key",
+ "name": "replicateApiKey",
+ "type": "password",
+ "id": "replicate_0-input-replicateApiKey-password"
+ },
+ {
+ "label": "Model",
+ "name": "model",
+ "type": "string",
+ "placeholder": "a16z-infra/llama13b-v2-chat:df7690f1994d94e96ad9d568eac121aecf50684a0b0963b25a41cc40061269e5",
+ "optional": true,
+ "id": "replicate_0-input-model-string"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "description": "Adjusts randomness of outputs, greater than 1 is random and 0 is deterministic, 0.75 is a good starting value.",
+ "default": 0.7,
+ "optional": true,
+ "id": "replicate_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "description": "Maximum number of tokens to generate. A word is generally 2-3 tokens",
+ "optional": true,
+ "additionalParams": true,
+ "id": "replicate_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "description": "When decoding text, samples from the top p percentage of most likely tokens; lower to ignore less likely tokens",
+ "optional": true,
+ "additionalParams": true,
+ "id": "replicate_0-input-topP-number"
+ },
+ {
+ "label": "Repetition Penalty",
+ "name": "repetitionPenalty",
+ "type": "number",
+ "description": "Penalty for repeated words in generated text; 1 is no penalty, values greater than 1 discourage repetition, less than 1 encourage it. (minimum: 0.01; maximum: 5)",
+ "optional": true,
+ "additionalParams": true,
+ "id": "replicate_0-input-repetitionPenalty-number"
+ },
+ {
+ "label": "Additional Inputs",
+ "name": "additionalInputs",
+ "type": "json",
+ "description": "Each model has different parameters, refer to the specific model accepted inputs. For example: llama13b-v2",
+ "additionalParams": true,
+ "optional": true,
+ "id": "replicate_0-input-additionalInputs-json"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "model": "a16z-infra/llama13b-v2-chat:df7690f1994d94e96ad9d568eac121aecf50684a0b0963b25a41cc40061269e5",
+ "temperature": 0.7,
+ "maxTokens": "",
+ "topP": "",
+ "repetitionPenalty": "",
+ "additionalInputs": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "replicate_0-output-replicate-Replicate|LLM|BaseLLM|BaseLanguageModel",
+ "name": "replicate",
+ "label": "Replicate",
+ "type": "Replicate | LLM | BaseLLM | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 607.4915400488668,
+ "y": -60.643337207007804
+ },
+ "dragging": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "promptTemplate_0",
+ "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "target": "llmChain_1",
+ "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
+ "type": "buttonedge",
+ "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "replicate_0",
+ "sourceHandle": "replicate_0-output-replicate-Replicate|LLM|BaseLLM|BaseLanguageModel",
+ "target": "llmChain_1",
+ "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "replicate_0-replicate_0-output-replicate-Replicate|LLM|BaseLLM|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ }
+ ]
+}
diff --git a/packages/server/marketplaces/SQL DB Chain.json b/packages/server/marketplaces/chatflows/SQL DB Chain.json
similarity index 64%
rename from packages/server/marketplaces/SQL DB Chain.json
rename to packages/server/marketplaces/chatflows/SQL DB Chain.json
index e7826aa2..b37dc7ce 100644
--- a/packages/server/marketplaces/SQL DB Chain.json
+++ b/packages/server/marketplaces/chatflows/SQL DB Chain.json
@@ -1,159 +1,6 @@
{
"description": "Answer questions over a SQL database",
"nodes": [
- {
- "width": 300,
- "height": 524,
- "id": "openAI_1",
- "position": {
- "x": 835.4668837832456,
- "y": 182.4724119898708
- },
- "type": "customNode",
- "data": {
- "id": "openAI_1",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": 0.7,
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 835.4668837832456,
- "y": 182.4724119898708
- },
- "dragging": false
- },
{
"width": 300,
"height": 424,
@@ -167,6 +14,7 @@
"id": "sqlDatabaseChain_0",
"label": "Sql Database Chain",
"name": "sqlDatabaseChain",
+ "version": 1,
"type": "SqlDatabaseChain",
"baseClasses": ["SqlDatabaseChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -202,7 +50,7 @@
}
],
"inputs": {
- "model": "{{openAI_1.data.instance}}",
+ "model": "{{chatOpenAI_0.data.instance}}",
"database": "sqlite",
"dbFilePath": ""
},
@@ -223,16 +71,170 @@
"y": 217.507437391498
},
"dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 855.0396169649254,
+ "y": 179.29430548099504
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": "0",
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 855.0396169649254,
+ "y": 179.29430548099504
+ },
+ "dragging": false
}
],
"edges": [
{
- "source": "openAI_1",
- "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "sqlDatabaseChain_0",
"targetHandle": "sqlDatabaseChain_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-sqlDatabaseChain_0-sqlDatabaseChain_0-input-model-BaseLanguageModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-sqlDatabaseChain_0-sqlDatabaseChain_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Simple Conversation Chain.json b/packages/server/marketplaces/chatflows/Simple Conversation Chain.json
similarity index 87%
rename from packages/server/marketplaces/Simple Conversation Chain.json
rename to packages/server/marketplaces/chatflows/Simple Conversation Chain.json
index f7e654db..2c41a54f 100644
--- a/packages/server/marketplaces/Simple Conversation Chain.json
+++ b/packages/server/marketplaces/chatflows/Simple Conversation Chain.json
@@ -3,27 +3,86 @@
"nodes": [
{
"width": 300,
- "height": 524,
+ "height": 376,
+ "id": "bufferMemory_0",
+ "position": {
+ "x": 753.4300788823234,
+ "y": 479.5336426526603
+ },
+ "type": "customNode",
+ "data": {
+ "id": "bufferMemory_0",
+ "label": "Buffer Memory",
+ "name": "bufferMemory",
+ "version": 1,
+ "type": "BufferMemory",
+ "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Remembers previous conversational back and forths directly",
+ "inputParams": [
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "id": "bufferMemory_0-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "id": "bufferMemory_0-input-inputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "memoryKey": "chat_history",
+ "inputKey": "input"
+ },
+ "outputAnchors": [
+ {
+ "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "name": "bufferMemory",
+ "label": "BufferMemory",
+ "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 753.4300788823234,
+ "y": 479.5336426526603
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
"id": "chatOpenAI_0",
"position": {
- "x": 750.6529856117049,
- "y": -75.72544375812092
+ "x": 754.8942497823595,
+ "y": -70.76607584232393
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -132,70 +191,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 750.6529856117049,
- "y": -75.72544375812092
- },
- "selected": false,
- "dragging": false
- },
- {
- "width": 300,
- "height": 376,
- "id": "bufferMemory_0",
- "position": {
- "x": 753.4300788823234,
- "y": 479.5336426526603
- },
- "type": "customNode",
- "data": {
- "id": "bufferMemory_0",
- "label": "Buffer Memory",
- "name": "bufferMemory",
- "type": "BufferMemory",
- "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
- "category": "Memory",
- "description": "Remembers previous conversational back and forths directly",
- "inputParams": [
- {
- "label": "Memory Key",
- "name": "memoryKey",
- "type": "string",
- "default": "chat_history",
- "id": "bufferMemory_0-input-memoryKey-string"
- },
- {
- "label": "Input Key",
- "name": "inputKey",
- "type": "string",
- "default": "input",
- "id": "bufferMemory_0-input-inputKey-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "memoryKey": "chat_history",
- "inputKey": "input"
- },
- "outputAnchors": [
- {
- "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
- "name": "bufferMemory",
- "label": "BufferMemory",
- "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -203,26 +207,27 @@
},
"selected": false,
"positionAbsolute": {
- "x": 753.4300788823234,
- "y": 479.5336426526603
+ "x": 754.8942497823595,
+ "y": -70.76607584232393
},
"dragging": false
},
{
"width": 300,
- "height": 332,
+ "height": 383,
"id": "conversationChain_0",
"position": {
- "x": 1201.6630991237407,
- "y": 291.86981791303066
+ "x": 1174.6496397666272,
+ "y": 311.1052536740497
},
"type": "customNode",
"data": {
"id": "conversationChain_0",
"label": "Conversation Chain",
"name": "conversationChain",
+ "version": 1,
"type": "ConversationChain",
- "baseClasses": ["ConversationChain", "LLMChain", "BaseChain", "BaseLangChain"],
+ "baseClasses": ["ConversationChain", "LLMChain", "BaseChain"],
"category": "Chains",
"description": "Chat models specific conversational chain with memory",
"inputParams": [
@@ -249,19 +254,29 @@
"name": "memory",
"type": "BaseMemory",
"id": "conversationChain_0-input-memory-BaseMemory"
+ },
+ {
+ "label": "Document",
+ "name": "document",
+ "type": "Document",
+ "description": "Include whole document into the context window",
+ "optional": true,
+ "list": true,
+ "id": "conversationChain_0-input-document-Document"
}
],
"inputs": {
"model": "{{chatOpenAI_0.data.instance}}",
"memory": "{{bufferMemory_0.data.instance}}",
+ "document": "",
"systemMessagePrompt": ""
},
"outputAnchors": [
{
- "id": "conversationChain_0-output-conversationChain-ConversationChain|LLMChain|BaseChain|BaseLangChain",
+ "id": "conversationChain_0-output-conversationChain-ConversationChain|LLMChain|BaseChain",
"name": "conversationChain",
"label": "ConversationChain",
- "type": "ConversationChain | LLMChain | BaseChain | BaseLangChain"
+ "type": "ConversationChain | LLMChain | BaseChain"
}
],
"outputs": {},
@@ -269,8 +284,8 @@
},
"selected": false,
"positionAbsolute": {
- "x": 1201.6630991237407,
- "y": 291.86981791303066
+ "x": 1174.6496397666272,
+ "y": 311.1052536740497
},
"dragging": false
}
@@ -278,11 +293,11 @@
"edges": [
{
"source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "conversationChain_0",
"targetHandle": "conversationChain_0-input-model-BaseChatModel",
"type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationChain_0-conversationChain_0-input-model-BaseChatModel",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationChain_0-conversationChain_0-input-model-BaseChatModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Simple LLM Chain.json b/packages/server/marketplaces/chatflows/Simple LLM Chain.json
similarity index 79%
rename from packages/server/marketplaces/Simple LLM Chain.json
rename to packages/server/marketplaces/chatflows/Simple LLM Chain.json
index c9d354bc..0fc648c6 100644
--- a/packages/server/marketplaces/Simple LLM Chain.json
+++ b/packages/server/marketplaces/chatflows/Simple LLM Chain.json
@@ -3,221 +3,7 @@
"nodes": [
{
"width": 300,
- "height": 526,
- "id": "openAI_1",
- "position": {
- "x": 510.75932526856377,
- "y": -44.80152395958956
- },
- "type": "customNode",
- "data": {
- "id": "openAI_1",
- "label": "OpenAI",
- "name": "openAI",
- "type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
- "category": "LLMs",
- "description": "Wrapper around OpenAI large language models",
- "inputParams": [
- {
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_1-input-openAIApiKey-password"
- },
- {
- "label": "Model Name",
- "name": "modelName",
- "type": "options",
- "options": [
- {
- "label": "text-davinci-003",
- "name": "text-davinci-003"
- },
- {
- "label": "text-davinci-002",
- "name": "text-davinci-002"
- },
- {
- "label": "text-curie-001",
- "name": "text-curie-001"
- },
- {
- "label": "text-babbage-001",
- "name": "text-babbage-001"
- }
- ],
- "default": "text-davinci-003",
- "optional": true,
- "id": "openAI_1-input-modelName-options"
- },
- {
- "label": "Temperature",
- "name": "temperature",
- "type": "number",
- "default": 0.7,
- "optional": true,
- "id": "openAI_1-input-temperature-number"
- },
- {
- "label": "Max Tokens",
- "name": "maxTokens",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-maxTokens-number"
- },
- {
- "label": "Top Probability",
- "name": "topP",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-topP-number"
- },
- {
- "label": "Best Of",
- "name": "bestOf",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-bestOf-number"
- },
- {
- "label": "Frequency Penalty",
- "name": "frequencyPenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-frequencyPenalty-number"
- },
- {
- "label": "Presence Penalty",
- "name": "presencePenalty",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-presencePenalty-number"
- },
- {
- "label": "Batch Size",
- "name": "batchSize",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-batchSize-number"
- },
- {
- "label": "Timeout",
- "name": "timeout",
- "type": "number",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-timeout-number"
- },
- {
- "label": "BasePath",
- "name": "basepath",
- "type": "string",
- "optional": true,
- "additionalParams": true,
- "id": "openAI_1-input-basepath-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "modelName": "text-davinci-003",
- "temperature": 0.7,
- "maxTokens": "",
- "topP": "",
- "bestOf": "",
- "frequencyPenalty": "",
- "presencePenalty": "",
- "batchSize": "",
- "timeout": ""
- },
- "outputAnchors": [
- {
- "id": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
- "name": "openAI",
- "label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 510.75932526856377,
- "y": -44.80152395958956
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 534,
- "id": "promptTemplate_1",
- "position": {
- "x": 514.5434056794296,
- "y": 507.47798128037107
- },
- "type": "customNode",
- "data": {
- "id": "promptTemplate_1",
- "label": "Prompt Template",
- "name": "promptTemplate",
- "type": "PromptTemplate",
- "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
- "category": "Prompts",
- "description": "Schema to represent a basic prompt for an LLM",
- "inputParams": [
- {
- "label": "Template",
- "name": "template",
- "type": "string",
- "rows": 4,
- "placeholder": "What is a good name for a company that makes {product}?",
- "id": "promptTemplate_1-input-template-string"
- },
- {
- "label": "Format Prompt Values",
- "name": "promptValues",
- "type": "string",
- "rows": 4,
- "placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
- "optional": true,
- "acceptVariable": true,
- "list": true,
- "id": "promptTemplate_1-input-promptValues-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "template": "",
- "promptValues": ""
- },
- "outputAnchors": [
- {
- "id": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
- "name": "promptTemplate",
- "label": "PromptTemplate",
- "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 514.5434056794296,
- "y": 507.47798128037107
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 407,
+ "height": 405,
"id": "llmChain_1",
"position": {
"x": 970.9254258940236,
@@ -228,6 +14,7 @@
"id": "llmChain_1",
"label": "LLM Chain",
"name": "llmChain",
+ "version": 1,
"type": "LLMChain",
"baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
"category": "Chains",
@@ -257,8 +44,8 @@
}
],
"inputs": {
- "model": "{{openAI_1.data.instance}}",
- "prompt": "{{promptTemplate_1.data.instance}}",
+ "model": "{{openAI_0.data.instance}}",
+ "prompt": "{{promptTemplate_0.data.instance}}",
"chainName": ""
},
"outputAnchors": [
@@ -274,10 +61,10 @@
"type": "LLMChain | BaseChain | BaseLangChain"
},
{
- "id": "llmChain_1-output-outputPrediction-string",
+ "id": "llmChain_1-output-outputPrediction-string|json",
"name": "outputPrediction",
"label": "Output Prediction",
- "type": "string"
+ "type": "string | json"
}
],
"default": "llmChain"
@@ -294,27 +81,243 @@
},
"selected": false,
"dragging": false
+ },
+ {
+ "width": 300,
+ "height": 475,
+ "id": "promptTemplate_0",
+ "position": {
+ "x": 517.7412884791509,
+ "y": 506.7411400888471
+ },
+ "type": "customNode",
+ "data": {
+ "id": "promptTemplate_0",
+ "label": "Prompt Template",
+ "name": "promptTemplate",
+ "version": 1,
+ "type": "PromptTemplate",
+ "baseClasses": ["PromptTemplate", "BaseStringPromptTemplate", "BasePromptTemplate"],
+ "category": "Prompts",
+ "description": "Schema to represent a basic prompt for an LLM",
+ "inputParams": [
+ {
+ "label": "Template",
+ "name": "template",
+ "type": "string",
+ "rows": 4,
+ "placeholder": "What is a good name for a company that makes {product}?",
+ "id": "promptTemplate_0-input-template-string"
+ },
+ {
+ "label": "Format Prompt Values",
+ "name": "promptValues",
+ "type": "json",
+ "optional": true,
+ "acceptVariable": true,
+ "list": true,
+ "id": "promptTemplate_0-input-promptValues-json"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "template": "What is a good name for a company that makes {product}?",
+ "promptValues": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "name": "promptTemplate",
+ "label": "PromptTemplate",
+ "type": "PromptTemplate | BaseStringPromptTemplate | BasePromptTemplate"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 517.7412884791509,
+ "y": 506.7411400888471
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
+ "id": "openAI_0",
+ "position": {
+ "x": 513.3297923232442,
+ "y": -42.67554802812833
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAI_0",
+ "label": "OpenAI",
+ "name": "openAI",
+ "version": 1,
+ "type": "OpenAI",
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
+ "category": "LLMs",
+ "description": "Wrapper around OpenAI large language models",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "text-davinci-003",
+ "name": "text-davinci-003"
+ },
+ {
+ "label": "text-davinci-002",
+ "name": "text-davinci-002"
+ },
+ {
+ "label": "text-curie-001",
+ "name": "text-curie-001"
+ },
+ {
+ "label": "text-babbage-001",
+ "name": "text-babbage-001"
+ }
+ ],
+ "default": "text-davinci-003",
+ "optional": true,
+ "id": "openAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.7,
+ "optional": true,
+ "id": "openAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-topP-number"
+ },
+ {
+ "label": "Best Of",
+ "name": "bestOf",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-bestOf-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "text-davinci-003",
+ "temperature": 0.7,
+ "maxTokens": "",
+ "topP": "",
+ "bestOf": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
+ "name": "openAI",
+ "label": "OpenAI",
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 513.3297923232442,
+ "y": -42.67554802812833
+ },
+ "dragging": false
}
],
"edges": [
{
- "source": "openAI_1",
- "sourceHandle": "openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "source": "promptTemplate_0",
+ "sourceHandle": "promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
"target": "llmChain_1",
- "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
+ "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge",
- "id": "openAI_1-openAI_1-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
+ "id": "promptTemplate_0-promptTemplate_0-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
},
{
- "source": "promptTemplate_1",
- "sourceHandle": "promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate",
+ "source": "openAI_0",
+ "sourceHandle": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"target": "llmChain_1",
- "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
+ "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "promptTemplate_1-promptTemplate_1-output-promptTemplate-PromptTemplate|BaseStringPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
+ "id": "openAI_0-openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/Translator.json b/packages/server/marketplaces/chatflows/Translator.json
similarity index 79%
rename from packages/server/marketplaces/Translator.json
rename to packages/server/marketplaces/chatflows/Translator.json
index fda400e2..dc2ee6ba 100644
--- a/packages/server/marketplaces/Translator.json
+++ b/packages/server/marketplaces/chatflows/Translator.json
@@ -3,17 +3,99 @@
"nodes": [
{
"width": 300,
- "height": 711,
- "id": "chatPromptTemplate_1",
+ "height": 405,
+ "id": "llmChain_1",
"position": {
- "x": 441.8516979620723,
- "y": 636.1108860994266
+ "x": 865.7775572410412,
+ "y": 543.9211372857111
},
"type": "customNode",
"data": {
- "id": "chatPromptTemplate_1",
+ "id": "llmChain_1",
+ "label": "LLM Chain",
+ "name": "llmChain",
+ "version": 1,
+ "type": "LLMChain",
+ "baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
+ "category": "Chains",
+ "description": "Chain to run queries against LLMs",
+ "inputParams": [
+ {
+ "label": "Chain Name",
+ "name": "chainName",
+ "type": "string",
+ "placeholder": "Name Your Chain",
+ "optional": true,
+ "id": "llmChain_1-input-chainName-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "llmChain_1-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Prompt",
+ "name": "prompt",
+ "type": "BasePromptTemplate",
+ "id": "llmChain_1-input-prompt-BasePromptTemplate"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "prompt": "{{chatPromptTemplate_0.data.instance}}",
+ "chainName": "Language Translation"
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "llmChain_1-output-llmChain-LLMChain|BaseChain|BaseLangChain",
+ "name": "llmChain",
+ "label": "LLM Chain",
+ "type": "LLMChain | BaseChain | BaseLangChain"
+ },
+ {
+ "id": "llmChain_1-output-outputPrediction-string|json",
+ "name": "outputPrediction",
+ "label": "Output Prediction",
+ "type": "string | json"
+ }
+ ],
+ "default": "llmChain"
+ }
+ ],
+ "outputs": {
+ "output": "llmChain"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 865.7775572410412,
+ "y": 543.9211372857111
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 652,
+ "id": "chatPromptTemplate_0",
+ "position": {
+ "x": 437.51367850489396,
+ "y": 649.7619214034173
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatPromptTemplate_0",
"label": "Chat Prompt Template",
"name": "chatPromptTemplate",
+ "version": 1,
"type": "ChatPromptTemplate",
"baseClasses": ["ChatPromptTemplate", "BaseChatPromptTemplate", "BasePromptTemplate"],
"category": "Prompts",
@@ -25,7 +107,7 @@
"type": "string",
"rows": 4,
"placeholder": "You are a helpful assistant that translates {input_language} to {output_language}.",
- "id": "chatPromptTemplate_1-input-systemMessagePrompt-string"
+ "id": "chatPromptTemplate_0-input-systemMessagePrompt-string"
},
{
"label": "Human Message",
@@ -33,29 +115,27 @@
"type": "string",
"rows": 4,
"placeholder": "{text}",
- "id": "chatPromptTemplate_1-input-humanMessagePrompt-string"
+ "id": "chatPromptTemplate_0-input-humanMessagePrompt-string"
},
{
"label": "Format Prompt Values",
"name": "promptValues",
- "type": "string",
- "rows": 4,
- "placeholder": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}",
+ "type": "json",
"optional": true,
"acceptVariable": true,
"list": true,
- "id": "chatPromptTemplate_1-input-promptValues-string"
+ "id": "chatPromptTemplate_0-input-promptValues-json"
}
],
"inputAnchors": [],
"inputs": {
"systemMessagePrompt": "You are a helpful assistant that translates {input_language} to {output_language}.",
- "humanMessagePrompt": "{input}",
- "promptValues": "{\n \"input_language\": \"English\",\n \"output_language\": \"French\"\n}"
+ "humanMessagePrompt": "{text}",
+ "promptValues": "{\"input_language\":\"English\",\"output_language\":\"French\",\"text\":\"{{question}}\"}"
},
"outputAnchors": [
{
- "id": "chatPromptTemplate_1-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
+ "id": "chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"name": "chatPromptTemplate",
"label": "ChatPromptTemplate",
"type": "ChatPromptTemplate | BaseChatPromptTemplate | BasePromptTemplate"
@@ -66,34 +146,36 @@
},
"selected": false,
"positionAbsolute": {
- "x": 441.8516979620723,
- "y": 636.1108860994266
+ "x": 437.51367850489396,
+ "y": 649.7619214034173
},
"dragging": false
},
{
"width": 300,
- "height": 526,
- "id": "chatOpenAI_1",
+ "height": 523,
+ "id": "chatOpenAI_0",
"position": {
- "x": 439.5219561593599,
- "y": 93.61600226758335
+ "x": 436.97058562345904,
+ "y": 99.96180150605153
},
"type": "customNode",
"data": {
- "id": "chatOpenAI_1",
+ "id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_1-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -135,7 +217,7 @@
],
"default": "gpt-3.5-turbo",
"optional": true,
- "id": "chatOpenAI_1-input-modelName-options"
+ "id": "chatOpenAI_0-input-modelName-options"
},
{
"label": "Temperature",
@@ -143,7 +225,7 @@
"type": "number",
"default": 0.9,
"optional": true,
- "id": "chatOpenAI_1-input-temperature-number"
+ "id": "chatOpenAI_0-input-temperature-number"
},
{
"label": "Max Tokens",
@@ -151,7 +233,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-maxTokens-number"
+ "id": "chatOpenAI_0-input-maxTokens-number"
},
{
"label": "Top Probability",
@@ -159,7 +241,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-topP-number"
+ "id": "chatOpenAI_0-input-topP-number"
},
{
"label": "Frequency Penalty",
@@ -167,7 +249,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-frequencyPenalty-number"
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
},
{
"label": "Presence Penalty",
@@ -175,7 +257,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-presencePenalty-number"
+ "id": "chatOpenAI_0-input-presencePenalty-number"
},
{
"label": "Timeout",
@@ -183,7 +265,7 @@
"type": "number",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-timeout-number"
+ "id": "chatOpenAI_0-input-timeout-number"
},
{
"label": "BasePath",
@@ -191,25 +273,26 @@
"type": "string",
"optional": true,
"additionalParams": true,
- "id": "chatOpenAI_1-input-basepath-string"
+ "id": "chatOpenAI_0-input-basepath-string"
}
],
"inputAnchors": [],
"inputs": {
"modelName": "gpt-3.5-turbo",
- "temperature": 0.9,
+ "temperature": "0",
"maxTokens": "",
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -217,111 +300,31 @@
},
"selected": false,
"positionAbsolute": {
- "x": 439.5219561593599,
- "y": 93.61600226758335
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 407,
- "id": "llmChain_1",
- "position": {
- "x": 865.7775572410412,
- "y": 543.9211372857111
- },
- "type": "customNode",
- "data": {
- "id": "llmChain_1",
- "label": "LLM Chain",
- "name": "llmChain",
- "type": "LLMChain",
- "baseClasses": ["LLMChain", "BaseChain", "BaseLangChain"],
- "category": "Chains",
- "description": "Chain to run queries against LLMs",
- "inputParams": [
- {
- "label": "Chain Name",
- "name": "chainName",
- "type": "string",
- "placeholder": "Name Your Chain",
- "optional": true,
- "id": "llmChain_1-input-chainName-string"
- }
- ],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "llmChain_1-input-model-BaseLanguageModel"
- },
- {
- "label": "Prompt",
- "name": "prompt",
- "type": "BasePromptTemplate",
- "id": "llmChain_1-input-prompt-BasePromptTemplate"
- }
- ],
- "inputs": {
- "model": "{{chatOpenAI_1.data.instance}}",
- "prompt": "{{chatPromptTemplate_1.data.instance}}",
- "chainName": "Language Translation"
- },
- "outputAnchors": [
- {
- "name": "output",
- "label": "Output",
- "type": "options",
- "options": [
- {
- "id": "llmChain_1-output-llmChain-LLMChain|BaseChain|BaseLangChain",
- "name": "llmChain",
- "label": "LLM Chain",
- "type": "LLMChain | BaseChain | BaseLangChain"
- },
- {
- "id": "llmChain_1-output-outputPrediction-string",
- "name": "outputPrediction",
- "label": "Output Prediction",
- "type": "string"
- }
- ],
- "default": "llmChain"
- }
- ],
- "outputs": {
- "output": "llmChain"
- },
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 865.7775572410412,
- "y": 543.9211372857111
+ "x": 436.97058562345904,
+ "y": 99.96180150605153
},
"dragging": false
}
],
"edges": [
{
- "source": "chatOpenAI_1",
- "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "source": "chatPromptTemplate_0",
+ "sourceHandle": "chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
"target": "llmChain_1",
- "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
+ "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
"type": "buttonedge",
- "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
+ "id": "chatPromptTemplate_0-chatPromptTemplate_0-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
"data": {
"label": ""
}
},
{
- "source": "chatPromptTemplate_1",
- "sourceHandle": "chatPromptTemplate_1-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate",
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"target": "llmChain_1",
- "targetHandle": "llmChain_1-input-prompt-BasePromptTemplate",
+ "targetHandle": "llmChain_1-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "chatPromptTemplate_1-chatPromptTemplate_1-output-chatPromptTemplate-ChatPromptTemplate|BaseChatPromptTemplate|BasePromptTemplate-llmChain_1-llmChain_1-input-prompt-BasePromptTemplate",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-llmChain_1-llmChain_1-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/WebBrowser.json b/packages/server/marketplaces/chatflows/WebBrowser.json
similarity index 81%
rename from packages/server/marketplaces/WebBrowser.json
rename to packages/server/marketplaces/chatflows/WebBrowser.json
index f87fe07e..95743f9f 100644
--- a/packages/server/marketplaces/WebBrowser.json
+++ b/packages/server/marketplaces/chatflows/WebBrowser.json
@@ -3,27 +3,216 @@
"nodes": [
{
"width": 300,
- "height": 524,
+ "height": 376,
+ "id": "bufferMemory_0",
+ "position": {
+ "x": 457.04304716743604,
+ "y": 362.4048129799687
+ },
+ "type": "customNode",
+ "data": {
+ "id": "bufferMemory_0",
+ "label": "Buffer Memory",
+ "name": "bufferMemory",
+ "version": 1,
+ "type": "BufferMemory",
+ "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Remembers previous conversational back and forths directly",
+ "inputParams": [
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "id": "bufferMemory_0-input-memoryKey-string"
+ },
+ {
+ "label": "Input Key",
+ "name": "inputKey",
+ "type": "string",
+ "default": "input",
+ "id": "bufferMemory_0-input-inputKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "memoryKey": "chat_history",
+ "inputKey": "input"
+ },
+ "outputAnchors": [
+ {
+ "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
+ "name": "bufferMemory",
+ "label": "BufferMemory",
+ "type": "BufferMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 457.04304716743604,
+ "y": 362.4048129799687
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 280,
+ "id": "webBrowser_0",
+ "position": {
+ "x": 1091.0866823400172,
+ "y": -16.43806989958216
+ },
+ "type": "customNode",
+ "data": {
+ "id": "webBrowser_0",
+ "label": "Web Browser",
+ "name": "webBrowser",
+ "version": 1,
+ "type": "WebBrowser",
+ "baseClasses": ["WebBrowser", "Tool", "StructuredTool", "BaseLangChain"],
+ "category": "Tools",
+ "description": "Gives agent the ability to visit a website and extract information",
+ "inputParams": [],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "webBrowser_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "webBrowser_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "webBrowser_0-output-webBrowser-WebBrowser|Tool|StructuredTool|BaseLangChain",
+ "name": "webBrowser",
+ "label": "WebBrowser",
+ "type": "WebBrowser | Tool | StructuredTool | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1091.0866823400172,
+ "y": -16.43806989958216
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 383,
+ "id": "conversationalAgent_0",
+ "position": {
+ "x": 1464.513303631911,
+ "y": 155.73036805253955
+ },
+ "type": "customNode",
+ "data": {
+ "id": "conversationalAgent_0",
+ "label": "Conversational Agent",
+ "name": "conversationalAgent",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain"],
+ "category": "Agents",
+ "description": "Conversational agent for a chat model. It will utilize chat specific prompts",
+ "inputParams": [
+ {
+ "label": "System Message",
+ "name": "systemMessage",
+ "type": "string",
+ "rows": 4,
+ "default": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.",
+ "optional": true,
+ "additionalParams": true,
+ "id": "conversationalAgent_0-input-systemMessage-string"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "conversationalAgent_0-input-tools-Tool"
+ },
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "conversationalAgent_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseChatMemory",
+ "id": "conversationalAgent_0-input-memory-BaseChatMemory"
+ }
+ ],
+ "inputs": {
+ "tools": ["{{webBrowser_0.data.instance}}"],
+ "model": "{{chatOpenAI_1.data.instance}}",
+ "memory": "{{bufferMemory_0.data.instance}}",
+ "systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."
+ },
+ "outputAnchors": [
+ {
+ "id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain",
+ "name": "conversationalAgent",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1464.513303631911,
+ "y": 155.73036805253955
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 523,
"id": "chatOpenAI_0",
"position": {
- "x": 348.0817836845733,
- "y": -86.56099395751443
+ "x": 734.7477982032904,
+ "y": -400.9979556765114
},
"type": "customNode",
"data": {
"id": "chatOpenAI_0",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -132,14 +321,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -147,90 +337,36 @@
},
"selected": false,
"positionAbsolute": {
- "x": 348.0817836845733,
- "y": -86.56099395751443
+ "x": 734.7477982032904,
+ "y": -400.9979556765114
},
"dragging": false
},
{
"width": 300,
- "height": 376,
- "id": "bufferMemory_0",
- "position": {
- "x": 15.045898260926037,
- "y": 114.13407401971622
- },
- "type": "customNode",
- "data": {
- "id": "bufferMemory_0",
- "label": "Buffer Memory",
- "name": "bufferMemory",
- "type": "BufferMemory",
- "baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
- "category": "Memory",
- "description": "Remembers previous conversational back and forths directly",
- "inputParams": [
- {
- "label": "Memory Key",
- "name": "memoryKey",
- "type": "string",
- "default": "chat_history",
- "id": "bufferMemory_0-input-memoryKey-string"
- },
- {
- "label": "Input Key",
- "name": "inputKey",
- "type": "string",
- "default": "input",
- "id": "bufferMemory_0-input-inputKey-string"
- }
- ],
- "inputAnchors": [],
- "inputs": {
- "memoryKey": "chat_history",
- "inputKey": "input"
- },
- "outputAnchors": [
- {
- "id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
- "name": "bufferMemory",
- "label": "BufferMemory",
- "type": "BufferMemory | BaseChatMemory | BaseMemory"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 15.045898260926037,
- "y": 114.13407401971622
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 330,
+ "height": 329,
"id": "openAIEmbeddings_0",
"position": {
- "x": 693.9266260641734,
- "y": 37.098856540087496
+ "x": 403.72014625628697,
+ "y": -103.82540449681527
},
"type": "customNode",
"data": {
"id": "openAIEmbeddings_0",
"label": "OpenAI Embeddings",
"name": "openAIEmbeddings",
+ "version": 1,
"type": "OpenAIEmbeddings",
"baseClasses": ["OpenAIEmbeddings", "Embeddings"],
"category": "Embeddings",
"description": "OpenAI API to generate embeddings for a given text",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAIEmbeddings_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
},
{
"label": "Strip New Lines",
@@ -269,7 +405,8 @@
"inputs": {
"stripNewLines": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
@@ -284,34 +421,36 @@
},
"selected": false,
"positionAbsolute": {
- "x": 693.9266260641734,
- "y": 37.098856540087496
+ "x": 403.72014625628697,
+ "y": -103.82540449681527
},
"dragging": false
},
{
"width": 300,
- "height": 524,
+ "height": 523,
"id": "chatOpenAI_1",
"position": {
- "x": 691.5132411896494,
- "y": -533.1696369549378
+ "x": 68.312124033115,
+ "y": -169.65476709991256
},
"type": "customNode",
"data": {
"id": "chatOpenAI_1",
"label": "ChatOpenAI",
"name": "chatOpenAI",
+ "version": 1,
"type": "ChatOpenAI",
- "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
"category": "Chat Models",
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "chatOpenAI_1-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_1-input-credential-credential"
},
{
"label": "Model Name",
@@ -420,14 +559,15 @@
"topP": "",
"frequencyPenalty": "",
"presencePenalty": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
+ "id": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
"name": "chatOpenAI",
"label": "ChatOpenAI",
- "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
}
],
"outputs": {},
@@ -435,161 +575,13 @@
},
"selected": false,
"positionAbsolute": {
- "x": 691.5132411896494,
- "y": -533.1696369549378
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 280,
- "id": "webBrowser_0",
- "position": {
- "x": 1091.0866823400172,
- "y": -16.43806989958216
- },
- "type": "customNode",
- "data": {
- "id": "webBrowser_0",
- "label": "Web Browser",
- "name": "webBrowser",
- "type": "WebBrowser",
- "baseClasses": ["WebBrowser", "Tool", "StructuredTool", "BaseLangChain"],
- "category": "Tools",
- "description": "Gives agent the ability to visit a website and extract information",
- "inputParams": [],
- "inputAnchors": [
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "webBrowser_0-input-model-BaseLanguageModel"
- },
- {
- "label": "Embeddings",
- "name": "embeddings",
- "type": "Embeddings",
- "id": "webBrowser_0-input-embeddings-Embeddings"
- }
- ],
- "inputs": {
- "model": "{{chatOpenAI_1.data.instance}}",
- "embeddings": "{{openAIEmbeddings_0.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "webBrowser_0-output-webBrowser-WebBrowser|Tool|StructuredTool|BaseLangChain",
- "name": "webBrowser",
- "label": "WebBrowser",
- "type": "WebBrowser | Tool | StructuredTool | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1091.0866823400172,
- "y": -16.43806989958216
- },
- "dragging": false
- },
- {
- "width": 300,
- "height": 383,
- "id": "conversationalAgent_0",
- "position": {
- "x": 1451.6222493253506,
- "y": 239.69137914100338
- },
- "type": "customNode",
- "data": {
- "id": "conversationalAgent_0",
- "label": "Conversational Agent",
- "name": "conversationalAgent",
- "type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
- "category": "Agents",
- "description": "Conversational agent for a chat model. It will utilize chat specific prompts",
- "inputParams": [
- {
- "label": "System Message",
- "name": "systemMessage",
- "type": "string",
- "rows": 4,
- "optional": true,
- "additionalParams": true,
- "id": "conversationalAgent_0-input-systemMessage-string"
- },
- {
- "label": "Human Message",
- "name": "humanMessage",
- "type": "string",
- "rows": 4,
- "optional": true,
- "additionalParams": true,
- "id": "conversationalAgent_0-input-humanMessage-string"
- }
- ],
- "inputAnchors": [
- {
- "label": "Allowed Tools",
- "name": "tools",
- "type": "Tool",
- "list": true,
- "id": "conversationalAgent_0-input-tools-Tool"
- },
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "conversationalAgent_0-input-model-BaseLanguageModel"
- },
- {
- "label": "Memory",
- "name": "memory",
- "type": "BaseChatMemory",
- "id": "conversationalAgent_0-input-memory-BaseChatMemory"
- }
- ],
- "inputs": {
- "tools": ["{{webBrowser_0.data.instance}}"],
- "model": "{{chatOpenAI_0.data.instance}}",
- "memory": "{{bufferMemory_0.data.instance}}",
- "systemMessage": "",
- "humanMessage": ""
- },
- "outputAnchors": [
- {
- "id": "conversationalAgent_0-output-conversationalAgent-AgentExecutor|BaseChain|BaseLangChain",
- "name": "conversationalAgent",
- "label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "selected": false,
- "positionAbsolute": {
- "x": 1451.6222493253506,
- "y": 239.69137914100338
+ "x": 68.312124033115,
+ "y": -169.65476709991256
},
"dragging": false
}
],
"edges": [
- {
- "source": "chatOpenAI_1",
- "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "webBrowser_0",
- "targetHandle": "webBrowser_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-webBrowser_0-webBrowser_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
{
"source": "openAIEmbeddings_0",
"sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
@@ -601,6 +593,28 @@
"label": ""
}
},
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "webBrowser_0",
+ "targetHandle": "webBrowser_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-webBrowser_0-webBrowser_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_1",
+ "sourceHandle": "chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "conversationalAgent_0",
+ "targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_1-chatOpenAI_1-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
{
"source": "webBrowser_0",
"sourceHandle": "webBrowser_0-output-webBrowser-WebBrowser|Tool|StructuredTool|BaseLangChain",
@@ -612,17 +626,6 @@
"label": ""
}
},
- {
- "source": "chatOpenAI_0",
- "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
- "target": "conversationalAgent_0",
- "targetHandle": "conversationalAgent_0-input-model-BaseLanguageModel",
- "type": "buttonedge",
- "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationalAgent_0-conversationalAgent_0-input-model-BaseLanguageModel",
- "data": {
- "label": ""
- }
- },
{
"source": "bufferMemory_0",
"sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
diff --git a/packages/server/marketplaces/chatflows/WebPage QnA.json b/packages/server/marketplaces/chatflows/WebPage QnA.json
new file mode 100644
index 00000000..b04ad5e2
--- /dev/null
+++ b/packages/server/marketplaces/chatflows/WebPage QnA.json
@@ -0,0 +1,771 @@
+{
+ "description": "Scrape web pages for QnA with long term memory Motorhead and return source documents",
+ "nodes": [
+ {
+ "width": 300,
+ "height": 522,
+ "id": "chatOpenAI_0",
+ "position": {
+ "x": 1509.7110310286191,
+ "y": -171.0099374102956
+ },
+ "type": "customNode",
+ "data": {
+ "id": "chatOpenAI_0",
+ "label": "ChatOpenAI",
+ "name": "chatOpenAI",
+ "version": 1,
+ "type": "ChatOpenAI",
+ "baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel"],
+ "category": "Chat Models",
+ "description": "Wrapper around OpenAI large language models that use the Chat endpoint",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "chatOpenAI_0-input-credential-credential"
+ },
+ {
+ "label": "Model Name",
+ "name": "modelName",
+ "type": "options",
+ "options": [
+ {
+ "label": "gpt-4",
+ "name": "gpt-4"
+ },
+ {
+ "label": "gpt-4-0613",
+ "name": "gpt-4-0613"
+ },
+ {
+ "label": "gpt-4-32k",
+ "name": "gpt-4-32k"
+ },
+ {
+ "label": "gpt-4-32k-0613",
+ "name": "gpt-4-32k-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo",
+ "name": "gpt-3.5-turbo"
+ },
+ {
+ "label": "gpt-3.5-turbo-0613",
+ "name": "gpt-3.5-turbo-0613"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k",
+ "name": "gpt-3.5-turbo-16k"
+ },
+ {
+ "label": "gpt-3.5-turbo-16k-0613",
+ "name": "gpt-3.5-turbo-16k-0613"
+ }
+ ],
+ "default": "gpt-3.5-turbo",
+ "optional": true,
+ "id": "chatOpenAI_0-input-modelName-options"
+ },
+ {
+ "label": "Temperature",
+ "name": "temperature",
+ "type": "number",
+ "default": 0.9,
+ "optional": true,
+ "id": "chatOpenAI_0-input-temperature-number"
+ },
+ {
+ "label": "Max Tokens",
+ "name": "maxTokens",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-maxTokens-number"
+ },
+ {
+ "label": "Top Probability",
+ "name": "topP",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-topP-number"
+ },
+ {
+ "label": "Frequency Penalty",
+ "name": "frequencyPenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-frequencyPenalty-number"
+ },
+ {
+ "label": "Presence Penalty",
+ "name": "presencePenalty",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-presencePenalty-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "chatOpenAI_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "modelName": "gpt-3.5-turbo",
+ "temperature": "0",
+ "maxTokens": "",
+ "topP": "",
+ "frequencyPenalty": "",
+ "presencePenalty": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "name": "chatOpenAI",
+ "label": "ChatOpenAI",
+ "type": "ChatOpenAI | BaseChatModel | BaseLanguageModel"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 1509.7110310286191,
+ "y": -171.0099374102956
+ },
+ "selected": false,
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 328,
+ "id": "openAIEmbeddings_0",
+ "position": {
+ "x": 827.6835380475393,
+ "y": 253.8955254525015
+ },
+ "type": "customNode",
+ "data": {
+ "id": "openAIEmbeddings_0",
+ "label": "OpenAI Embeddings",
+ "name": "openAIEmbeddings",
+ "version": 1,
+ "type": "OpenAIEmbeddings",
+ "baseClasses": ["OpenAIEmbeddings", "Embeddings"],
+ "category": "Embeddings",
+ "description": "OpenAI API to generate embeddings for a given text",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAIEmbeddings_0-input-credential-credential"
+ },
+ {
+ "label": "Strip New Lines",
+ "name": "stripNewLines",
+ "type": "boolean",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-stripNewLines-boolean"
+ },
+ {
+ "label": "Batch Size",
+ "name": "batchSize",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-batchSize-number"
+ },
+ {
+ "label": "Timeout",
+ "name": "timeout",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-timeout-number"
+ },
+ {
+ "label": "BasePath",
+ "name": "basepath",
+ "type": "string",
+ "optional": true,
+ "additionalParams": true,
+ "id": "openAIEmbeddings_0-input-basepath-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "stripNewLines": "",
+ "batchSize": "",
+ "timeout": "",
+ "basepath": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "name": "openAIEmbeddings",
+ "label": "OpenAIEmbeddings",
+ "type": "OpenAIEmbeddings | Embeddings"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 827.6835380475393,
+ "y": 253.8955254525015
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 554,
+ "id": "pineconeUpsert_0",
+ "position": {
+ "x": 1178.0855412625938,
+ "y": -1.6626550640073674
+ },
+ "type": "customNode",
+ "data": {
+ "id": "pineconeUpsert_0",
+ "label": "Pinecone Upsert Document",
+ "name": "pineconeUpsert",
+ "version": 1,
+ "type": "Pinecone",
+ "baseClasses": ["Pinecone", "VectorStoreRetriever", "BaseRetriever"],
+ "category": "Vector Stores",
+ "description": "Upsert documents to Pinecone",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["pineconeApi"],
+ "id": "pineconeUpsert_0-input-credential-credential"
+ },
+ {
+ "label": "Pinecone Index",
+ "name": "pineconeIndex",
+ "type": "string",
+ "id": "pineconeUpsert_0-input-pineconeIndex-string"
+ },
+ {
+ "label": "Pinecone Namespace",
+ "name": "pineconeNamespace",
+ "type": "string",
+ "placeholder": "my-first-namespace",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeUpsert_0-input-pineconeNamespace-string"
+ },
+ {
+ "label": "Top K",
+ "name": "topK",
+ "description": "Number of top results to fetch. Default to 4",
+ "placeholder": "4",
+ "type": "number",
+ "additionalParams": true,
+ "optional": true,
+ "id": "pineconeUpsert_0-input-topK-number"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Document",
+ "name": "document",
+ "type": "Document",
+ "list": true,
+ "id": "pineconeUpsert_0-input-document-Document"
+ },
+ {
+ "label": "Embeddings",
+ "name": "embeddings",
+ "type": "Embeddings",
+ "id": "pineconeUpsert_0-input-embeddings-Embeddings"
+ }
+ ],
+ "inputs": {
+ "document": ["{{cheerioWebScraper_0.data.instance}}"],
+ "embeddings": "{{openAIEmbeddings_0.data.instance}}",
+ "pineconeIndex": "",
+ "pineconeNamespace": "",
+ "topK": ""
+ },
+ "outputAnchors": [
+ {
+ "name": "output",
+ "label": "Output",
+ "type": "options",
+ "options": [
+ {
+ "id": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "name": "retriever",
+ "label": "Pinecone Retriever",
+ "type": "Pinecone | VectorStoreRetriever | BaseRetriever"
+ },
+ {
+ "id": "pineconeUpsert_0-output-vectorStore-Pinecone|VectorStore",
+ "name": "vectorStore",
+ "label": "Pinecone Vector Store",
+ "type": "Pinecone | VectorStore"
+ }
+ ],
+ "default": "retriever"
+ }
+ ],
+ "outputs": {
+ "output": "retriever"
+ },
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1178.0855412625938,
+ "y": -1.6626550640073674
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 379,
+ "id": "cheerioWebScraper_0",
+ "position": {
+ "x": 829.4409518246235,
+ "y": -168.78678247276423
+ },
+ "type": "customNode",
+ "data": {
+ "id": "cheerioWebScraper_0",
+ "label": "Cheerio Web Scraper",
+ "name": "cheerioWebScraper",
+ "version": 1,
+ "type": "Document",
+ "baseClasses": ["Document"],
+ "category": "Document Loaders",
+ "description": "Load data from webpages",
+ "inputParams": [
+ {
+ "label": "URL",
+ "name": "url",
+ "type": "string",
+ "id": "cheerioWebScraper_0-input-url-string"
+ },
+ {
+ "label": "Get Relative Links Method",
+ "name": "relativeLinksMethod",
+ "type": "options",
+ "description": "Select a method to retrieve relative links",
+ "options": [
+ {
+ "label": "Web Crawl",
+ "name": "webCrawl",
+ "description": "Crawl relative links from HTML URL"
+ },
+ {
+ "label": "Scrape XML Sitemap",
+ "name": "scrapeXMLSitemap",
+ "description": "Scrape relative links from XML sitemap URL"
+ }
+ ],
+ "optional": true,
+ "additionalParams": true,
+ "id": "cheerioWebScraper_0-input-relativeLinksMethod-options"
+ },
+ {
+ "label": "Get Relative Links Limit",
+ "name": "limit",
+ "type": "number",
+ "optional": true,
+ "additionalParams": true,
+ "description": "Only used when \"Get Relative Links Method\" is selected. Set 0 to retrieve all relative links, default limit is 10.",
+ "warning": "Retreiving all links might take long time, and all links will be upserted again if the flow's state changed (eg: different URL, chunk size, etc)",
+ "id": "cheerioWebScraper_0-input-limit-number"
+ },
+ {
+ "label": "Metadata",
+ "name": "metadata",
+ "type": "json",
+ "optional": true,
+ "additionalParams": true,
+ "id": "cheerioWebScraper_0-input-metadata-json"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Text Splitter",
+ "name": "textSplitter",
+ "type": "TextSplitter",
+ "optional": true,
+ "id": "cheerioWebScraper_0-input-textSplitter-TextSplitter"
+ }
+ ],
+ "inputs": {
+ "url": "https://www.itsjane.com",
+ "textSplitter": "{{htmlToMarkdownTextSplitter_0.data.instance}}",
+ "relativeLinksMethod": "",
+ "limit": "",
+ "metadata": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "cheerioWebScraper_0-output-cheerioWebScraper-Document",
+ "name": "cheerioWebScraper",
+ "label": "Document",
+ "type": "Document"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 829.4409518246235,
+ "y": -168.78678247276423
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 376,
+ "id": "htmlToMarkdownTextSplitter_0",
+ "position": {
+ "x": 443.00626484042334,
+ "y": 1.2942107707648631
+ },
+ "type": "customNode",
+ "data": {
+ "id": "htmlToMarkdownTextSplitter_0",
+ "label": "HtmlToMarkdown Text Splitter",
+ "name": "htmlToMarkdownTextSplitter",
+ "version": 1,
+ "type": "HtmlToMarkdownTextSplitter",
+ "baseClasses": [
+ "HtmlToMarkdownTextSplitter",
+ "MarkdownTextSplitter",
+ "RecursiveCharacterTextSplitter",
+ "TextSplitter",
+ "BaseDocumentTransformer"
+ ],
+ "category": "Text Splitters",
+ "description": "Converts Html to Markdown and then split your content into documents based on the Markdown headers",
+ "inputParams": [
+ {
+ "label": "Chunk Size",
+ "name": "chunkSize",
+ "type": "number",
+ "default": 1000,
+ "optional": true,
+ "id": "htmlToMarkdownTextSplitter_0-input-chunkSize-number"
+ },
+ {
+ "label": "Chunk Overlap",
+ "name": "chunkOverlap",
+ "type": "number",
+ "optional": true,
+ "id": "htmlToMarkdownTextSplitter_0-input-chunkOverlap-number"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "chunkSize": 1000,
+ "chunkOverlap": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "htmlToMarkdownTextSplitter_0-output-htmlToMarkdownTextSplitter-HtmlToMarkdownTextSplitter|MarkdownTextSplitter|RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer",
+ "name": "htmlToMarkdownTextSplitter",
+ "label": "HtmlToMarkdownTextSplitter",
+ "type": "HtmlToMarkdownTextSplitter | MarkdownTextSplitter | RecursiveCharacterTextSplitter | TextSplitter | BaseDocumentTransformer"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 443.00626484042334,
+ "y": 1.2942107707648631
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 479,
+ "id": "conversationalRetrievalQAChain_0",
+ "position": {
+ "x": 1882.5543981868987,
+ "y": 305.08959224761225
+ },
+ "type": "customNode",
+ "data": {
+ "id": "conversationalRetrievalQAChain_0",
+ "label": "Conversational Retrieval QA Chain",
+ "name": "conversationalRetrievalQAChain",
+ "version": 1,
+ "type": "ConversationalRetrievalQAChain",
+ "baseClasses": ["ConversationalRetrievalQAChain", "BaseChain"],
+ "category": "Chains",
+ "description": "Document QA - built on RetrievalQAChain to provide a chat history component",
+ "inputParams": [
+ {
+ "label": "Return Source Documents",
+ "name": "returnSourceDocuments",
+ "type": "boolean",
+ "optional": true,
+ "id": "conversationalRetrievalQAChain_0-input-returnSourceDocuments-boolean"
+ },
+ {
+ "label": "System Message",
+ "name": "systemMessagePrompt",
+ "type": "string",
+ "rows": 4,
+ "additionalParams": true,
+ "optional": true,
+ "placeholder": "I want you to act as a document that I am having a conversation with. Your name is \"AI Assistant\". You will provide me with answers from the given info. If the answer is not included, say exactly \"Hmm, I am not sure.\" and stop after that. Refuse to answer any question not about the info. Never break character.",
+ "id": "conversationalRetrievalQAChain_0-input-systemMessagePrompt-string"
+ },
+ {
+ "label": "Chain Option",
+ "name": "chainOption",
+ "type": "options",
+ "options": [
+ {
+ "label": "MapReduceDocumentsChain",
+ "name": "map_reduce",
+ "description": "Suitable for QA tasks over larger documents and can run the preprocessing step in parallel, reducing the running time"
+ },
+ {
+ "label": "RefineDocumentsChain",
+ "name": "refine",
+ "description": "Suitable for QA tasks over a large number of documents."
+ },
+ {
+ "label": "StuffDocumentsChain",
+ "name": "stuff",
+ "description": "Suitable for QA tasks over a small number of documents."
+ }
+ ],
+ "additionalParams": true,
+ "optional": true,
+ "id": "conversationalRetrievalQAChain_0-input-chainOption-options"
+ }
+ ],
+ "inputAnchors": [
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel"
+ },
+ {
+ "label": "Vector Store Retriever",
+ "name": "vectorStoreRetriever",
+ "type": "BaseRetriever",
+ "id": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever"
+ },
+ {
+ "label": "Memory",
+ "name": "memory",
+ "type": "BaseMemory",
+ "optional": true,
+ "description": "If left empty, a default BufferMemory will be used",
+ "id": "conversationalRetrievalQAChain_0-input-memory-BaseMemory"
+ }
+ ],
+ "inputs": {
+ "model": "{{chatOpenAI_0.data.instance}}",
+ "vectorStoreRetriever": "{{pineconeUpsert_0.data.instance}}",
+ "memory": "{{motorheadMemory_0.data.instance}}",
+ "returnSourceDocuments": true,
+ "systemMessagePrompt": "",
+ "chainOption": ""
+ },
+ "outputAnchors": [
+ {
+ "id": "conversationalRetrievalQAChain_0-output-conversationalRetrievalQAChain-ConversationalRetrievalQAChain|BaseChain",
+ "name": "conversationalRetrievalQAChain",
+ "label": "ConversationalRetrievalQAChain",
+ "type": "ConversationalRetrievalQAChain | BaseChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1882.5543981868987,
+ "y": 305.08959224761225
+ },
+ "dragging": false
+ },
+ {
+ "width": 300,
+ "height": 426,
+ "id": "motorheadMemory_0",
+ "position": {
+ "x": 1515.4202055109095,
+ "y": 539.7912360964175
+ },
+ "type": "customNode",
+ "data": {
+ "id": "motorheadMemory_0",
+ "label": "Motorhead Memory",
+ "name": "motorheadMemory",
+ "version": 1,
+ "type": "MotorheadMemory",
+ "baseClasses": ["MotorheadMemory", "BaseChatMemory", "BaseMemory"],
+ "category": "Memory",
+ "description": "Use Motorhead Memory to store chat conversations",
+ "inputParams": [
+ {
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "optional": true,
+ "description": "Only needed when using hosted solution - https://getmetal.io",
+ "credentialNames": ["motorheadMemoryApi"],
+ "id": "motorheadMemory_0-input-credential-credential"
+ },
+ {
+ "label": "Base URL",
+ "name": "baseURL",
+ "type": "string",
+ "optional": true,
+ "description": "To use the online version, leave the URL blank. More details at https://getmetal.io.",
+ "id": "motorheadMemory_0-input-baseURL-string"
+ },
+ {
+ "label": "Session Id",
+ "name": "sessionId",
+ "type": "string",
+ "description": "if empty, chatId will be used automatically",
+ "default": "",
+ "additionalParams": true,
+ "optional": true,
+ "id": "motorheadMemory_0-input-sessionId-string"
+ },
+ {
+ "label": "Memory Key",
+ "name": "memoryKey",
+ "type": "string",
+ "default": "chat_history",
+ "additionalParams": true,
+ "id": "motorheadMemory_0-input-memoryKey-string"
+ }
+ ],
+ "inputAnchors": [],
+ "inputs": {
+ "baseURL": "",
+ "sessionId": "",
+ "memoryKey": "chat_history"
+ },
+ "outputAnchors": [
+ {
+ "id": "motorheadMemory_0-output-motorheadMemory-MotorheadMemory|BaseChatMemory|BaseMemory",
+ "name": "motorheadMemory",
+ "label": "MotorheadMemory",
+ "type": "MotorheadMemory | BaseChatMemory | BaseMemory"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "selected": false,
+ "positionAbsolute": {
+ "x": 1515.4202055109095,
+ "y": 539.7912360964175
+ },
+ "dragging": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "openAIEmbeddings_0",
+ "sourceHandle": "openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings",
+ "target": "pineconeUpsert_0",
+ "targetHandle": "pineconeUpsert_0-input-embeddings-Embeddings",
+ "type": "buttonedge",
+ "id": "openAIEmbeddings_0-openAIEmbeddings_0-output-openAIEmbeddings-OpenAIEmbeddings|Embeddings-pineconeUpsert_0-pineconeUpsert_0-input-embeddings-Embeddings",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "cheerioWebScraper_0",
+ "sourceHandle": "cheerioWebScraper_0-output-cheerioWebScraper-Document",
+ "target": "pineconeUpsert_0",
+ "targetHandle": "pineconeUpsert_0-input-document-Document",
+ "type": "buttonedge",
+ "id": "cheerioWebScraper_0-cheerioWebScraper_0-output-cheerioWebScraper-Document-pineconeUpsert_0-pineconeUpsert_0-input-document-Document",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "htmlToMarkdownTextSplitter_0",
+ "sourceHandle": "htmlToMarkdownTextSplitter_0-output-htmlToMarkdownTextSplitter-HtmlToMarkdownTextSplitter|MarkdownTextSplitter|RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer",
+ "target": "cheerioWebScraper_0",
+ "targetHandle": "cheerioWebScraper_0-input-textSplitter-TextSplitter",
+ "type": "buttonedge",
+ "id": "htmlToMarkdownTextSplitter_0-htmlToMarkdownTextSplitter_0-output-htmlToMarkdownTextSplitter-HtmlToMarkdownTextSplitter|MarkdownTextSplitter|RecursiveCharacterTextSplitter|TextSplitter|BaseDocumentTransformer-cheerioWebScraper_0-cheerioWebScraper_0-input-textSplitter-TextSplitter",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "chatOpenAI_0",
+ "sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "type": "buttonedge",
+ "id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-model-BaseLanguageModel",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "pineconeUpsert_0",
+ "sourceHandle": "pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "type": "buttonedge",
+ "id": "pineconeUpsert_0-pineconeUpsert_0-output-retriever-Pinecone|VectorStoreRetriever|BaseRetriever-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-vectorStoreRetriever-BaseRetriever",
+ "data": {
+ "label": ""
+ }
+ },
+ {
+ "source": "motorheadMemory_0",
+ "sourceHandle": "motorheadMemory_0-output-motorheadMemory-MotorheadMemory|BaseChatMemory|BaseMemory",
+ "target": "conversationalRetrievalQAChain_0",
+ "targetHandle": "conversationalRetrievalQAChain_0-input-memory-BaseMemory",
+ "type": "buttonedge",
+ "id": "motorheadMemory_0-motorheadMemory_0-output-motorheadMemory-MotorheadMemory|BaseChatMemory|BaseMemory-conversationalRetrievalQAChain_0-conversationalRetrievalQAChain_0-input-memory-BaseMemory",
+ "data": {
+ "label": ""
+ }
+ }
+ ]
+}
diff --git a/packages/server/marketplaces/Zapier NLA.json b/packages/server/marketplaces/chatflows/Zapier NLA.json
similarity index 93%
rename from packages/server/marketplaces/Zapier NLA.json
rename to packages/server/marketplaces/chatflows/Zapier NLA.json
index 19b30107..60258b46 100644
--- a/packages/server/marketplaces/Zapier NLA.json
+++ b/packages/server/marketplaces/chatflows/Zapier NLA.json
@@ -14,6 +14,7 @@
"id": "zapierNLA_0",
"label": "Zapier NLA",
"name": "zapierNLA",
+ "version": 1,
"type": "ZapierNLA",
"baseClasses": ["ZapierNLA", "Tool"],
"category": "Tools",
@@ -48,27 +49,84 @@
},
{
"width": 300,
- "height": 524,
+ "height": 280,
+ "id": "mrklAgentLLM_0",
+ "position": {
+ "x": 1002.5779315680477,
+ "y": 329.9701389591812
+ },
+ "type": "customNode",
+ "data": {
+ "id": "mrklAgentLLM_0",
+ "label": "MRKL Agent for LLMs",
+ "name": "mrklAgentLLM",
+ "version": 1,
+ "type": "AgentExecutor",
+ "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
+ "category": "Agents",
+ "description": "Agent that uses the ReAct Framework to decide what action to take, optimized to be used with LLMs",
+ "inputParams": [],
+ "inputAnchors": [
+ {
+ "label": "Allowed Tools",
+ "name": "tools",
+ "type": "Tool",
+ "list": true,
+ "id": "mrklAgentLLM_0-input-tools-Tool"
+ },
+ {
+ "label": "Language Model",
+ "name": "model",
+ "type": "BaseLanguageModel",
+ "id": "mrklAgentLLM_0-input-model-BaseLanguageModel"
+ }
+ ],
+ "inputs": {
+ "tools": ["{{zapierNLA_0.data.instance}}"],
+ "model": "{{openAI_0.data.instance}}"
+ },
+ "outputAnchors": [
+ {
+ "id": "mrklAgentLLM_0-output-mrklAgentLLM-AgentExecutor|BaseChain|BaseLangChain",
+ "name": "mrklAgentLLM",
+ "label": "AgentExecutor",
+ "type": "AgentExecutor | BaseChain | BaseLangChain"
+ }
+ ],
+ "outputs": {},
+ "selected": false
+ },
+ "positionAbsolute": {
+ "x": 1002.5779315680477,
+ "y": 329.9701389591812
+ },
+ "selected": false
+ },
+ {
+ "width": 300,
+ "height": 523,
"id": "openAI_0",
"position": {
- "x": 547.3867724775708,
- "y": 394.1919189424442
+ "x": 550.5957793208096,
+ "y": 378.30370661617934
},
"type": "customNode",
"data": {
"id": "openAI_0",
"label": "OpenAI",
"name": "openAI",
+ "version": 1,
"type": "OpenAI",
- "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel", "BaseLangChain"],
+ "baseClasses": ["OpenAI", "BaseLLM", "BaseLanguageModel"],
"category": "LLMs",
"description": "Wrapper around OpenAI large language models",
"inputParams": [
{
- "label": "OpenAI Api Key",
- "name": "openAIApiKey",
- "type": "password",
- "id": "openAI_0-input-openAIApiKey-password"
+ "label": "Connect Credential",
+ "name": "credential",
+ "type": "credential",
+ "credentialNames": ["openAIApi"],
+ "id": "openAI_0-input-credential-credential"
},
{
"label": "Model Name",
@@ -179,14 +237,15 @@
"frequencyPenalty": "",
"presencePenalty": "",
"batchSize": "",
- "timeout": ""
+ "timeout": "",
+ "basepath": ""
},
"outputAnchors": [
{
- "id": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "id": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"name": "openAI",
"label": "OpenAI",
- "type": "OpenAI | BaseLLM | BaseLanguageModel | BaseLangChain"
+ "type": "OpenAI | BaseLLM | BaseLanguageModel"
}
],
"outputs": {},
@@ -194,64 +253,10 @@
},
"selected": false,
"positionAbsolute": {
- "x": 547.3867724775708,
- "y": 394.1919189424442
+ "x": 550.5957793208096,
+ "y": 378.30370661617934
},
"dragging": false
- },
- {
- "width": 300,
- "height": 280,
- "id": "mrklAgentLLM_0",
- "position": {
- "x": 1002.5779315680477,
- "y": 329.9701389591812
- },
- "type": "customNode",
- "data": {
- "id": "mrklAgentLLM_0",
- "label": "MRKL Agent for LLMs",
- "name": "mrklAgentLLM",
- "type": "AgentExecutor",
- "baseClasses": ["AgentExecutor", "BaseChain", "BaseLangChain"],
- "category": "Agents",
- "description": "Agent that uses the ReAct Framework to decide what action to take, optimized to be used with LLMs",
- "inputParams": [],
- "inputAnchors": [
- {
- "label": "Allowed Tools",
- "name": "tools",
- "type": "Tool",
- "list": true,
- "id": "mrklAgentLLM_0-input-tools-Tool"
- },
- {
- "label": "Language Model",
- "name": "model",
- "type": "BaseLanguageModel",
- "id": "mrklAgentLLM_0-input-model-BaseLanguageModel"
- }
- ],
- "inputs": {
- "tools": ["{{zapierNLA_0.data.instance}}"],
- "model": "{{openAI_0.data.instance}}"
- },
- "outputAnchors": [
- {
- "id": "mrklAgentLLM_0-output-mrklAgentLLM-AgentExecutor|BaseChain|BaseLangChain",
- "name": "mrklAgentLLM",
- "label": "AgentExecutor",
- "type": "AgentExecutor | BaseChain | BaseLangChain"
- }
- ],
- "outputs": {},
- "selected": false
- },
- "positionAbsolute": {
- "x": 1002.5779315680477,
- "y": 329.9701389591812
- },
- "selected": false
}
],
"edges": [
@@ -268,11 +273,11 @@
},
{
"source": "openAI_0",
- "sourceHandle": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain",
+ "sourceHandle": "openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel",
"target": "mrklAgentLLM_0",
"targetHandle": "mrklAgentLLM_0-input-model-BaseLanguageModel",
"type": "buttonedge",
- "id": "openAI_0-openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel|BaseLangChain-mrklAgentLLM_0-mrklAgentLLM_0-input-model-BaseLanguageModel",
+ "id": "openAI_0-openAI_0-output-openAI-OpenAI|BaseLLM|BaseLanguageModel-mrklAgentLLM_0-mrklAgentLLM_0-input-model-BaseLanguageModel",
"data": {
"label": ""
}
diff --git a/packages/server/marketplaces/tools/Add Hubspot Contact.json b/packages/server/marketplaces/tools/Add Hubspot Contact.json
new file mode 100644
index 00000000..584df4c3
--- /dev/null
+++ b/packages/server/marketplaces/tools/Add Hubspot Contact.json
@@ -0,0 +1,8 @@
+{
+ "name": "add_contact_hubspot",
+ "description": "Add new contact to Hubspot",
+ "color": "linear-gradient(rgb(85,198,123), rgb(0,230,99))",
+ "iconSrc": "https://cdn.worldvectorlogo.com/logos/hubspot-1.svg",
+ "schema": "[{\"id\":1,\"property\":\"email\",\"description\":\"email address of contact\",\"type\":\"string\",\"required\":true},{\"id\":2,\"property\":\"firstname\",\"description\":\"first name of contact\",\"type\":\"string\",\"required\":false},{\"id\":3,\"property\":\"lastname\",\"description\":\"last name of contact\",\"type\":\"string\",\"required\":false}]",
+ "func": "const fetch = require('node-fetch');\nconst url = 'https://api.hubapi.com/crm/v3/objects/contacts'\nconst token = 'YOUR-TOKEN';\n\nconst body = {\n\t\"properties\": {\n\t \"email\": $email\n\t}\n};\n\nif ($firstname) body.properties.firstname = $firstname;\nif ($lastname) body.properties.lastname = $lastname;\n\nconst options = {\n\tmethod: 'POST',\n\theaders: {\n\t 'Authorization': `Bearer ${token}`,\n\t\t'Content-Type': 'application/json'\n\t},\n\tbody: JSON.stringify(body)\n};\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst text = await response.text();\n\treturn text;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/marketplaces/tools/Create Airtable Record.json b/packages/server/marketplaces/tools/Create Airtable Record.json
new file mode 100644
index 00000000..c52c9199
--- /dev/null
+++ b/packages/server/marketplaces/tools/Create Airtable Record.json
@@ -0,0 +1,8 @@
+{
+ "name": "add_airtable",
+ "description": "Add column1, column2 to Airtable",
+ "color": "linear-gradient(rgb(125,71,222), rgb(128,102,23))",
+ "iconSrc": "https://raw.githubusercontent.com/gilbarbara/logos/main/logos/airtable.svg",
+ "schema": "[{\"id\":0,\"property\":\"column1\",\"description\":\"this is column1\",\"type\":\"string\",\"required\":true},{\"id\":1,\"property\":\"column2\",\"description\":\"this is column2\",\"type\":\"string\",\"required\":true}]",
+ "func": "const fetch = require('node-fetch');\nconst baseId = 'YOUR-BASE-ID';\nconst tableId = 'YOUR-TABLE-ID';\nconst token = 'YOUR-TOKEN';\n\nconst body = {\n\t\"records\": [\n\t\t{\n\t\t\t\"fields\": {\n\t\t\t\t\"column1\": $column1,\n\t\t\t\t\"column2\": $column2,\n\t\t\t}\n\t\t}\n\t]\n};\n\nconst options = {\n\tmethod: 'POST',\n\theaders: {\n\t\t'Authorization': `Bearer ${token}`,\n\t\t'Content-Type': 'application/json'\n\t},\n\tbody: JSON.stringify(body)\n};\n\nconst url = `https://api.airtable.com/v0/${baseId}/${tableId}`\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst text = await response.text();\n\treturn text;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/marketplaces/tools/Get Stock Mover.json b/packages/server/marketplaces/tools/Get Stock Mover.json
new file mode 100644
index 00000000..9108cc50
--- /dev/null
+++ b/packages/server/marketplaces/tools/Get Stock Mover.json
@@ -0,0 +1,8 @@
+{
+ "name": "get_stock_movers",
+ "description": "Get the stocks that has biggest price/volume moves, e.g. actives, gainers, losers, etc.",
+ "iconSrc": "https://rapidapi.com/cdn/images?url=https://rapidapi-prod-apis.s3.amazonaws.com/9c/e743343bdd41edad39a3fdffd5b974/016c33699f51603ae6fe4420c439124b.png",
+ "color": "linear-gradient(rgb(191,202,167), rgb(143,202,246))",
+ "schema": "[]",
+ "func": "const fetch = require('node-fetch');\nconst url = 'https://morning-star.p.rapidapi.com/market/v2/get-movers';\nconst options = {\n\tmethod: 'GET',\n\theaders: {\n\t\t'X-RapidAPI-Key': 'YOUR-API-KEY',\n\t\t'X-RapidAPI-Host': 'morning-star.p.rapidapi.com'\n\t}\n};\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst result = await response.text();\n\tconsole.log(result);\n\treturn result;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/marketplaces/tools/Send Discord Message.json b/packages/server/marketplaces/tools/Send Discord Message.json
new file mode 100644
index 00000000..bbfaaa90
--- /dev/null
+++ b/packages/server/marketplaces/tools/Send Discord Message.json
@@ -0,0 +1,8 @@
+{
+ "name": "send_message_to_discord_channel",
+ "description": "Send message to Discord channel",
+ "color": "linear-gradient(rgb(155,190,84), rgb(176,69,245))",
+ "iconSrc": "https://raw.githubusercontent.com/gilbarbara/logos/main/logos/discord-icon.svg",
+ "schema": "[{\"id\":1,\"property\":\"content\",\"description\":\"message to send\",\"type\":\"string\",\"required\":true}]",
+ "func": "const fetch = require('node-fetch');\nconst webhookUrl = 'YOUR-WEBHOOK-URL'\n\nconst body = {\n\t\"content\": $content\n};\n\nconst options = {\n\tmethod: 'POST',\n\theaders: {\n\t\t'Content-Type': 'application/json'\n\t},\n\tbody: JSON.stringify(body)\n};\n\nconst url = `${webhookUrl}?wait=true`\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst text = await response.text();\n\treturn text;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/marketplaces/tools/Send Slack Message.json b/packages/server/marketplaces/tools/Send Slack Message.json
new file mode 100644
index 00000000..f15d4050
--- /dev/null
+++ b/packages/server/marketplaces/tools/Send Slack Message.json
@@ -0,0 +1,8 @@
+{
+ "name": "send_message_to_slack_channel",
+ "description": "Send message to Slack channel",
+ "color": "linear-gradient(rgb(155,190,84), rgb(176,69,245))",
+ "iconSrc": "https://raw.githubusercontent.com/gilbarbara/logos/main/logos/slack-icon.svg",
+ "schema": "[{\"id\":1,\"property\":\"text\",\"description\":\"message to send\",\"type\":\"string\",\"required\":true}]",
+ "func": "const fetch = require('node-fetch');\nconst webhookUrl = 'YOUR-WEBHOOK-URL'\n\nconst body = {\n\t\"text\": $text\n};\n\nconst options = {\n\tmethod: 'POST',\n\theaders: {\n\t\t'Content-Type': 'application/json'\n\t},\n\tbody: JSON.stringify(body)\n};\n\nconst url = `${webhookUrl}`\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst text = await response.text();\n\treturn text;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/marketplaces/tools/Send Teams Message.json b/packages/server/marketplaces/tools/Send Teams Message.json
new file mode 100644
index 00000000..1af8111b
--- /dev/null
+++ b/packages/server/marketplaces/tools/Send Teams Message.json
@@ -0,0 +1,8 @@
+{
+ "name": "send_message_to_teams_channel",
+ "description": "Send message to Teams channel",
+ "color": "linear-gradient(rgb(155,190,84), rgb(176,69,245))",
+ "iconSrc": "https://raw.githubusercontent.com/gilbarbara/logos/main/logos/microsoft-teams.svg",
+ "schema": "[{\"id\":1,\"property\":\"content\",\"description\":\"message to send\",\"type\":\"string\",\"required\":true}]",
+ "func": "const fetch = require('node-fetch');\nconst webhookUrl = 'YOUR-WEBHOOK-URL'\n\nconst body = {\n\t\"content\": $content\n};\n\nconst options = {\n\tmethod: 'POST',\n\theaders: {\n\t\t'Content-Type': 'application/json'\n\t},\n\tbody: JSON.stringify(body)\n};\n\nconst url = `${webhookUrl}?wait=true`\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst text = await response.text();\n\treturn text;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/marketplaces/tools/SendGrid Email.json b/packages/server/marketplaces/tools/SendGrid Email.json
new file mode 100644
index 00000000..18f6dad8
--- /dev/null
+++ b/packages/server/marketplaces/tools/SendGrid Email.json
@@ -0,0 +1,8 @@
+{
+ "name": "sendgrid_email",
+ "description": "Send email using SendGrid",
+ "color": "linear-gradient(rgb(230,108,70), rgb(222,4,98))",
+ "iconSrc": "https://raw.githubusercontent.com/gilbarbara/logos/main/logos/sendgrid-icon.svg",
+ "schema": "[{\"id\":0,\"property\":\"fromEmail\",\"description\":\"Email address used to send the message\",\"type\":\"string\",\"required\":true},{\"id\":1,\"property\":\"toEmail \",\"description\":\"The intended recipient's email address\",\"type\":\"string\",\"required\":true},{\"id\":2,\"property\":\"subject\",\"description\":\"The subject of email\",\"type\":\"string\",\"required\":true},{\"id\":3,\"property\":\"content\",\"description\":\"Content of email\",\"type\":\"string\",\"required\":true}]",
+ "func": "const fetch = require('node-fetch');\nconst url = 'https://api.sendgrid.com/v3/mail/send';\nconst api_key = 'YOUR-API-KEY';\n\nconst body = {\n \"personalizations\": [\n {\n \"to\": [{ \"email\": $toEmail }]\n }\n ],\n\t\"from\": {\n\t \"email\": $fromEmail\n\t},\n\t\"subject\": $subject,\n\t\"content\": [\n\t {\n\t \"type\": 'text/plain',\n\t \"value\": $content\n\t }\n\t]\n};\n\nconst options = {\n\tmethod: 'POST',\n\theaders: {\n\t 'Authorization': `Bearer ${api_key}`,\n\t\t'Content-Type': 'application/json'\n\t},\n\tbody: JSON.stringify(body)\n};\n\ntry {\n\tconst response = await fetch(url, options);\n\tconst text = await response.text();\n\treturn text;\n} catch (error) {\n\tconsole.error(error);\n\treturn '';\n}"
+}
diff --git a/packages/server/nodemon.json b/packages/server/nodemon.json
index d896b48b..bf25eb00 100644
--- a/packages/server/nodemon.json
+++ b/packages/server/nodemon.json
@@ -1,6 +1,6 @@
{
"ignore": ["**/*.spec.ts", ".git", "node_modules"],
- "watch": ["commands", "index.ts", "src"],
+ "watch": ["commands", "index.ts", "src", "../components/nodes", "../components/src"],
"exec": "yarn oclif-dev",
"ext": "ts"
}
diff --git a/packages/server/package.json b/packages/server/package.json
index eda69322..0aac4ac5 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise",
- "version": "1.2.13",
+ "version": "1.3.2",
"description": "Flowiseai Server",
"main": "dist/index",
"types": "dist/index.d.ts",
@@ -48,6 +48,7 @@
"@oclif/core": "^1.13.10",
"axios": "^0.27.2",
"cors": "^2.8.5",
+ "crypto-js": "^4.1.1",
"dotenv": "^16.0.0",
"express": "^4.17.3",
"express-basic-auth": "^1.2.1",
@@ -55,13 +56,17 @@
"flowise-ui": "*",
"moment-timezone": "^0.5.34",
"multer": "^1.4.5-lts.1",
+ "mysql": "^2.18.1",
+ "pg": "^8.11.1",
"reflect-metadata": "^0.1.13",
"socket.io": "^4.6.1",
"sqlite3": "^5.1.6",
- "typeorm": "^0.3.6"
+ "typeorm": "^0.3.6",
+ "winston": "^3.9.0"
},
"devDependencies": {
"@types/cors": "^2.8.12",
+ "@types/crypto-js": "^4.1.1",
"@types/multer": "^1.4.7",
"concurrently": "^7.1.0",
"nodemon": "^2.0.15",
diff --git a/packages/server/src/ChatflowPool.ts b/packages/server/src/ChatflowPool.ts
index 35b0d947..d296dcfe 100644
--- a/packages/server/src/ChatflowPool.ts
+++ b/packages/server/src/ChatflowPool.ts
@@ -1,5 +1,6 @@
import { ICommonObject } from 'flowise-components'
import { IActiveChatflows, INodeData, IReactFlowNode } from './Interface'
+import logger from './utils/logger'
/**
* This pool is to keep track of active chatflow pools
@@ -22,6 +23,7 @@ export class ChatflowPool {
inSync: true
}
if (overrideConfig) this.activeChatflows[chatflowid].overrideConfig = overrideConfig
+ logger.info(`[server]: Chatflow ${chatflowid} added into ChatflowPool`)
}
/**
@@ -32,6 +34,7 @@ export class ChatflowPool {
updateInSync(chatflowid: string, inSync: boolean) {
if (Object.prototype.hasOwnProperty.call(this.activeChatflows, chatflowid)) {
this.activeChatflows[chatflowid].inSync = inSync
+ logger.info(`[server]: Chatflow ${chatflowid} updated inSync=${inSync} in ChatflowPool`)
}
}
@@ -42,6 +45,7 @@ export class ChatflowPool {
async remove(chatflowid: string) {
if (Object.prototype.hasOwnProperty.call(this.activeChatflows, chatflowid)) {
delete this.activeChatflows[chatflowid]
+ logger.info(`[server]: Chatflow ${chatflowid} removed from ChatflowPool`)
}
}
}
diff --git a/packages/server/src/ChildProcess.ts b/packages/server/src/ChildProcess.ts
index e8aeaff2..2eae90f8 100644
--- a/packages/server/src/ChildProcess.ts
+++ b/packages/server/src/ChildProcess.ts
@@ -1,10 +1,20 @@
import path from 'path'
import { IChildProcessMessage, IReactFlowNode, IReactFlowObject, IRunChatflowMessageValue, INodeData } from './Interface'
-import { buildLangchain, constructGraphs, getEndingNode, getStartingNodes, getUserHome, resolveVariables } from './utils'
+import {
+ buildLangchain,
+ constructGraphs,
+ getEndingNode,
+ getStartingNodes,
+ getUserHome,
+ replaceInputsWithConfig,
+ resolveVariables
+} from './utils'
import { DataSource } from 'typeorm'
import { ChatFlow } from './entity/ChatFlow'
import { ChatMessage } from './entity/ChatMessage'
import { Tool } from './entity/Tool'
+import { Credential } from './entity/Credential'
+import logger from './utils/logger'
export class ChildProcess {
/**
@@ -27,115 +37,175 @@ export class ChildProcess {
await sendToParentProcess('start', '_')
- const childAppDataSource = await initDB()
+ try {
+ const childAppDataSource = await initDB()
- // Create a Queue and add our initial node in it
- const { endingNodeData, chatflow, chatId, incomingInput, componentNodes } = messageValue
+ // Create a Queue and add our initial node in it
+ const { endingNodeData, chatflow, chatId, incomingInput, componentNodes } = messageValue
- let nodeToExecuteData: INodeData
- let addToChatFlowPool: any = {}
+ let nodeToExecuteData: INodeData
+ let addToChatFlowPool: any = {}
- /* Don't rebuild the flow (to avoid duplicated upsert, recomputation) when all these conditions met:
- * - Node Data already exists in pool
- * - Still in sync (i.e the flow has not been modified since)
- * - Existing overrideConfig and new overrideConfig are the same
- * - Flow doesn't start with nodes that depend on incomingInput.question
- ***/
- if (endingNodeData) {
- nodeToExecuteData = endingNodeData
- } else {
- /*** Get chatflows and prepare data ***/
- const flowData = chatflow.flowData
- const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
- const nodes = parsedFlowData.nodes
- const edges = parsedFlowData.edges
+ /* Don't rebuild the flow (to avoid duplicated upsert, recomputation) when all these conditions met:
+ * - Node Data already exists in pool
+ * - Still in sync (i.e the flow has not been modified since)
+ * - Existing overrideConfig and new overrideConfig are the same
+ * - Flow doesn't start with nodes that depend on incomingInput.question
+ ***/
+ if (endingNodeData) {
+ nodeToExecuteData = endingNodeData
+ } else {
+ /*** Get chatflows and prepare data ***/
+ const flowData = chatflow.flowData
+ const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
+ const nodes = parsedFlowData.nodes
+ const edges = parsedFlowData.edges
- /*** Get Ending Node with Directed Graph ***/
- const { graph, nodeDependencies } = constructGraphs(nodes, edges)
- const directedGraph = graph
- const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
- if (!endingNodeId) {
- await sendToParentProcess('error', `Ending node must be either a Chain or Agent`)
- return
- }
+ /*** Get Ending Node with Directed Graph ***/
+ const { graph, nodeDependencies } = constructGraphs(nodes, edges)
+ const directedGraph = graph
+ const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
+ if (!endingNodeId) {
+ await sendToParentProcess('error', `Ending node ${endingNodeId} not found`)
+ return
+ }
- const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
- if (!endingNodeData) {
- await sendToParentProcess('error', `Ending node must be either a Chain or Agent`)
- return
- }
+ const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
+ if (!endingNodeData) {
+ await sendToParentProcess('error', `Ending node ${endingNodeId} data not found`)
+ return
+ }
- if (
- endingNodeData.outputs &&
- Object.keys(endingNodeData.outputs).length &&
- !Object.values(endingNodeData.outputs).includes(endingNodeData.name)
- ) {
- await sendToParentProcess(
- 'error',
- `Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
+ if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
+ await sendToParentProcess('error', `Ending node must be either a Chain or Agent`)
+ return
+ }
+
+ if (
+ endingNodeData.outputs &&
+ Object.keys(endingNodeData.outputs).length &&
+ !Object.values(endingNodeData.outputs).includes(endingNodeData.name)
+ ) {
+ await sendToParentProcess(
+ 'error',
+ `Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
+ )
+ return
+ }
+
+ /*** Get Starting Nodes with Non-Directed Graph ***/
+ const constructedObj = constructGraphs(nodes, edges, true)
+ const nonDirectedGraph = constructedObj.graph
+ const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
+
+ logger.debug(`[server] [mode:child]: Start building chatflow ${chatflow.id}`)
+ /*** BFS to traverse from Starting Nodes to Ending Node ***/
+ const reactFlowNodes = await buildLangchain(
+ startingNodeIds,
+ nodes,
+ graph,
+ depthQueue,
+ componentNodes,
+ incomingInput.question,
+ chatId,
+ childAppDataSource,
+ incomingInput?.overrideConfig
)
- return
+
+ const nodeToExecute = reactFlowNodes.find((node: IReactFlowNode) => node.id === endingNodeId)
+ if (!nodeToExecute) {
+ await sendToParentProcess('error', `Node ${endingNodeId} not found`)
+ return
+ }
+
+ if (incomingInput.overrideConfig)
+ nodeToExecute.data = replaceInputsWithConfig(nodeToExecute.data, incomingInput.overrideConfig)
+ const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
+ nodeToExecuteData = reactFlowNodeData
+
+ const startingNodes = nodes.filter((nd) => startingNodeIds.includes(nd.id))
+ addToChatFlowPool = {
+ chatflowid: chatflow.id,
+ nodeToExecuteData,
+ startingNodes,
+ overrideConfig: incomingInput?.overrideConfig
+ }
}
- /*** Get Starting Nodes with Non-Directed Graph ***/
- const constructedObj = constructGraphs(nodes, edges, true)
- const nonDirectedGraph = constructedObj.graph
- const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
+ const nodeInstanceFilePath = componentNodes[nodeToExecuteData.name].filePath as string
+ const nodeModule = await import(nodeInstanceFilePath)
+ const nodeInstance = new nodeModule.nodeClass()
- /*** BFS to traverse from Starting Nodes to Ending Node ***/
- const reactFlowNodes = await buildLangchain(
- startingNodeIds,
- nodes,
- graph,
- depthQueue,
- componentNodes,
- incomingInput.question,
- chatId,
- childAppDataSource,
- incomingInput?.overrideConfig
- )
+ logger.debug(`[server] [mode:child]: Running ${nodeToExecuteData.label} (${nodeToExecuteData.id})`)
+ const result = await nodeInstance.run(nodeToExecuteData, incomingInput.question, { chatHistory: incomingInput.history })
+ logger.debug(`[server] [mode:child]: Finished running ${nodeToExecuteData.label} (${nodeToExecuteData.id})`)
- const nodeToExecute = reactFlowNodes.find((node: IReactFlowNode) => node.id === endingNodeId)
- if (!nodeToExecute) {
- await sendToParentProcess('error', `Node ${endingNodeId} not found`)
- return
- }
-
- const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
- nodeToExecuteData = reactFlowNodeData
-
- const startingNodes = nodes.filter((nd) => startingNodeIds.includes(nd.id))
- addToChatFlowPool = {
- chatflowid: chatflow.id,
- nodeToExecuteData,
- startingNodes,
- overrideConfig: incomingInput?.overrideConfig
- }
+ await sendToParentProcess('finish', { result, addToChatFlowPool })
+ } catch (e: any) {
+ await sendToParentProcess('error', e.message)
+ logger.error('[server] [mode:child]: Error:', e)
}
-
- const nodeInstanceFilePath = componentNodes[nodeToExecuteData.name].filePath as string
- const nodeModule = await import(nodeInstanceFilePath)
- const nodeInstance = new nodeModule.nodeClass()
-
- const result = await nodeInstance.run(nodeToExecuteData, incomingInput.question, { chatHistory: incomingInput.history })
-
- await sendToParentProcess('finish', { result, addToChatFlowPool })
}
}
/**
- * Initalize DB in child process
+ * Initialize DB in child process
* @returns {DataSource}
*/
async function initDB() {
- const homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise')
- const childAppDataSource = new DataSource({
- type: 'sqlite',
- database: path.resolve(homePath, 'database.sqlite'),
- synchronize: true,
- entities: [ChatFlow, ChatMessage, Tool],
- migrations: []
- })
+ let childAppDataSource
+ let homePath
+ const synchronize = process.env.OVERRIDE_DATABASE === 'false' ? false : true
+ switch (process.env.DATABASE_TYPE) {
+ case 'sqlite':
+ homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise')
+ childAppDataSource = new DataSource({
+ type: 'sqlite',
+ database: path.resolve(homePath, 'database.sqlite'),
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ case 'mysql':
+ childAppDataSource = new DataSource({
+ type: 'mysql',
+ host: process.env.DATABASE_HOST,
+ port: parseInt(process.env.DATABASE_PORT || '3306'),
+ username: process.env.DATABASE_USER,
+ password: process.env.DATABASE_PASSWORD,
+ database: process.env.DATABASE_NAME,
+ charset: 'utf8mb4',
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ case 'postgres':
+ childAppDataSource = new DataSource({
+ type: 'postgres',
+ host: process.env.DATABASE_HOST,
+ port: parseInt(process.env.DATABASE_PORT || '5432'),
+ username: process.env.DATABASE_USER,
+ password: process.env.DATABASE_PASSWORD,
+ database: process.env.DATABASE_NAME,
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ default:
+ homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise')
+ childAppDataSource = new DataSource({
+ type: 'sqlite',
+ database: path.resolve(homePath, 'database.sqlite'),
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ }
+
return await childAppDataSource.initialize()
}
diff --git a/packages/server/src/DataSource.ts b/packages/server/src/DataSource.ts
index 03b9d5ce..b0d56477 100644
--- a/packages/server/src/DataSource.ts
+++ b/packages/server/src/DataSource.ts
@@ -3,21 +3,64 @@ import path from 'path'
import { DataSource } from 'typeorm'
import { ChatFlow } from './entity/ChatFlow'
import { ChatMessage } from './entity/ChatMessage'
+import { Credential } from './entity/Credential'
import { Tool } from './entity/Tool'
import { getUserHome } from './utils'
let appDataSource: DataSource
export const init = async (): Promise => {
- const homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise')
-
- appDataSource = new DataSource({
- type: 'sqlite',
- database: path.resolve(homePath, 'database.sqlite'),
- synchronize: true,
- entities: [ChatFlow, ChatMessage, Tool],
- migrations: []
- })
+ let homePath
+ const synchronize = process.env.OVERRIDE_DATABASE === 'false' ? false : true
+ switch (process.env.DATABASE_TYPE) {
+ case 'sqlite':
+ homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise')
+ appDataSource = new DataSource({
+ type: 'sqlite',
+ database: path.resolve(homePath, 'database.sqlite'),
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ case 'mysql':
+ appDataSource = new DataSource({
+ type: 'mysql',
+ host: process.env.DATABASE_HOST,
+ port: parseInt(process.env.DATABASE_PORT || '3306'),
+ username: process.env.DATABASE_USER,
+ password: process.env.DATABASE_PASSWORD,
+ database: process.env.DATABASE_NAME,
+ charset: 'utf8mb4',
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ case 'postgres':
+ appDataSource = new DataSource({
+ type: 'postgres',
+ host: process.env.DATABASE_HOST,
+ port: parseInt(process.env.DATABASE_PORT || '5432'),
+ username: process.env.DATABASE_USER,
+ password: process.env.DATABASE_PASSWORD,
+ database: process.env.DATABASE_NAME,
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ default:
+ homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise')
+ appDataSource = new DataSource({
+ type: 'sqlite',
+ database: path.resolve(homePath, 'database.sqlite'),
+ synchronize,
+ entities: [ChatFlow, ChatMessage, Tool, Credential],
+ migrations: []
+ })
+ break
+ }
}
export function getDataSource(): DataSource {
diff --git a/packages/server/src/Interface.ts b/packages/server/src/Interface.ts
index 1eafcae6..49d61036 100644
--- a/packages/server/src/Interface.ts
+++ b/packages/server/src/Interface.ts
@@ -9,10 +9,12 @@ export interface IChatFlow {
id: string
name: string
flowData: string
- apikeyid: string
- deployed: boolean
updatedDate: Date
createdDate: Date
+ deployed?: boolean
+ isPublic?: boolean
+ apikeyid?: string
+ chatbotConfig?: string
}
export interface IChatMessage {
@@ -21,7 +23,7 @@ export interface IChatMessage {
content: string
chatflowid: string
createdDate: Date
- sourceDocuments: string
+ sourceDocuments?: string
}
export interface ITool {
@@ -29,8 +31,18 @@ export interface ITool {
name: string
description: string
color: string
- schema: string
- func: string
+ iconSrc?: string
+ schema?: string
+ func?: string
+ updatedDate: Date
+ createdDate: Date
+}
+
+export interface ICredential {
+ id: string
+ name: string
+ credentialName: string
+ encryptedData: string
updatedDate: Date
createdDate: Date
}
@@ -39,6 +51,10 @@ export interface IComponentNodes {
[key: string]: INode
}
+export interface IComponentCredentials {
+ [key: string]: INode
+}
+
export interface IVariableDict {
[key: string]: string
}
@@ -164,3 +180,17 @@ export interface IChildProcessMessage {
key: string
value?: any
}
+
+export type ICredentialDataDecrypted = ICommonObject
+
+// Plain credential object sent to server
+export interface ICredentialReqBody {
+ name: string
+ credentialName: string
+ plainDataObj: ICredentialDataDecrypted
+}
+
+// Decrypted credential object sent back to client
+export interface ICredentialReturnResponse extends ICredential {
+ plainDataObj: ICredentialDataDecrypted
+}
diff --git a/packages/server/src/NodesPool.ts b/packages/server/src/NodesPool.ts
index 1ee506ea..62db41ba 100644
--- a/packages/server/src/NodesPool.ts
+++ b/packages/server/src/NodesPool.ts
@@ -1,17 +1,27 @@
-import { IComponentNodes } from './Interface'
-
+import { IComponentNodes, IComponentCredentials } from './Interface'
import path from 'path'
import { Dirent } from 'fs'
import { getNodeModulesPackagePath } from './utils'
import { promises } from 'fs'
+import { ICommonObject } from 'flowise-components'
export class NodesPool {
componentNodes: IComponentNodes = {}
+ componentCredentials: IComponentCredentials = {}
+ private credentialIconPath: ICommonObject = {}
/**
- * Initialize to get all nodes
+ * Initialize to get all nodes & credentials
*/
async initialize() {
+ await this.initializeNodes()
+ await this.initializeCrdentials()
+ }
+
+ /**
+ * Initialize nodes
+ */
+ private async initializeNodes() {
const packagePath = getNodeModulesPackagePath('flowise-components')
const nodesPath = path.join(packagePath, 'dist', 'nodes')
const nodeFiles = await this.getFiles(nodesPath)
@@ -37,6 +47,13 @@ export class NodesPool {
filePath.pop()
const nodeIconAbsolutePath = `${filePath.join('/')}/${newNodeInstance.icon}`
this.componentNodes[newNodeInstance.name].icon = nodeIconAbsolutePath
+
+ // Store icon path for componentCredentials
+ if (newNodeInstance.credential) {
+ for (const credName of newNodeInstance.credential.credentialNames) {
+ this.credentialIconPath[credName] = nodeIconAbsolutePath
+ }
+ }
}
}
}
@@ -44,12 +61,33 @@ export class NodesPool {
)
}
+ /**
+ * Initialize credentials
+ */
+ private async initializeCrdentials() {
+ const packagePath = getNodeModulesPackagePath('flowise-components')
+ const nodesPath = path.join(packagePath, 'dist', 'credentials')
+ const nodeFiles = await this.getFiles(nodesPath)
+ return Promise.all(
+ nodeFiles.map(async (file) => {
+ if (file.endsWith('.credential.js')) {
+ const credentialModule = await require(file)
+ if (credentialModule.credClass) {
+ const newCredInstance = new credentialModule.credClass()
+ newCredInstance.icon = this.credentialIconPath[newCredInstance.name] ?? ''
+ this.componentCredentials[newCredInstance.name] = newCredInstance
+ }
+ }
+ })
+ )
+ }
+
/**
* Recursive function to get node files
* @param {string} dir
* @returns {string[]}
*/
- async getFiles(dir: string): Promise {
+ private async getFiles(dir: string): Promise {
const dirents = await promises.readdir(dir, { withFileTypes: true })
const files = await Promise.all(
dirents.map((dirent: Dirent) => {
diff --git a/packages/server/src/commands/start.ts b/packages/server/src/commands/start.ts
index 9066f1cf..6c6260b6 100644
--- a/packages/server/src/commands/start.ts
+++ b/packages/server/src/commands/start.ts
@@ -3,6 +3,7 @@ import path from 'path'
import * as Server from '../index'
import * as DataSource from '../DataSource'
import dotenv from 'dotenv'
+import logger from '../utils/logger'
dotenv.config({ path: path.join(__dirname, '..', '..', '.env'), override: true })
@@ -18,16 +19,31 @@ export default class Start extends Command {
FLOWISE_USERNAME: Flags.string(),
FLOWISE_PASSWORD: Flags.string(),
PORT: Flags.string(),
+ PASSPHRASE: Flags.string(),
+ DEBUG: Flags.string(),
+ APIKEY_PATH: Flags.string(),
+ SECRETKEY_PATH: Flags.string(),
+ LOG_PATH: Flags.string(),
+ LOG_LEVEL: Flags.string(),
+ EXECUTION_MODE: Flags.string(),
+ TOOL_FUNCTION_BUILTIN_DEP: Flags.string(),
+ TOOL_FUNCTION_EXTERNAL_DEP: Flags.string(),
+ OVERRIDE_DATABASE: Flags.string(),
+ DATABASE_TYPE: Flags.string(),
DATABASE_PATH: Flags.string(),
- EXECUTION_MODE: Flags.string()
+ DATABASE_PORT: Flags.string(),
+ DATABASE_HOST: Flags.string(),
+ DATABASE_NAME: Flags.string(),
+ DATABASE_USER: Flags.string(),
+ DATABASE_PASSWORD: Flags.string()
}
async stopProcess() {
- console.info('Shutting down Flowise...')
+ logger.info('Shutting down Flowise...')
try {
// Shut down the app after timeout if it ever stuck removing pools
setTimeout(() => {
- console.info('Flowise was forced to shut down after 30 secs')
+ logger.info('Flowise was forced to shut down after 30 secs')
process.exit(processExitCode)
}, 30000)
@@ -35,7 +51,7 @@ export default class Start extends Command {
const serverApp = Server.getInstance()
if (serverApp) await serverApp.stopApp()
} catch (error) {
- console.error('There was an error shutting down Flowise...', error)
+ logger.error('There was an error shutting down Flowise...', error)
}
process.exit(processExitCode)
}
@@ -47,23 +63,49 @@ export default class Start extends Command {
// Prevent throw new Error from crashing the app
// TODO: Get rid of this and send proper error message to ui
process.on('uncaughtException', (err) => {
- console.error('uncaughtException: ', err)
+ logger.error('uncaughtException: ', err)
})
const { flags } = await this.parse(Start)
+
+ if (flags.PORT) process.env.PORT = flags.PORT
+ if (flags.EXECUTION_MODE) process.env.EXECUTION_MODE = flags.EXECUTION_MODE
+ if (flags.DEBUG) process.env.DEBUG = flags.DEBUG
+
+ // Authorization
if (flags.FLOWISE_USERNAME) process.env.FLOWISE_USERNAME = flags.FLOWISE_USERNAME
if (flags.FLOWISE_PASSWORD) process.env.FLOWISE_PASSWORD = flags.FLOWISE_PASSWORD
- if (flags.PORT) process.env.PORT = flags.PORT
+ if (flags.APIKEY_PATH) process.env.APIKEY_PATH = flags.APIKEY_PATH
+
+ // Credentials
+ if (flags.PASSPHRASE) process.env.PASSPHRASE = flags.PASSPHRASE
+ if (flags.SECRETKEY_PATH) process.env.SECRETKEY_PATH = flags.SECRETKEY_PATH
+
+ // Logs
+ if (flags.LOG_PATH) process.env.LOG_PATH = flags.LOG_PATH
+ if (flags.LOG_LEVEL) process.env.LOG_LEVEL = flags.LOG_LEVEL
+
+ // Tool functions
+ 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
+
+ // Database config
+ if (flags.OVERRIDE_DATABASE) process.env.OVERRIDE_DATABASE = flags.OVERRIDE_DATABASE
+ if (flags.DATABASE_TYPE) process.env.DATABASE_TYPE = flags.DATABASE_TYPE
if (flags.DATABASE_PATH) process.env.DATABASE_PATH = flags.DATABASE_PATH
- if (flags.EXECUTION_MODE) process.env.EXECUTION_MODE = flags.EXECUTION_MODE
+ if (flags.DATABASE_PORT) process.env.DATABASE_PORT = flags.DATABASE_PORT
+ if (flags.DATABASE_HOST) process.env.DATABASE_HOST = flags.DATABASE_HOST
+ if (flags.DATABASE_NAME) process.env.DATABASE_NAME = flags.DATABASE_NAME
+ if (flags.DATABASE_USER) process.env.DATABASE_USER = flags.DATABASE_USER
+ if (flags.DATABASE_PASSWORD) process.env.DATABASE_PASSWORD = flags.DATABASE_PASSWORD
await (async () => {
try {
- this.log('Starting Flowise...')
+ logger.info('Starting Flowise...')
await DataSource.init()
await Server.start()
} catch (error) {
- console.error('There was an error starting Flowise...', error)
+ logger.error('There was an error starting Flowise...', error)
processExitCode = EXIT_CODE.FAILED
// @ts-ignore
process.emit('SIGINT')
diff --git a/packages/server/src/entity/ChatFlow.ts b/packages/server/src/entity/ChatFlow.ts
index d9b12929..4c37e083 100644
--- a/packages/server/src/entity/ChatFlow.ts
+++ b/packages/server/src/entity/ChatFlow.ts
@@ -10,14 +10,20 @@ export class ChatFlow implements IChatFlow {
@Column()
name: string
- @Column()
+ @Column({ type: 'text' })
flowData: string
@Column({ nullable: true })
- apikeyid: string
+ deployed?: boolean
- @Column()
- deployed: boolean
+ @Column({ nullable: true })
+ isPublic?: boolean
+
+ @Column({ nullable: true })
+ apikeyid?: string
+
+ @Column({ nullable: true })
+ chatbotConfig?: string
@CreateDateColumn()
createdDate: Date
diff --git a/packages/server/src/entity/ChatMessage.ts b/packages/server/src/entity/ChatMessage.ts
index 236dc5f9..8123020c 100644
--- a/packages/server/src/entity/ChatMessage.ts
+++ b/packages/server/src/entity/ChatMessage.ts
@@ -14,11 +14,11 @@ export class ChatMessage implements IChatMessage {
@Column()
chatflowid: string
- @Column()
+ @Column({ type: 'text' })
content: string
@Column({ nullable: true })
- sourceDocuments: string
+ sourceDocuments?: string
@CreateDateColumn()
createdDate: Date
diff --git a/packages/server/src/entity/Credential.ts b/packages/server/src/entity/Credential.ts
new file mode 100644
index 00000000..b724eed6
--- /dev/null
+++ b/packages/server/src/entity/Credential.ts
@@ -0,0 +1,24 @@
+/* eslint-disable */
+import { Entity, Column, PrimaryGeneratedColumn, Index, CreateDateColumn, UpdateDateColumn } from 'typeorm'
+import { ICredential } from '../Interface'
+
+@Entity()
+export class Credential implements ICredential {
+ @PrimaryGeneratedColumn('uuid')
+ id: string
+
+ @Column()
+ name: string
+
+ @Column()
+ credentialName: string
+
+ @Column()
+ encryptedData: string
+
+ @CreateDateColumn()
+ createdDate: Date
+
+ @UpdateDateColumn()
+ updatedDate: Date
+}
diff --git a/packages/server/src/entity/Tool.ts b/packages/server/src/entity/Tool.ts
index d547374c..011bf957 100644
--- a/packages/server/src/entity/Tool.ts
+++ b/packages/server/src/entity/Tool.ts
@@ -10,17 +10,20 @@ export class Tool implements ITool {
@Column()
name: string
- @Column()
+ @Column({ type: 'text' })
description: string
@Column()
color: string
@Column({ nullable: true })
- schema: string
+ iconSrc?: string
@Column({ nullable: true })
- func: string
+ schema?: string
+
+ @Column({ nullable: true })
+ func?: string
@CreateDateColumn()
createdDate: Date
diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts
index 65bfef23..545c75a7 100644
--- a/packages/server/src/index.ts
+++ b/packages/server/src/index.ts
@@ -6,6 +6,8 @@ import http from 'http'
import * as fs from 'fs'
import basicAuth from 'express-basic-auth'
import { Server } from 'socket.io'
+import logger from './utils/logger'
+import { expressRequestLogger } from './utils/logger'
import {
IChatFlow,
@@ -15,7 +17,8 @@ import {
INodeData,
IDatabaseExport,
IRunChatflowMessageValue,
- IChildProcessMessage
+ IChildProcessMessage,
+ ICredentialReturnResponse
} from './Interface'
import {
getNodeModulesPackagePath,
@@ -36,17 +39,24 @@ import {
replaceAllAPIKeys,
isFlowValidForStream,
isVectorStoreFaiss,
- databaseEntities
+ databaseEntities,
+ getApiKey,
+ transformToCredentialEntity,
+ decryptCredentialData,
+ clearSessionMemory,
+ replaceInputsWithConfig,
+ getEncryptionKey
} from './utils'
-import { cloneDeep } from 'lodash'
+import { cloneDeep, omit } from 'lodash'
import { getDataSource } from './DataSource'
import { NodesPool } from './NodesPool'
import { ChatFlow } from './entity/ChatFlow'
import { ChatMessage } from './entity/ChatMessage'
+import { Credential } from './entity/Credential'
+import { Tool } from './entity/Tool'
import { ChatflowPool } from './ChatflowPool'
import { ICommonObject, INodeOptionsValue } from 'flowise-components'
import { fork } from 'child_process'
-import { Tool } from './entity/Tool'
export class App {
app: express.Application
@@ -62,19 +72,23 @@ export class App {
// Initialize database
this.AppDataSource.initialize()
.then(async () => {
- console.info('π¦[server]: Data Source has been initialized!')
+ logger.info('π¦ [server]: Data Source has been initialized!')
- // Initialize pools
+ // Initialize nodes pool
this.nodesPool = new NodesPool()
await this.nodesPool.initialize()
+ // Initialize chatflow pool
this.chatflowPool = new ChatflowPool()
// Initialize API keys
await getAPIKeys()
+
+ // Initialize encryption key
+ await getEncryptionKey()
})
.catch((err) => {
- console.error('β[server]: Error during Data Source initialization:', err)
+ logger.error('β [server]: Error during Data Source initialization:', err)
})
}
@@ -86,13 +100,24 @@ export class App {
// Allow access from *
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) {
const username = process.env.FLOWISE_USERNAME
const password = process.env.FLOWISE_PASSWORD
const basicAuthMiddleware = basicAuth({
users: { [username]: password }
})
- const whitelistURLs = ['/api/v1/prediction/', '/api/v1/node-icon/', '/api/v1/chatflows-streaming']
+ const whitelistURLs = [
+ '/api/v1/verify/apikey/',
+ '/api/v1/chatflows/apikey/',
+ '/api/v1/public-chatflows',
+ '/api/v1/prediction/',
+ '/api/v1/node-icon/',
+ '/api/v1/components-credentials-icon/',
+ '/api/v1/chatflows-streaming'
+ ]
this.app.use((req, res, next) => {
if (req.url.includes('/api/v1/')) {
whitelistURLs.some((url) => req.url.includes(url)) ? next() : basicAuthMiddleware(req, res, next)
@@ -103,7 +128,7 @@ export class App {
const upload = multer({ dest: `${path.join(__dirname, '..', 'uploads')}/` })
// ----------------------------------------
- // Nodes
+ // Components
// ----------------------------------------
// Get all component nodes
@@ -116,6 +141,16 @@ export class App {
return res.json(returnData)
})
+ // Get all component credentials
+ this.app.get('/api/v1/components-credentials', async (req: Request, res: Response) => {
+ const returnData = []
+ for (const credName in this.nodesPool.componentCredentials) {
+ const clonedCred = cloneDeep(this.nodesPool.componentCredentials[credName])
+ returnData.push(clonedCred)
+ }
+ return res.json(returnData)
+ })
+
// Get specific component node via name
this.app.get('/api/v1/nodes/:name', (req: Request, res: Response) => {
if (Object.prototype.hasOwnProperty.call(this.nodesPool.componentNodes, req.params.name)) {
@@ -125,6 +160,27 @@ export class App {
}
})
+ // Get component credential via name
+ this.app.get('/api/v1/components-credentials/:name', (req: Request, res: Response) => {
+ if (!req.params.name.includes('&')) {
+ if (Object.prototype.hasOwnProperty.call(this.nodesPool.componentCredentials, req.params.name)) {
+ return res.json(this.nodesPool.componentCredentials[req.params.name])
+ } else {
+ throw new Error(`Credential ${req.params.name} not found`)
+ }
+ } else {
+ const returnResponse = []
+ for (const name of req.params.name.split('&')) {
+ if (Object.prototype.hasOwnProperty.call(this.nodesPool.componentCredentials, name)) {
+ returnResponse.push(this.nodesPool.componentCredentials[name])
+ } else {
+ throw new Error(`Credential ${name} not found`)
+ }
+ }
+ return res.json(returnResponse)
+ }
+ })
+
// Returns specific component node icon via name
this.app.get('/api/v1/node-icon/:name', (req: Request, res: Response) => {
if (Object.prototype.hasOwnProperty.call(this.nodesPool.componentNodes, req.params.name)) {
@@ -144,6 +200,25 @@ export class App {
}
})
+ // Returns specific component credential icon via name
+ this.app.get('/api/v1/components-credentials-icon/:name', (req: Request, res: Response) => {
+ if (Object.prototype.hasOwnProperty.call(this.nodesPool.componentCredentials, req.params.name)) {
+ const credInstance = this.nodesPool.componentCredentials[req.params.name]
+ if (credInstance.icon === undefined) {
+ throw new Error(`Credential ${req.params.name} icon not found`)
+ }
+
+ if (credInstance.icon.endsWith('.svg') || credInstance.icon.endsWith('.png') || credInstance.icon.endsWith('.jpg')) {
+ const filepath = credInstance.icon
+ res.sendFile(filepath)
+ } else {
+ throw new Error(`Credential ${req.params.name} icon is missing icon`)
+ }
+ } else {
+ throw new Error(`Credential ${req.params.name} not found`)
+ }
+ })
+
// load async options
this.app.post('/api/v1/node-load-method/:name', async (req: Request, res: Response) => {
const nodeData: INodeData = req.body
@@ -177,6 +252,25 @@ export class App {
return res.json(chatflows)
})
+ // Get specific chatflow via api key
+ this.app.get('/api/v1/chatflows/apikey/:apiKey', async (req: Request, res: Response) => {
+ try {
+ const apiKey = await getApiKey(req.params.apiKey)
+ if (!apiKey) return res.status(401).send('Unauthorized')
+ const chatflows = await this.AppDataSource.getRepository(ChatFlow)
+ .createQueryBuilder('cf')
+ .where('cf.apikeyid = :apikeyid', { apikeyid: apiKey.id })
+ .orWhere('cf.apikeyid IS NULL')
+ .orWhere('cf.apikeyid = ""')
+ .orderBy('cf.name', 'ASC')
+ .getMany()
+ if (chatflows.length >= 1) return res.status(200).send(chatflows)
+ return res.status(404).send('Chatflow not found')
+ } catch (err: any) {
+ return res.status(500).send(err?.message)
+ }
+ })
+
// Get specific chatflow via id
this.app.get('/api/v1/chatflows/:id', async (req: Request, res: Response) => {
const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({
@@ -186,6 +280,16 @@ export class App {
return res.status(404).send(`Chatflow ${req.params.id} not found`)
})
+ // Get specific chatflow via id (PUBLIC endpoint, used when sharing chatbot link)
+ this.app.get('/api/v1/public-chatflows/:id', async (req: Request, res: Response) => {
+ const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({
+ id: req.params.id
+ })
+ if (chatflow && chatflow.isPublic) return res.json(chatflow)
+ else if (chatflow && !chatflow.isPublic) return res.status(401).send(`Unauthorized`)
+ return res.status(404).send(`Chatflow ${req.params.id} not found`)
+ })
+
// Save chatflow
this.app.post('/api/v1/chatflows', async (req: Request, res: Response) => {
const body = req.body
@@ -241,10 +345,16 @@ export class App {
const nodes = parsedFlowData.nodes
const edges = parsedFlowData.edges
const { graph, nodeDependencies } = constructGraphs(nodes, edges)
+
const endingNodeId = getEndingNode(nodeDependencies, graph)
- if (!endingNodeId) return res.status(500).send(`Ending node must be either a Chain or Agent`)
+ if (!endingNodeId) return res.status(500).send(`Ending node ${endingNodeId} not found`)
+
const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
- if (!endingNodeData) return res.status(500).send(`Ending node must be either a Chain or Agent`)
+ if (!endingNodeData) return res.status(500).send(`Ending node ${endingNodeId} data not found`)
+
+ if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
+ return res.status(500).send(`Ending node must be either a Chain or Agent`)
+ }
const obj = {
isStreaming: isFlowValidForStream(nodes, endingNodeData)
@@ -258,8 +368,13 @@ export class App {
// Get all chatmessages from chatflowid
this.app.get('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
- const chatmessages = await this.AppDataSource.getRepository(ChatMessage).findBy({
- chatflowid: req.params.id
+ const chatmessages = await this.AppDataSource.getRepository(ChatMessage).find({
+ where: {
+ chatflowid: req.params.id
+ },
+ order: {
+ createdDate: 'ASC'
+ }
})
return res.json(chatmessages)
})
@@ -278,10 +393,108 @@ export class App {
// Delete all chatmessages from chatflowid
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, this.AppDataSource, req.query.sessionId as string)
const results = await this.AppDataSource.getRepository(ChatMessage).delete({ chatflowid: req.params.id })
return res.json(results)
})
+ // ----------------------------------------
+ // Credentials
+ // ----------------------------------------
+
+ // Create new credential
+ this.app.post('/api/v1/credentials', async (req: Request, res: Response) => {
+ const body = req.body
+ const newCredential = await transformToCredentialEntity(body)
+ const credential = this.AppDataSource.getRepository(Credential).create(newCredential)
+ const results = await this.AppDataSource.getRepository(Credential).save(credential)
+ return res.json(results)
+ })
+
+ // Get all credentials
+ this.app.get('/api/v1/credentials', async (req: Request, res: Response) => {
+ if (req.query.credentialName) {
+ let returnCredentials = []
+ if (Array.isArray(req.query.credentialName)) {
+ for (let i = 0; i < req.query.credentialName.length; i += 1) {
+ const name = req.query.credentialName[i] as string
+ const credentials = await this.AppDataSource.getRepository(Credential).findBy({
+ credentialName: name
+ })
+ returnCredentials.push(...credentials)
+ }
+ } else {
+ const credentials = await this.AppDataSource.getRepository(Credential).findBy({
+ credentialName: req.query.credentialName as string
+ })
+ returnCredentials = [...credentials]
+ }
+ return res.json(returnCredentials)
+ } else {
+ const credentials = await this.AppDataSource.getRepository(Credential).find()
+ const returnCredentials = []
+ for (const credential of credentials) {
+ returnCredentials.push(omit(credential, ['encryptedData']))
+ }
+ return res.json(returnCredentials)
+ }
+ })
+
+ // Get specific credential
+ this.app.get('/api/v1/credentials/:id', async (req: Request, res: Response) => {
+ const credential = await this.AppDataSource.getRepository(Credential).findOneBy({
+ id: req.params.id
+ })
+
+ if (!credential) return res.status(404).send(`Credential ${req.params.id} not found`)
+
+ // Decrpyt credentialData
+ const decryptedCredentialData = await decryptCredentialData(
+ credential.encryptedData,
+ credential.credentialName,
+ this.nodesPool.componentCredentials
+ )
+ const returnCredential: ICredentialReturnResponse = {
+ ...credential,
+ plainDataObj: decryptedCredentialData
+ }
+ return res.json(omit(returnCredential, ['encryptedData']))
+ })
+
+ // Update credential
+ this.app.put('/api/v1/credentials/:id', async (req: Request, res: Response) => {
+ const credential = await this.AppDataSource.getRepository(Credential).findOneBy({
+ id: req.params.id
+ })
+
+ if (!credential) return res.status(404).send(`Credential ${req.params.id} not found`)
+
+ const body = req.body
+ const updateCredential = await transformToCredentialEntity(body)
+ this.AppDataSource.getRepository(Credential).merge(credential, updateCredential)
+ const result = await this.AppDataSource.getRepository(Credential).save(credential)
+
+ return res.json(result)
+ })
+
+ // Delete all chatmessages from chatflowid
+ this.app.delete('/api/v1/credentials/:id', async (req: Request, res: Response) => {
+ const results = await this.AppDataSource.getRepository(Credential).delete({ id: req.params.id })
+ return res.json(results)
+ })
+
// ----------------------------------------
// Tools
// ----------------------------------------
@@ -351,7 +564,13 @@ export class App {
const flowData = chatflow.flowData
const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
const nodes = parsedFlowData.nodes
- const availableConfigs = findAvailableConfigs(nodes)
+ const availableConfigs = findAvailableConfigs(nodes, this.nodesPool.componentCredentials)
+ return res.json(availableConfigs)
+ })
+
+ this.app.post('/api/v1/node-config', async (req: Request, res: Response) => {
+ const nodes = [{ data: req.body }] as IReactFlowNode[]
+ const availableConfigs = findAvailableConfigs(nodes, this.nodesPool.componentCredentials)
return res.json(availableConfigs)
})
@@ -425,12 +644,12 @@ export class App {
// ----------------------------------------
// Get all chatflows for marketplaces
- this.app.get('/api/v1/marketplaces', async (req: Request, res: Response) => {
- const marketplaceDir = path.join(__dirname, '..', 'marketplaces')
+ this.app.get('/api/v1/marketplaces/chatflows', async (req: Request, res: Response) => {
+ const marketplaceDir = path.join(__dirname, '..', 'marketplaces', 'chatflows')
const jsonsInDir = fs.readdirSync(marketplaceDir).filter((file) => path.extname(file) === '.json')
const templates: any[] = []
jsonsInDir.forEach((file, index) => {
- const filePath = path.join(__dirname, '..', 'marketplaces', file)
+ const filePath = path.join(__dirname, '..', 'marketplaces', 'chatflows', file)
const fileData = fs.readFileSync(filePath)
const fileDataObj = JSON.parse(fileData.toString())
const template = {
@@ -441,6 +660,27 @@ export class App {
}
templates.push(template)
})
+ const FlowiseDocsQnA = templates.find((tmp) => tmp.name === 'Flowise Docs QnA')
+ if (FlowiseDocsQnA) templates.unshift(FlowiseDocsQnA)
+ return res.json(templates)
+ })
+
+ // Get all tools for marketplaces
+ this.app.get('/api/v1/marketplaces/tools', async (req: Request, res: Response) => {
+ const marketplaceDir = path.join(__dirname, '..', 'marketplaces', 'tools')
+ const jsonsInDir = fs.readdirSync(marketplaceDir).filter((file) => path.extname(file) === '.json')
+ const templates: any[] = []
+ jsonsInDir.forEach((file, index) => {
+ const filePath = path.join(__dirname, '..', 'marketplaces', 'tools', file)
+ const fileData = fs.readFileSync(filePath)
+ const fileDataObj = JSON.parse(fileData.toString())
+ const template = {
+ ...fileDataObj,
+ id: index,
+ templateName: file.split('.json')[0]
+ }
+ templates.push(template)
+ })
return res.json(templates)
})
@@ -472,6 +712,17 @@ export class App {
return res.json(keys)
})
+ // Verify api key
+ this.app.get('/api/v1/verify/apikey/:apiKey', async (req: Request, res: Response) => {
+ try {
+ const apiKey = await getApiKey(req.params.apiKey)
+ if (!apiKey) return res.status(401).send('Unauthorized')
+ return res.status(200).send('OK')
+ } catch (err: any) {
+ return res.status(500).send(err?.message)
+ }
+ })
+
// ----------------------------------------
// Serve UI static
// ----------------------------------------
@@ -566,7 +817,7 @@ export class App {
})
})
} catch (err) {
- console.error(err)
+ logger.error('[server] [mode:child]: Error:', err)
}
}
@@ -590,7 +841,7 @@ export class App {
if (!chatflow) return res.status(404).send(`Chatflow ${chatflowid} not found`)
let chatId = await getChatId(chatflow.id)
- if (!chatId) chatId = Date.now().toString()
+ if (!chatId) chatId = chatflowid
if (!isInternal) {
await this.validateKey(req, res, chatflow)
@@ -620,13 +871,13 @@ export class App {
}
}
- /* Don't rebuild the flow (to avoid duplicated upsert, recomputation) when all these conditions met:
+ /* Reuse the flow without having to rebuild (to avoid duplicated upsert, recomputation) when all these conditions met:
* - Node Data already exists in pool
* - Still in sync (i.e the flow has not been modified since)
* - Existing overrideConfig and new overrideConfig are the same
* - Flow doesn't start with nodes that depend on incomingInput.question
***/
- const isRebuildNeeded = () => {
+ const isFlowReusable = () => {
return (
Object.prototype.hasOwnProperty.call(this.chatflowPool.activeChatflows, chatflowid) &&
this.chatflowPool.activeChatflows[chatflowid].inSync &&
@@ -640,11 +891,13 @@ export class App {
}
if (process.env.EXECUTION_MODE === 'child') {
- if (isRebuildNeeded()) {
+ if (isFlowReusable()) {
nodeToExecuteData = this.chatflowPool.activeChatflows[chatflowid].endingNodeData
+ logger.debug(
+ `[server] [mode:child]: Reuse existing chatflow ${chatflowid} with ending node ${nodeToExecuteData.label} (${nodeToExecuteData.id})`
+ )
try {
const result = await this.startChildProcess(chatflow, chatId, incomingInput, nodeToExecuteData)
-
return res.json(result)
} catch (error) {
return res.status(500).send(error)
@@ -664,18 +917,25 @@ export class App {
const nodes = parsedFlowData.nodes
const edges = parsedFlowData.edges
- if (isRebuildNeeded()) {
+ if (isFlowReusable()) {
nodeToExecuteData = this.chatflowPool.activeChatflows[chatflowid].endingNodeData
isStreamValid = isFlowValidForStream(nodes, nodeToExecuteData)
+ logger.debug(
+ `[server]: Reuse existing chatflow ${chatflowid} with ending node ${nodeToExecuteData.label} (${nodeToExecuteData.id})`
+ )
} else {
/*** Get Ending Node with Directed Graph ***/
const { graph, nodeDependencies } = constructGraphs(nodes, edges)
const directedGraph = graph
const endingNodeId = getEndingNode(nodeDependencies, directedGraph)
- if (!endingNodeId) return res.status(500).send(`Ending node must be either a Chain or Agent`)
+ if (!endingNodeId) return res.status(500).send(`Ending node ${endingNodeId} not found`)
const endingNodeData = nodes.find((nd) => nd.id === endingNodeId)?.data
- if (!endingNodeData) return res.status(500).send(`Ending node must be either a Chain or Agent`)
+ if (!endingNodeData) return res.status(500).send(`Ending node ${endingNodeId} data not found`)
+
+ if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
+ return res.status(500).send(`Ending node must be either a Chain or Agent`)
+ }
if (
endingNodeData.outputs &&
@@ -696,6 +956,7 @@ export class App {
const nonDirectedGraph = constructedObj.graph
const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId)
+ logger.debug(`[server]: Start building chatflow ${chatflowid}`)
/*** BFS to traverse from Starting Nodes to Ending Node ***/
const reactFlowNodes = await buildLangchain(
startingNodeIds,
@@ -712,6 +973,8 @@ export class App {
const nodeToExecute = reactFlowNodes.find((node: IReactFlowNode) => node.id === endingNodeId)
if (!nodeToExecute) return res.status(404).send(`Node ${endingNodeId} not found`)
+ if (incomingInput.overrideConfig)
+ nodeToExecute.data = replaceInputsWithConfig(nodeToExecute.data, incomingInput.overrideConfig)
const reactFlowNodeData: INodeData = resolveVariables(nodeToExecute.data, reactFlowNodes, incomingInput.question)
nodeToExecuteData = reactFlowNodeData
@@ -724,17 +987,21 @@ export class App {
const nodeInstance = new nodeModule.nodeClass()
isStreamValid = isStreamValid && !isVectorStoreFaiss(nodeToExecuteData)
+ logger.debug(`[server]: Running ${nodeToExecuteData.label} (${nodeToExecuteData.id})`)
const result = isStreamValid
? await nodeInstance.run(nodeToExecuteData, incomingInput.question, {
chatHistory: incomingInput.history,
socketIO,
- socketIOClientId: incomingInput.socketIOClientId
+ socketIOClientId: incomingInput.socketIOClientId,
+ logger
})
- : await nodeInstance.run(nodeToExecuteData, incomingInput.question, { chatHistory: incomingInput.history })
+ : await nodeInstance.run(nodeToExecuteData, incomingInput.question, { chatHistory: incomingInput.history, logger })
+ logger.debug(`[server]: Finished running ${nodeToExecuteData.label} (${nodeToExecuteData.id})`)
return res.json(result)
}
} catch (e: any) {
+ logger.error('[server]: Error:', e)
return res.status(500).send(e.message)
}
}
@@ -744,7 +1011,7 @@ export class App {
const removePromises: any[] = []
await Promise.all(removePromises)
} catch (e) {
- console.error(`β[server]: Flowise Server shut down error: ${e}`)
+ logger.error(`β[server]: Flowise Server shut down error: ${e}`)
}
}
}
@@ -784,7 +1051,7 @@ export async function start(): Promise {
await serverApp.config(io)
server.listen(port, () => {
- console.info(`β‘οΈ[server]: Flowise Server is listening at ${port}`)
+ logger.info(`β‘οΈ [server]: Flowise Server is listening at ${port}`)
})
}
diff --git a/packages/server/src/utils/config.ts b/packages/server/src/utils/config.ts
new file mode 100644
index 00000000..b5f5884e
--- /dev/null
+++ b/packages/server/src/utils/config.ts
@@ -0,0 +1,25 @@
+// BEWARE: This file is an intereem solution until we have a proper config strategy
+
+import path from 'path'
+import dotenv from 'dotenv'
+
+dotenv.config({ path: path.join(__dirname, '..', '..', '.env'), override: true })
+
+// default config
+const loggingConfig = {
+ dir: process.env.LOG_PATH ?? path.join(__dirname, '..', '..', 'logs'),
+ server: {
+ level: process.env.LOG_LEVEL ?? 'info',
+ filename: 'server.log',
+ errorFilename: 'server-error.log'
+ },
+ express: {
+ level: process.env.LOG_LEVEL ?? 'info',
+ format: 'jsonl', // can't be changed currently
+ filename: 'server-requests.log.jsonl' // should end with .jsonl
+ }
+}
+
+export default {
+ logging: loggingConfig
+}
diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts
index e3005c7b..2a68be47 100644
--- a/packages/server/src/utils/index.ts
+++ b/packages/server/src/utils/index.ts
@@ -1,6 +1,7 @@
import path from 'path'
import fs from 'fs'
import moment from 'moment'
+import logger from './logger'
import {
IComponentNodes,
IDepthQueue,
@@ -12,18 +13,26 @@ import {
IReactFlowNode,
IVariableDict,
INodeData,
- IOverrideConfig
+ IOverrideConfig,
+ ICredentialDataDecrypted,
+ IComponentCredentials,
+ ICredentialReqBody
} from '../Interface'
-import { cloneDeep, get, omit, merge } from 'lodash'
-import { ICommonObject, getInputVariables, IDatabaseEntity } from 'flowise-components'
+import { cloneDeep, get, omit, merge, isEqual } from 'lodash'
+import { ICommonObject, getInputVariables, IDatabaseEntity, handleEscapeCharacters } from 'flowise-components'
import { scryptSync, randomBytes, timingSafeEqual } from 'crypto'
+import { lib, PBKDF2, AES, enc } from 'crypto-js'
+
import { ChatFlow } from '../entity/ChatFlow'
import { ChatMessage } from '../entity/ChatMessage'
+import { Credential } from '../entity/Credential'
import { Tool } from '../entity/Tool'
import { DataSource } from 'typeorm'
const QUESTION_VAR_PREFIX = 'question'
-export const databaseEntities: IDatabaseEntity = { ChatFlow: ChatFlow, ChatMessage: ChatMessage, Tool: Tool }
+const REDACTED_CREDENTIAL_VALUE = '_FLOWISE_BLANK_07167752-1a71-43b1-bf8f-4f32252165db'
+
+export const databaseEntities: IDatabaseEntity = { ChatFlow: ChatFlow, ChatMessage: ChatMessage, Tool: Tool, Credential: Credential }
/**
* Returns the home folder path of the user if
@@ -173,12 +182,15 @@ export const getEndingNode = (nodeDependencies: INodeDependencies, graph: INodeD
/**
* Build langchain from start to end
- * @param {string} startingNodeId
+ * @param {string[]} startingNodeIds
* @param {IReactFlowNode[]} reactFlowNodes
* @param {INodeDirectedGraph} graph
* @param {IDepthQueue} depthQueue
* @param {IComponentNodes} componentNodes
* @param {string} question
+ * @param {string} chatId
+ * @param {DataSource} appDataSource
+ * @param {ICommonObject} overrideConfig
*/
export const buildLangchain = async (
startingNodeIds: string[],
@@ -221,13 +233,16 @@ export const buildLangchain = async (
if (overrideConfig) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig)
const reactFlowNodeData: INodeData = resolveVariables(flowNodeData, flowNodes, question)
+ logger.debug(`[server]: Initializing ${reactFlowNode.data.label} (${reactFlowNode.data.id})`)
flowNodes[nodeIndex].data.instance = await newNodeInstance.init(reactFlowNodeData, question, {
chatId,
appDataSource,
- databaseEntities
+ databaseEntities,
+ logger
})
+ logger.debug(`[server]: Finished initializing ${reactFlowNode.data.label} (${reactFlowNode.data.id})`)
} catch (e: any) {
- console.error(e)
+ logger.error(e)
throw new Error(e)
}
@@ -266,6 +281,32 @@ export const buildLangchain = async (
return flowNodes
}
+/**
+ * Clear memory
+ * @param {IReactFlowNode[]} reactFlowNodes
+ * @param {IComponentNodes} componentNodes
+ * @param {string} chatId
+ * @param {DataSource} appDataSource
+ * @param {string} sessionId
+ */
+export const clearSessionMemory = async (
+ reactFlowNodes: IReactFlowNode[],
+ componentNodes: IComponentNodes,
+ chatId: string,
+ appDataSource: DataSource,
+ 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, appDataSource, databaseEntities, logger })
+ }
+}
+
/**
* Get variable value from outputResponses.output
* @param {string} paramValue
@@ -295,8 +336,13 @@ export const getVariableValue = (paramValue: string, reactFlowNodes: IReactFlowN
const variableEndIdx = startIdx
const variableFullPath = returnVal.substring(variableStartIdx, variableEndIdx)
+ /**
+ * Apply string transformation to convert special chars:
+ * FROM: hello i am ben\n\n\thow are you?
+ * TO: hello i am benFLOWISE_NEWLINEFLOWISE_NEWLINEFLOWISE_TABhow are you?
+ */
if (isAcceptVariable && variableFullPath === QUESTION_VAR_PREFIX) {
- variableDict[`{{${variableFullPath}}}`] = question
+ variableDict[`{{${variableFullPath}}}`] = handleEscapeCharacters(question, false)
}
// Split by first occurrence of '.' to get just nodeId
@@ -398,9 +444,12 @@ export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig:
const types = 'inputs'
const getParamValues = (paramsObj: ICommonObject) => {
- for (const key in paramsObj) {
- const paramValue: string = paramsObj[key]
- paramsObj[key] = overrideConfig[key] ?? paramValue
+ for (const config in overrideConfig) {
+ let paramValue = overrideConfig[config] ?? paramsObj[config]
+ // Check if boolean
+ if (paramValue === 'true') paramValue = true
+ else if (paramValue === 'false') paramValue = false
+ paramsObj[config] = paramValue
}
}
@@ -449,7 +498,7 @@ export const isSameOverrideConfig = (
Object.keys(existingOverrideConfig).length &&
newOverrideConfig &&
Object.keys(newOverrideConfig).length &&
- JSON.stringify(existingOverrideConfig) === JSON.stringify(newOverrideConfig)
+ isEqual(existingOverrideConfig, newOverrideConfig)
) {
return true
}
@@ -463,7 +512,7 @@ export const isSameOverrideConfig = (
* @returns {string}
*/
export const getAPIKeyPath = (): string => {
- return path.join(__dirname, '..', '..', 'api.json')
+ return process.env.APIKEY_PATH ? path.join(process.env.APIKEY_PATH, 'api.json') : path.join(__dirname, '..', '..', 'api.json')
}
/**
@@ -547,6 +596,18 @@ export const addAPIKey = async (keyName: string): Promise => {
return content
}
+/**
+ * Get API Key details
+ * @param {string} apiKey
+ * @returns {Promise}
+ */
+export const getApiKey = async (apiKey: string) => {
+ const existingAPIKeys = await getAPIKeys()
+ const keyIndex = existingAPIKeys.findIndex((key) => key.apiKey === apiKey)
+ if (keyIndex < 0) return undefined
+ return existingAPIKeys[keyIndex]
+}
+
/**
* Update existing API key
* @param {string} keyIdToUpdate
@@ -583,7 +644,7 @@ export const replaceAllAPIKeys = async (content: ICommonObject[]): Promise
try {
await fs.promises.writeFile(getAPIKeyPath(), JSON.stringify(content), 'utf8')
} catch (error) {
- console.error(error)
+ logger.error(error)
}
}
@@ -602,39 +663,78 @@ export const mapMimeTypeToInputField = (mimeType: string) => {
return 'jsonFile'
case 'text/csv':
return 'csvFile'
+ case 'application/json-lines':
+ case 'application/jsonl':
+ case 'text/jsonl':
+ return 'jsonlinesFile'
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
return 'docxFile'
+ case 'application/vnd.yaml':
+ case 'application/x-yaml':
+ case 'text/vnd.yaml':
+ case 'text/x-yaml':
+ case 'text/yaml':
+ return 'yamlFile'
default:
return ''
}
}
/**
- * Find all available inpur params config
+ * Find all available input params config
* @param {IReactFlowNode[]} reactFlowNodes
- * @returns {Promise}
+ * @param {IComponentCredentials} componentCredentials
+ * @returns {IOverrideConfig[]}
*/
-export const findAvailableConfigs = (reactFlowNodes: IReactFlowNode[]) => {
+export const findAvailableConfigs = (reactFlowNodes: IReactFlowNode[], componentCredentials: IComponentCredentials) => {
const configs: IOverrideConfig[] = []
for (const flowNode of reactFlowNodes) {
for (const inputParam of flowNode.data.inputParams) {
let obj: IOverrideConfig
- if (inputParam.type === 'password' || inputParam.type === 'options') {
- continue
- } else if (inputParam.type === 'file') {
+ if (inputParam.type === 'file') {
obj = {
node: flowNode.data.label,
label: inputParam.label,
name: 'files',
type: inputParam.fileType ?? inputParam.type
}
+ } else if (inputParam.type === 'options') {
+ obj = {
+ node: flowNode.data.label,
+ label: inputParam.label,
+ name: inputParam.name,
+ type: inputParam.options
+ ? inputParam.options
+ ?.map((option) => {
+ return option.name
+ })
+ .join(', ')
+ : 'string'
+ }
+ } else if (inputParam.type === 'credential') {
+ // get component credential inputs
+ for (const name of inputParam.credentialNames ?? []) {
+ if (Object.prototype.hasOwnProperty.call(componentCredentials, name)) {
+ const inputs = componentCredentials[name]?.inputs ?? []
+ for (const input of inputs) {
+ obj = {
+ node: flowNode.data.label,
+ label: input.label,
+ name: input.name,
+ type: input.type === 'password' ? 'string' : input.type
+ }
+ configs.push(obj)
+ }
+ }
+ }
+ continue
} else {
obj = {
node: flowNode.data.label,
label: inputParam.label,
name: inputParam.name,
- type: inputParam.type
+ type: inputParam.type === 'password' ? 'string' : inputParam.type
}
}
if (!configs.some((config) => JSON.stringify(config) === JSON.stringify(obj))) {
@@ -668,10 +768,131 @@ export const isFlowValidForStream = (reactFlowNodes: IReactFlowNode[], endingNod
}
}
- return (
- isChatOrLLMsExist &&
- (endingNodeData.category === 'Chains' || endingNodeData.name === 'openAIFunctionAgent') &&
- !isVectorStoreFaiss(endingNodeData) &&
- process.env.EXECUTION_MODE !== 'child'
- )
+ let isValidChainOrAgent = false
+ if (endingNodeData.category === 'Chains') {
+ // Chains that are not available to stream
+ const blacklistChains = ['openApiChain']
+ isValidChainOrAgent = !blacklistChains.includes(endingNodeData.name)
+ } else if (endingNodeData.category === 'Agents') {
+ // Agent that are available to stream
+ const whitelistAgents = ['openAIFunctionAgent', 'csvAgent', 'airtableAgent']
+ isValidChainOrAgent = whitelistAgents.includes(endingNodeData.name)
+ }
+
+ return isChatOrLLMsExist && isValidChainOrAgent && !isVectorStoreFaiss(endingNodeData) && process.env.EXECUTION_MODE !== 'child'
+}
+
+/**
+ * Returns the path of encryption key
+ * @returns {string}
+ */
+export const getEncryptionKeyPath = (): string => {
+ return process.env.SECRETKEY_PATH
+ ? path.join(process.env.SECRETKEY_PATH, 'encryption.key')
+ : path.join(__dirname, '..', '..', 'encryption.key')
+}
+
+/**
+ * Generate an encryption key
+ * @returns {string}
+ */
+export const generateEncryptKey = (): string => {
+ const salt = lib.WordArray.random(128 / 8)
+ const key256Bits = PBKDF2(process.env.PASSPHRASE || 'MYPASSPHRASE', salt, {
+ keySize: 256 / 32,
+ iterations: 1000
+ })
+ return key256Bits.toString()
+}
+
+/**
+ * Returns the encryption key
+ * @returns {Promise}
+ */
+export const getEncryptionKey = async (): Promise => {
+ try {
+ return await fs.promises.readFile(getEncryptionKeyPath(), 'utf8')
+ } catch (error) {
+ const encryptKey = generateEncryptKey()
+ await fs.promises.writeFile(getEncryptionKeyPath(), encryptKey)
+ return encryptKey
+ }
+}
+
+/**
+ * Encrypt credential data
+ * @param {ICredentialDataDecrypted} plainDataObj
+ * @returns {Promise}
+ */
+export const encryptCredentialData = async (plainDataObj: ICredentialDataDecrypted): Promise => {
+ const encryptKey = await getEncryptionKey()
+ return AES.encrypt(JSON.stringify(plainDataObj), encryptKey).toString()
+}
+
+/**
+ * Decrypt credential data
+ * @param {string} encryptedData
+ * @param {string} componentCredentialName
+ * @param {IComponentCredentials} componentCredentials
+ * @returns {Promise}
+ */
+export const decryptCredentialData = async (
+ encryptedData: string,
+ componentCredentialName?: string,
+ componentCredentials?: IComponentCredentials
+): Promise => {
+ const encryptKey = await getEncryptionKey()
+ const decryptedData = AES.decrypt(encryptedData, encryptKey)
+ try {
+ if (componentCredentialName && componentCredentials) {
+ const plainDataObj = JSON.parse(decryptedData.toString(enc.Utf8))
+ return redactCredentialWithPasswordType(componentCredentialName, plainDataObj, componentCredentials)
+ }
+ return JSON.parse(decryptedData.toString(enc.Utf8))
+ } catch (e) {
+ console.error(e)
+ throw new Error('Credentials could not be decrypted.')
+ }
+}
+
+/**
+ * Transform ICredentialBody from req to Credential entity
+ * @param {ICredentialReqBody} body
+ * @returns {Credential}
+ */
+export const transformToCredentialEntity = async (body: ICredentialReqBody): Promise => {
+ const encryptedData = await encryptCredentialData(body.plainDataObj)
+
+ const credentialBody = {
+ name: body.name,
+ credentialName: body.credentialName,
+ encryptedData
+ }
+
+ const newCredential = new Credential()
+ Object.assign(newCredential, credentialBody)
+
+ return newCredential
+}
+
+/**
+ * Redact values that are of password type to avoid sending back to client
+ * @param {string} componentCredentialName
+ * @param {ICredentialDataDecrypted} decryptedCredentialObj
+ * @param {IComponentCredentials} componentCredentials
+ * @returns {ICredentialDataDecrypted}
+ */
+export const redactCredentialWithPasswordType = (
+ componentCredentialName: string,
+ decryptedCredentialObj: ICredentialDataDecrypted,
+ componentCredentials: IComponentCredentials
+): ICredentialDataDecrypted => {
+ const plainDataObj = cloneDeep(decryptedCredentialObj)
+ for (const cred in plainDataObj) {
+ const inputParam = componentCredentials[componentCredentialName].inputs?.find((inp) => inp.type === 'password' && inp.name === cred)
+ if (inputParam) {
+ plainDataObj[cred] = REDACTED_CREDENTIAL_VALUE
+ }
+ }
+ return plainDataObj
}
diff --git a/packages/server/src/utils/logger.ts b/packages/server/src/utils/logger.ts
new file mode 100644
index 00000000..839f1ad7
--- /dev/null
+++ b/packages/server/src/utils/logger.ts
@@ -0,0 +1,106 @@
+import * as path from 'path'
+import * as fs from 'fs'
+import config from './config' // should be replaced by node-config or similar
+import { createLogger, transports, format } from 'winston'
+import { NextFunction, Request, Response } from 'express'
+
+const { combine, timestamp, printf, errors } = format
+
+// expect the log dir be relative to the projects root
+const logDir = config.logging.dir
+
+// Create the log directory if it doesn't exist
+if (!fs.existsSync(logDir)) {
+ fs.mkdirSync(logDir)
+}
+
+const logger = createLogger({
+ format: combine(
+ timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
+ format.json(),
+ printf(({ level, message, timestamp, stack }) => {
+ const text = `${timestamp} [${level.toUpperCase()}]: ${message}`
+ return stack ? text + '\n' + stack : text
+ }),
+ errors({ stack: true })
+ ),
+ defaultMeta: {
+ package: 'server'
+ },
+ transports: [
+ new transports.Console(),
+ new transports.File({
+ filename: path.join(logDir, config.logging.server.filename ?? 'server.log'),
+ level: config.logging.server.level ?? 'info'
+ }),
+ new transports.File({
+ filename: path.join(logDir, config.logging.server.errorFilename ?? 'server-error.log'),
+ level: 'error' // Log only errors to this file
+ })
+ ],
+ exceptionHandlers: [
+ new transports.File({
+ filename: path.join(logDir, config.logging.server.errorFilename ?? 'server-error.log')
+ })
+ ],
+ rejectionHandlers: [
+ new transports.File({
+ filename: path.join(logDir, config.logging.server.errorFilename ?? 'server-error.log')
+ })
+ ]
+})
+
+/**
+ * This function is used by express as a middleware.
+ * @example
+ * this.app = express()
+ * this.app.use(expressRequestLogger)
+ */
+export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void {
+ const unwantedLogURLs = ['/api/v1/node-icon/']
+ if (req.url.includes('/api/v1/') && !unwantedLogURLs.some((url) => req.url.includes(url))) {
+ const fileLogger = createLogger({
+ format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.json(), errors({ stack: true })),
+ defaultMeta: {
+ package: 'server',
+ request: {
+ method: req.method,
+ url: req.url,
+ body: req.body,
+ 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'),
+ level: config.logging.express.level ?? 'debug'
+ })
+ ]
+ })
+
+ const getRequestEmoji = (method: string) => {
+ const requetsEmojis: Record = {
+ GET: 'β¬οΈ',
+ POST: 'β¬οΈ',
+ PUT: 'π',
+ DELETE: 'β',
+ OPTION: 'π'
+ }
+
+ 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}`)
+ } else {
+ fileLogger.http(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
+ }
+ }
+
+ next()
+}
+
+export default logger
diff --git a/packages/ui/craco.config.js b/packages/ui/craco.config.js
new file mode 100644
index 00000000..142305e0
--- /dev/null
+++ b/packages/ui/craco.config.js
@@ -0,0 +1,16 @@
+module.exports = {
+ webpack: {
+ configure: {
+ module: {
+ rules: [
+ {
+ test: /\.m?js$/,
+ resolve: {
+ fullySpecified: false
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 258b5471..a2eeec6f 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -1,6 +1,6 @@
{
"name": "flowise-ui",
- "version": "1.2.12",
+ "version": "1.3.0",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://flowiseai.com",
"author": {
@@ -16,6 +16,9 @@
"@mui/x-data-grid": "^6.8.0",
"@tabler/icons": "^1.39.1",
"clsx": "^1.1.1",
+ "flowise-embed": "*",
+ "flowise-embed-react": "*",
+ "flowise-react-json-view": "*",
"formik": "^2.2.6",
"framer-motion": "^4.1.13",
"history": "^5.0.0",
@@ -27,10 +30,10 @@
"prop-types": "^15.7.2",
"react": "^18.2.0",
"react-code-blocks": "^0.0.9-0",
+ "react-color": "^2.19.3",
"react-datepicker": "^4.8.0",
"react-device-detect": "^1.17.0",
"react-dom": "^18.2.0",
- "react-json-view": "^1.21.3",
"react-markdown": "^8.0.6",
"react-perfect-scrollbar": "^1.5.8",
"react-redux": "^8.0.5",
@@ -47,11 +50,11 @@
"yup": "^0.32.9"
},
"scripts": {
- "start": "react-scripts start",
- "dev": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
+ "start": "craco start",
+ "dev": "craco start",
+ "build": "craco build",
+ "test": "craco test",
+ "eject": "craco eject"
},
"babel": {
"presets": [
@@ -72,6 +75,7 @@
},
"devDependencies": {
"@babel/eslint-parser": "^7.15.8",
+ "@craco/craco": "^7.1.0",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^12.8.3",
diff --git a/packages/ui/public/index.html b/packages/ui/public/index.html
index 270cc805..b4ec9ea1 100644
--- a/packages/ui/public/index.html
+++ b/packages/ui/public/index.html
@@ -1,13 +1,13 @@
- Flowise - LangchainJS UI
+ Flowise - Low-code LLM apps builder
-
+
@@ -17,13 +17,13 @@
-
+
-
+
diff --git a/packages/ui/src/api/chatflows.js b/packages/ui/src/api/chatflows.js
index 1cd1ebb0..8810b5a5 100644
--- a/packages/ui/src/api/chatflows.js
+++ b/packages/ui/src/api/chatflows.js
@@ -4,6 +4,8 @@ const getAllChatflows = () => client.get('/chatflows')
const getSpecificChatflow = (id) => client.get(`/chatflows/${id}`)
+const getSpecificChatflowFromPublicEndpoint = (id) => client.get(`/public-chatflows/${id}`)
+
const createNewChatflow = (body) => client.post(`/chatflows`, body)
const updateChatflow = (id, body) => client.put(`/chatflows/${id}`, body)
@@ -15,6 +17,7 @@ const getIsChatflowStreaming = (id) => client.get(`/chatflows-streaming/${id}`)
export default {
getAllChatflows,
getSpecificChatflow,
+ getSpecificChatflowFromPublicEndpoint,
createNewChatflow,
updateChatflow,
deleteChatflow,
diff --git a/packages/ui/src/api/config.js b/packages/ui/src/api/config.js
index 0fb8297d..47ee51a0 100644
--- a/packages/ui/src/api/config.js
+++ b/packages/ui/src/api/config.js
@@ -1,7 +1,9 @@
import client from './client'
const getConfig = (id) => client.get(`/flow-config/${id}`)
+const getNodeConfig = (body) => client.post(`/node-config`, body)
export default {
- getConfig
+ getConfig,
+ getNodeConfig
}
diff --git a/packages/ui/src/api/credentials.js b/packages/ui/src/api/credentials.js
new file mode 100644
index 00000000..9dbdcf7a
--- /dev/null
+++ b/packages/ui/src/api/credentials.js
@@ -0,0 +1,28 @@
+import client from './client'
+
+const getAllCredentials = () => client.get('/credentials')
+
+const getCredentialsByName = (componentCredentialName) => client.get(`/credentials?credentialName=${componentCredentialName}`)
+
+const getAllComponentsCredentials = () => client.get('/components-credentials')
+
+const getSpecificCredential = (id) => client.get(`/credentials/${id}`)
+
+const getSpecificComponentCredential = (name) => client.get(`/components-credentials/${name}`)
+
+const createCredential = (body) => client.post(`/credentials`, body)
+
+const updateCredential = (id, body) => client.put(`/credentials/${id}`, body)
+
+const deleteCredential = (id) => client.delete(`/credentials/${id}`)
+
+export default {
+ getAllCredentials,
+ getCredentialsByName,
+ getAllComponentsCredentials,
+ getSpecificCredential,
+ getSpecificComponentCredential,
+ createCredential,
+ updateCredential,
+ deleteCredential
+}
diff --git a/packages/ui/src/api/marketplaces.js b/packages/ui/src/api/marketplaces.js
index 6906fb4e..3fd4ae87 100644
--- a/packages/ui/src/api/marketplaces.js
+++ b/packages/ui/src/api/marketplaces.js
@@ -1,7 +1,9 @@
import client from './client'
-const getAllMarketplaces = () => client.get('/marketplaces')
+const getAllChatflowsMarketplaces = () => client.get('/marketplaces/chatflows')
+const getAllToolsMarketplaces = () => client.get('/marketplaces/tools')
export default {
- getAllMarketplaces
+ getAllChatflowsMarketplaces,
+ getAllToolsMarketplaces
}
diff --git a/packages/ui/src/assets/images/account.png b/packages/ui/src/assets/images/account.png
new file mode 100644
index 00000000..a758a1db
Binary files /dev/null and b/packages/ui/src/assets/images/account.png differ
diff --git a/packages/ui/src/assets/images/credential_empty.svg b/packages/ui/src/assets/images/credential_empty.svg
new file mode 100644
index 00000000..0951ee07
--- /dev/null
+++ b/packages/ui/src/assets/images/credential_empty.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/ui/src/assets/images/robot.png b/packages/ui/src/assets/images/robot.png
new file mode 100644
index 00000000..d4fe920a
Binary files /dev/null and b/packages/ui/src/assets/images/robot.png differ
diff --git a/packages/ui/src/assets/images/sharing.png b/packages/ui/src/assets/images/sharing.png
new file mode 100644
index 00000000..1e538f2e
Binary files /dev/null and b/packages/ui/src/assets/images/sharing.png differ
diff --git a/packages/ui/src/menu-items/dashboard.js b/packages/ui/src/menu-items/dashboard.js
index 948b4e4a..87ef88f9 100644
--- a/packages/ui/src/menu-items/dashboard.js
+++ b/packages/ui/src/menu-items/dashboard.js
@@ -1,8 +1,8 @@
// assets
-import { IconHierarchy, IconBuildingStore, IconKey, IconTool } from '@tabler/icons'
+import { IconHierarchy, IconBuildingStore, IconKey, IconTool, IconLock } from '@tabler/icons'
// constant
-const icons = { IconHierarchy, IconBuildingStore, IconKey, IconTool }
+const icons = { IconHierarchy, IconBuildingStore, IconKey, IconTool, IconLock }
// ==============================|| DASHBOARD MENU ITEMS ||============================== //
@@ -35,6 +35,14 @@ const dashboard = {
icon: icons.IconTool,
breadcrumbs: true
},
+ {
+ id: 'credentials',
+ title: 'Credentials',
+ type: 'item',
+ url: '/credentials',
+ icon: icons.IconLock,
+ breadcrumbs: true
+ },
{
id: 'apikey',
title: 'API Keys',
diff --git a/packages/ui/src/routes/ChatbotRoutes.js b/packages/ui/src/routes/ChatbotRoutes.js
new file mode 100644
index 00000000..25d298d6
--- /dev/null
+++ b/packages/ui/src/routes/ChatbotRoutes.js
@@ -0,0 +1,23 @@
+import { lazy } from 'react'
+
+// project imports
+import Loadable from 'ui-component/loading/Loadable'
+import MinimalLayout from 'layout/MinimalLayout'
+
+// canvas routing
+const ChatbotFull = Loadable(lazy(() => import('views/chatbot')))
+
+// ==============================|| CANVAS ROUTING ||============================== //
+
+const ChatbotRoutes = {
+ path: '/',
+ element: ,
+ children: [
+ {
+ path: '/chatbot/:id',
+ element:
+ }
+ ]
+}
+
+export default ChatbotRoutes
diff --git a/packages/ui/src/routes/MainRoutes.js b/packages/ui/src/routes/MainRoutes.js
index 28e60287..9a1c29af 100644
--- a/packages/ui/src/routes/MainRoutes.js
+++ b/packages/ui/src/routes/MainRoutes.js
@@ -13,9 +13,12 @@ const Marketplaces = Loadable(lazy(() => import('views/marketplaces')))
// apikey routing
const APIKey = Loadable(lazy(() => import('views/apikey')))
-// apikey routing
+// tools routing
const Tools = Loadable(lazy(() => import('views/tools')))
+// credentials routing
+const Credentials = Loadable(lazy(() => import('views/credentials')))
+
// ==============================|| MAIN ROUTING ||============================== //
const MainRoutes = {
@@ -41,6 +44,10 @@ const MainRoutes = {
{
path: '/tools',
element:
+ },
+ {
+ path: '/credentials',
+ element:
}
]
}
diff --git a/packages/ui/src/routes/index.js b/packages/ui/src/routes/index.js
index 15fe4dca..ff8c1920 100644
--- a/packages/ui/src/routes/index.js
+++ b/packages/ui/src/routes/index.js
@@ -3,10 +3,11 @@ import { useRoutes } from 'react-router-dom'
// routes
import MainRoutes from './MainRoutes'
import CanvasRoutes from './CanvasRoutes'
+import ChatbotRoutes from './ChatbotRoutes'
import config from 'config'
// ==============================|| ROUTING RENDER ||============================== //
export default function ThemeRoutes() {
- return useRoutes([MainRoutes, CanvasRoutes], config.basename)
+ return useRoutes([MainRoutes, CanvasRoutes, ChatbotRoutes], config.basename)
}
diff --git a/packages/ui/src/store/actions.js b/packages/ui/src/store/actions.js
index 306c5cb0..0c68f8f2 100644
--- a/packages/ui/src/store/actions.js
+++ b/packages/ui/src/store/actions.js
@@ -11,6 +11,10 @@ export const SET_DARKMODE = '@customization/SET_DARKMODE'
export const SET_DIRTY = '@canvas/SET_DIRTY'
export const REMOVE_DIRTY = '@canvas/REMOVE_DIRTY'
export const SET_CHATFLOW = '@canvas/SET_CHATFLOW'
+export const SHOW_CANVAS_DIALOG = '@canvas/SHOW_CANVAS_DIALOG'
+export const HIDE_CANVAS_DIALOG = '@canvas/HIDE_CANVAS_DIALOG'
+export const SET_COMPONENT_NODES = '@canvas/SET_COMPONENT_NODES'
+export const SET_COMPONENT_CREDENTIALS = '@canvas/SET_COMPONENT_CREDENTIALS'
// action - notifier reducer
export const ENQUEUE_SNACKBAR = 'ENQUEUE_SNACKBAR'
diff --git a/packages/ui/src/store/constant.js b/packages/ui/src/store/constant.js
index c3138257..c0fce49d 100644
--- a/packages/ui/src/store/constant.js
+++ b/packages/ui/src/store/constant.js
@@ -5,3 +5,4 @@ export const appDrawerWidth = 320
export const maxScroll = 100000
export const baseURL = process.env.NODE_ENV === 'production' ? window.location.origin : window.location.origin.replace(':8080', ':3000')
export const uiBaseURL = window.location.origin
+export const FLOWISE_CREDENTIAL_ID = 'FLOWISE_CREDENTIAL_ID'
diff --git a/packages/ui/src/store/context/ReactFlowContext.js b/packages/ui/src/store/context/ReactFlowContext.js
index 4c35d702..055cb8bc 100644
--- a/packages/ui/src/store/context/ReactFlowContext.js
+++ b/packages/ui/src/store/context/ReactFlowContext.js
@@ -1,7 +1,9 @@
import { createContext, useState } from 'react'
+import { useDispatch } from 'react-redux'
import PropTypes from 'prop-types'
import { getUniqueNodeId } from 'utils/genericHelper'
import { cloneDeep } from 'lodash'
+import { SET_DIRTY } from 'store/actions'
const initialValue = {
reactFlowInstance: null,
@@ -14,17 +16,20 @@ const initialValue = {
export const flowContext = createContext(initialValue)
export const ReactFlowContext = ({ children }) => {
+ const dispatch = useDispatch()
const [reactFlowInstance, setReactFlowInstance] = useState(null)
const deleteNode = (nodeid) => {
deleteConnectedInput(nodeid, 'node')
reactFlowInstance.setNodes(reactFlowInstance.getNodes().filter((n) => n.id !== nodeid))
reactFlowInstance.setEdges(reactFlowInstance.getEdges().filter((ns) => ns.source !== nodeid && ns.target !== nodeid))
+ dispatch({ type: SET_DIRTY })
}
const deleteEdge = (edgeid) => {
deleteConnectedInput(edgeid, 'edge')
reactFlowInstance.setEdges(reactFlowInstance.getEdges().filter((edge) => edge.id !== edgeid))
+ dispatch({ type: SET_DIRTY })
}
const deleteConnectedInput = (id, type) => {
@@ -103,6 +108,7 @@ export const ReactFlowContext = ({ children }) => {
}
reactFlowInstance.setNodes([...nodes, duplicatedNode])
+ dispatch({ type: SET_DIRTY })
}
}
diff --git a/packages/ui/src/store/reducers/canvasReducer.js b/packages/ui/src/store/reducers/canvasReducer.js
index e98805bb..1c5e486f 100644
--- a/packages/ui/src/store/reducers/canvasReducer.js
+++ b/packages/ui/src/store/reducers/canvasReducer.js
@@ -3,7 +3,10 @@ import * as actionTypes from '../actions'
export const initialState = {
isDirty: false,
- chatflow: null
+ chatflow: null,
+ canvasDialogShow: false,
+ componentNodes: [],
+ componentCredentials: []
}
// ==============================|| CANVAS REDUCER ||============================== //
@@ -25,6 +28,26 @@ const canvasReducer = (state = initialState, action) => {
...state,
chatflow: action.chatflow
}
+ case actionTypes.SHOW_CANVAS_DIALOG:
+ return {
+ ...state,
+ canvasDialogShow: true
+ }
+ case actionTypes.HIDE_CANVAS_DIALOG:
+ return {
+ ...state,
+ canvasDialogShow: false
+ }
+ case actionTypes.SET_COMPONENT_NODES:
+ return {
+ ...state,
+ componentNodes: action.componentNodes
+ }
+ case actionTypes.SET_COMPONENT_CREDENTIALS:
+ return {
+ ...state,
+ componentCredentials: action.componentCredentials
+ }
default:
return state
}
diff --git a/packages/ui/src/themes/compStyleOverride.js b/packages/ui/src/themes/compStyleOverride.js
index b7ebc8b2..c04cc3f1 100644
--- a/packages/ui/src/themes/compStyleOverride.js
+++ b/packages/ui/src/themes/compStyleOverride.js
@@ -136,6 +136,9 @@ export default function componentStyleOverrides(theme) {
'&::placeholder': {
color: theme.darkTextSecondary,
fontSize: '0.875rem'
+ },
+ '&.Mui-disabled': {
+ WebkitTextFillColor: theme?.customization?.isDarkMode ? theme.colors?.grey500 : theme.darkTextSecondary
}
}
}
diff --git a/packages/ui/src/themes/palette.js b/packages/ui/src/themes/palette.js
index 9e7b7620..19a7df11 100644
--- a/packages/ui/src/themes/palette.js
+++ b/packages/ui/src/themes/palette.js
@@ -90,6 +90,10 @@ export default function themePalette(theme) {
},
codeEditor: {
main: theme.customization.isDarkMode ? theme.colors?.darkPrimary800 : theme.colors?.primaryLight
+ },
+ nodeToolTip: {
+ background: theme.customization.isDarkMode ? theme.colors?.darkPrimary800 : theme.colors?.paper,
+ color: theme.customization.isDarkMode ? theme.colors?.paper : 'rgba(0, 0, 0, 0.87)'
}
}
}
diff --git a/packages/ui/src/ui-component/cards/ItemCard.js b/packages/ui/src/ui-component/cards/ItemCard.js
index 345a88d5..1e8789d7 100644
--- a/packages/ui/src/ui-component/cards/ItemCard.js
+++ b/packages/ui/src/ui-component/cards/ItemCard.js
@@ -27,7 +27,7 @@ const CardWrapper = styled(MainCard)(({ theme }) => ({
// ===========================|| CONTRACT CARD ||=========================== //
-const ItemCard = ({ isLoading, data, images, color, onClick }) => {
+const ItemCard = ({ isLoading, data, images, onClick }) => {
return (
<>
{isLoading ? (
@@ -43,21 +43,35 @@ const ItemCard = ({ isLoading, data, images, color, onClick }) => {
alignItems: 'center'
}}
>
- {color && (
+ {data.iconSrc && (
+ )}
+ {!data.iconSrc && data.color && (
+
)}
- {data.name}
+ {data.templateName || data.name}
{data.description && (
@@ -107,7 +121,6 @@ ItemCard.propTypes = {
isLoading: PropTypes.bool,
data: PropTypes.object,
images: PropTypes.array,
- color: PropTypes.string,
onClick: PropTypes.func
}
diff --git a/packages/ui/src/ui-component/dialog/AdditionalParamsDialog.js b/packages/ui/src/ui-component/dialog/AdditionalParamsDialog.js
index 66a1eaf6..7cf9b3b7 100644
--- a/packages/ui/src/ui-component/dialog/AdditionalParamsDialog.js
+++ b/packages/ui/src/ui-component/dialog/AdditionalParamsDialog.js
@@ -1,12 +1,15 @@
import { createPortal } from 'react-dom'
+import { useDispatch } from 'react-redux'
import { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { Dialog, DialogContent } from '@mui/material'
import PerfectScrollbar from 'react-perfect-scrollbar'
import NodeInputHandler from 'views/canvas/NodeInputHandler'
+import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
const AdditionalParamsDialog = ({ show, dialogProps, onCancel }) => {
const portalElement = document.getElementById('portal')
+ const dispatch = useDispatch()
const [inputParams, setInputParams] = useState([])
const [data, setData] = useState({})
@@ -21,6 +24,12 @@ const AdditionalParamsDialog = ({ show, dialogProps, onCancel }) => {
}
}, [dialogProps])
+ useEffect(() => {
+ if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
+ else dispatch({ type: HIDE_CANVAS_DIALOG })
+ return () => dispatch({ type: HIDE_CANVAS_DIALOG })
+ }, [show, dispatch])
+
const component = show ? (
diff --git a/packages/ui/src/views/chatmessage/ChatMessage.css b/packages/ui/src/views/chatmessage/ChatMessage.css
index ef7f1e93..3b006c1d 100644
--- a/packages/ui/src/views/chatmessage/ChatMessage.css
+++ b/packages/ui/src/views/chatmessage/ChatMessage.css
@@ -127,7 +127,8 @@
.cloud-dialog {
width: 100%;
- height: calc(100vh - 230px);
+ height: 100vh;
+ overflow-y: scroll;
border-radius: 0.5rem;
display: flex;
justify-content: center;
diff --git a/packages/ui/src/views/chatmessage/ChatMessage.js b/packages/ui/src/views/chatmessage/ChatMessage.js
index 5021cd9b..b89af7bb 100644
--- a/packages/ui/src/views/chatmessage/ChatMessage.js
+++ b/packages/ui/src/views/chatmessage/ChatMessage.js
@@ -28,6 +28,9 @@ import useApi from 'hooks/useApi'
// Const
import { baseURL, maxScroll } from 'store/constant'
+import robotPNG from 'assets/images/robot.png'
+import userPNG from 'assets/images/account.png'
+
export const ChatMessage = ({ open, chatflowid, isDialog }) => {
const theme = useTheme()
const customization = useSelector((state) => state.customization)
@@ -163,7 +166,9 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => {
// Prevent blank submissions and allow for multiline input
const handleEnter = (e) => {
- if (e.key === 'Enter' && userInput) {
+ // Check if IME composition is in progress
+ const isIMEComposition = e.isComposing || e.keyCode === 229
+ if (e.key === 'Enter' && userInput && !isIMEComposition) {
if (!e.shiftKey && userInput) {
handleSubmit(e)
}
@@ -279,21 +284,9 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => {
>
{/* Display the correct icon depending on the message type */}
{message.type === 'apiMessage' ? (
-
+
) : (
-
+
)}
@@ -366,6 +359,7 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => {
value={userInput}
onChange={onChange}
multiline={true}
+ maxRows={isDialog ? 7 : 2}
endAdornment={
diff --git a/packages/ui/src/views/credentials/AddEditCredentialDialog.js b/packages/ui/src/views/credentials/AddEditCredentialDialog.js
new file mode 100644
index 00000000..65b72a5f
--- /dev/null
+++ b/packages/ui/src/views/credentials/AddEditCredentialDialog.js
@@ -0,0 +1,283 @@
+import { createPortal } from 'react-dom'
+import PropTypes from 'prop-types'
+import { useState, useEffect } from 'react'
+import { useDispatch } from 'react-redux'
+import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction } from 'store/actions'
+import parser from 'html-react-parser'
+
+// Material
+import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Box, Stack, OutlinedInput, Typography } from '@mui/material'
+
+// Project imports
+import { StyledButton } from 'ui-component/button/StyledButton'
+import ConfirmDialog from 'ui-component/dialog/ConfirmDialog'
+import CredentialInputHandler from './CredentialInputHandler'
+
+// Icons
+import { IconX } from '@tabler/icons'
+
+// API
+import credentialsApi from 'api/credentials'
+
+// Hooks
+import useApi from 'hooks/useApi'
+
+// utils
+import useNotifier from 'utils/useNotifier'
+
+// const
+import { baseURL } from 'store/constant'
+import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
+
+const AddEditCredentialDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
+ const portalElement = document.getElementById('portal')
+
+ const dispatch = useDispatch()
+
+ // ==============================|| Snackbar ||============================== //
+
+ useNotifier()
+
+ const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
+ const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
+
+ const getSpecificCredentialApi = useApi(credentialsApi.getSpecificCredential)
+ const getSpecificComponentCredentialApi = useApi(credentialsApi.getSpecificComponentCredential)
+
+ const [credential, setCredential] = useState({})
+ const [name, setName] = useState('')
+ const [credentialData, setCredentialData] = useState({})
+ const [componentCredential, setComponentCredential] = useState({})
+
+ useEffect(() => {
+ if (getSpecificCredentialApi.data) {
+ setCredential(getSpecificCredentialApi.data)
+ if (getSpecificCredentialApi.data.name) {
+ setName(getSpecificCredentialApi.data.name)
+ }
+ if (getSpecificCredentialApi.data.plainDataObj) {
+ setCredentialData(getSpecificCredentialApi.data.plainDataObj)
+ }
+ getSpecificComponentCredentialApi.request(getSpecificCredentialApi.data.credentialName)
+ }
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [getSpecificCredentialApi.data])
+
+ useEffect(() => {
+ if (getSpecificComponentCredentialApi.data) {
+ setComponentCredential(getSpecificComponentCredentialApi.data)
+ }
+ }, [getSpecificComponentCredentialApi.data])
+
+ useEffect(() => {
+ if (dialogProps.type === 'EDIT' && dialogProps.data) {
+ // When credential dialog is opened from Credentials dashboard
+ getSpecificCredentialApi.request(dialogProps.data.id)
+ } else if (dialogProps.type === 'EDIT' && dialogProps.credentialId) {
+ // When credential dialog is opened from node in canvas
+ getSpecificCredentialApi.request(dialogProps.credentialId)
+ } else if (dialogProps.type === 'ADD' && dialogProps.credentialComponent) {
+ // When credential dialog is to add a new credential
+ setName('')
+ setCredential({})
+ setCredentialData({})
+ setComponentCredential(dialogProps.credentialComponent)
+ }
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dialogProps])
+
+ useEffect(() => {
+ if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
+ else dispatch({ type: HIDE_CANVAS_DIALOG })
+ return () => dispatch({ type: HIDE_CANVAS_DIALOG })
+ }, [show, dispatch])
+
+ const addNewCredential = async () => {
+ try {
+ const obj = {
+ name,
+ credentialName: componentCredential.name,
+ plainDataObj: credentialData
+ }
+ const createResp = await credentialsApi.createCredential(obj)
+ if (createResp.data) {
+ enqueueSnackbar({
+ message: 'New Credential added',
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'success',
+ action: (key) => (
+
+ )
+ }
+ })
+ onConfirm(createResp.data.id)
+ }
+ } catch (error) {
+ const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
+ enqueueSnackbar({
+ message: `Failed to add new Credential: ${errorData}`,
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'error',
+ persist: true,
+ action: (key) => (
+
+ )
+ }
+ })
+ onCancel()
+ }
+ }
+
+ const saveCredential = async () => {
+ try {
+ const saveResp = await credentialsApi.updateCredential(credential.id, {
+ name,
+ credentialName: componentCredential.name,
+ plainDataObj: credentialData
+ })
+ if (saveResp.data) {
+ enqueueSnackbar({
+ message: 'Credential saved',
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'success',
+ action: (key) => (
+
+ )
+ }
+ })
+ onConfirm(saveResp.data.id)
+ }
+ } catch (error) {
+ const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
+ enqueueSnackbar({
+ message: `Failed to save Credential: ${errorData}`,
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'error',
+ persist: true,
+ action: (key) => (
+
+ )
+ }
+ })
+ onCancel()
+ }
+ }
+
+ const component = show ? (
+
+
+ {componentCredential && componentCredential.label && (
+
+
+

+
+ {componentCredential.label}
+
+ )}
+
+
+ {componentCredential && componentCredential.description && (
+
+
+ {parser(componentCredential.description)}
+
+
+ )}
+ {componentCredential && componentCredential.label && (
+
+
+
+ Credential Name
+ *
+
+
+ setName(e.target.value)}
+ />
+
+ )}
+ {componentCredential &&
+ componentCredential.inputs &&
+ componentCredential.inputs.map((inputParam, index) => (
+
+ ))}
+
+
+ (dialogProps.type === 'ADD' ? addNewCredential() : saveCredential())}
+ >
+ {dialogProps.confirmButtonName}
+
+
+
+
+ ) : null
+
+ return createPortal(component, portalElement)
+}
+
+AddEditCredentialDialog.propTypes = {
+ show: PropTypes.bool,
+ dialogProps: PropTypes.object,
+ onCancel: PropTypes.func,
+ onConfirm: PropTypes.func
+}
+
+export default AddEditCredentialDialog
diff --git a/packages/ui/src/views/credentials/CredentialInputHandler.js b/packages/ui/src/views/credentials/CredentialInputHandler.js
new file mode 100644
index 00000000..30cc5746
--- /dev/null
+++ b/packages/ui/src/views/credentials/CredentialInputHandler.js
@@ -0,0 +1,137 @@
+import PropTypes from 'prop-types'
+import { useRef, useState } from 'react'
+import { useSelector } from 'react-redux'
+
+// material-ui
+import { Box, Typography, IconButton } from '@mui/material'
+import { IconArrowsMaximize, IconAlertTriangle } from '@tabler/icons'
+
+// project import
+import { Dropdown } from 'ui-component/dropdown/Dropdown'
+import { Input } from 'ui-component/input/Input'
+import { SwitchInput } from 'ui-component/switch/Switch'
+import { JsonEditorInput } from 'ui-component/json/JsonEditor'
+import { TooltipWithParser } from 'ui-component/tooltip/TooltipWithParser'
+
+// ===========================|| NodeInputHandler ||=========================== //
+
+const CredentialInputHandler = ({ inputParam, data, disabled = false }) => {
+ const customization = useSelector((state) => state.customization)
+ const ref = useRef(null)
+
+ const [showExpandDialog, setShowExpandDialog] = useState(false)
+ const [expandDialogProps, setExpandDialogProps] = useState({})
+
+ const onExpandDialogClicked = (value, inputParam) => {
+ const dialogProp = {
+ value,
+ inputParam,
+ disabled,
+ confirmButtonName: 'Save',
+ cancelButtonName: 'Cancel'
+ }
+ setExpandDialogProps(dialogProp)
+ setShowExpandDialog(true)
+ }
+
+ const onExpandDialogSave = (newValue, inputParamName) => {
+ setShowExpandDialog(false)
+ data[inputParamName] = newValue
+ }
+
+ return (
+
+ {inputParam && (
+ <>
+
+
+
+ {inputParam.label}
+ {!inputParam.optional && *}
+ {inputParam.description && }
+
+
+ {inputParam.type === 'string' && inputParam.rows && (
+
onExpandDialogClicked(data[inputParam.name] ?? inputParam.default ?? '', inputParam)}
+ >
+
+
+ )}
+
+ {inputParam.warning && (
+
+
+ {inputParam.warning}
+
+ )}
+
+ {inputParam.type === 'boolean' && (
+ (data[inputParam.name] = newValue)}
+ value={data[inputParam.name] ?? inputParam.default ?? false}
+ />
+ )}
+ {(inputParam.type === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && (
+ (data[inputParam.name] = newValue)}
+ value={data[inputParam.name] ?? inputParam.default ?? ''}
+ showDialog={showExpandDialog}
+ dialogProps={expandDialogProps}
+ onDialogCancel={() => setShowExpandDialog(false)}
+ onDialogConfirm={(newValue, inputParamName) => onExpandDialogSave(newValue, inputParamName)}
+ />
+ )}
+ {inputParam.type === 'json' && (
+ (data[inputParam.name] = newValue)}
+ value={data[inputParam.name] ?? inputParam.default ?? ''}
+ isDarkMode={customization.isDarkMode}
+ />
+ )}
+ {inputParam.type === 'options' && (
+ (data[inputParam.name] = newValue)}
+ value={data[inputParam.name] ?? inputParam.default ?? 'choose an option'}
+ />
+ )}
+
+ >
+ )}
+
+ )
+}
+
+CredentialInputHandler.propTypes = {
+ inputAnchor: PropTypes.object,
+ inputParam: PropTypes.object,
+ data: PropTypes.object,
+ disabled: PropTypes.bool
+}
+
+export default CredentialInputHandler
diff --git a/packages/ui/src/views/credentials/CredentialListDialog.js b/packages/ui/src/views/credentials/CredentialListDialog.js
new file mode 100644
index 00000000..e0a3e08d
--- /dev/null
+++ b/packages/ui/src/views/credentials/CredentialListDialog.js
@@ -0,0 +1,179 @@
+import { useState, useEffect } from 'react'
+import { createPortal } from 'react-dom'
+import { useSelector, useDispatch } from 'react-redux'
+import PropTypes from 'prop-types'
+import {
+ List,
+ ListItemButton,
+ ListItem,
+ ListItemAvatar,
+ ListItemText,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+ Box,
+ OutlinedInput,
+ InputAdornment
+} from '@mui/material'
+import { useTheme } from '@mui/material/styles'
+import { IconSearch, IconX } from '@tabler/icons'
+
+// const
+import { baseURL } from 'store/constant'
+import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
+
+const CredentialListDialog = ({ show, dialogProps, onCancel, onCredentialSelected }) => {
+ const portalElement = document.getElementById('portal')
+ const customization = useSelector((state) => state.customization)
+ const dispatch = useDispatch()
+ const theme = useTheme()
+ const [searchValue, setSearchValue] = useState('')
+ const [componentsCredentials, setComponentsCredentials] = useState([])
+
+ const filterSearch = (value) => {
+ setSearchValue(value)
+ setTimeout(() => {
+ if (value) {
+ const searchData = dialogProps.componentsCredentials.filter((crd) => crd.name.toLowerCase().includes(value.toLowerCase()))
+ setComponentsCredentials(searchData)
+ } else if (value === '') {
+ setComponentsCredentials(dialogProps.componentsCredentials)
+ }
+ // scrollTop()
+ }, 500)
+ }
+
+ useEffect(() => {
+ if (dialogProps.componentsCredentials) {
+ setComponentsCredentials(dialogProps.componentsCredentials)
+ }
+ }, [dialogProps])
+
+ useEffect(() => {
+ if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
+ else dispatch({ type: HIDE_CANVAS_DIALOG })
+ return () => dispatch({ type: HIDE_CANVAS_DIALOG })
+ }, [show, dispatch])
+
+ const component = show ? (
+
+
+ {dialogProps.title}
+
+ filterSearch(e.target.value)}
+ placeholder='Search credential'
+ startAdornment={
+
+
+
+ }
+ endAdornment={
+
+ filterSearch('')}
+ style={{
+ cursor: 'pointer'
+ }}
+ />
+
+ }
+ aria-describedby='search-helper-text'
+ inputProps={{
+ 'aria-label': 'weight'
+ }}
+ />
+
+
+
+
+ {[...componentsCredentials].map((componentCredential) => (
+
+
onCredentialSelected(componentCredential)}
+ sx={{ p: 0, borderRadius: `${customization.borderRadius}px` }}
+ >
+
+
+
+

+
+
+
+
+
+
+ ))}
+
+
+
+ ) : null
+
+ return createPortal(component, portalElement)
+}
+
+CredentialListDialog.propTypes = {
+ show: PropTypes.bool,
+ dialogProps: PropTypes.object,
+ onCancel: PropTypes.func,
+ onCredentialSelected: PropTypes.func
+}
+
+export default CredentialListDialog
diff --git a/packages/ui/src/views/credentials/index.js b/packages/ui/src/views/credentials/index.js
new file mode 100644
index 00000000..9db990a7
--- /dev/null
+++ b/packages/ui/src/views/credentials/index.js
@@ -0,0 +1,276 @@
+import { useEffect, useState } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction } from 'store/actions'
+import moment from 'moment'
+
+// material-ui
+import { Button, Box, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, IconButton } from '@mui/material'
+import { useTheme } from '@mui/material/styles'
+
+// project imports
+import MainCard from 'ui-component/cards/MainCard'
+import { StyledButton } from 'ui-component/button/StyledButton'
+import CredentialListDialog from './CredentialListDialog'
+import ConfirmDialog from 'ui-component/dialog/ConfirmDialog'
+import AddEditCredentialDialog from './AddEditCredentialDialog'
+
+// API
+import credentialsApi from 'api/credentials'
+
+// Hooks
+import useApi from 'hooks/useApi'
+import useConfirm from 'hooks/useConfirm'
+
+// utils
+import useNotifier from 'utils/useNotifier'
+
+// Icons
+import { IconTrash, IconEdit, IconX, IconPlus } from '@tabler/icons'
+import CredentialEmptySVG from 'assets/images/credential_empty.svg'
+
+// const
+import { baseURL } from 'store/constant'
+import { SET_COMPONENT_CREDENTIALS } from 'store/actions'
+
+// ==============================|| Credentials ||============================== //
+
+const Credentials = () => {
+ const theme = useTheme()
+ const customization = useSelector((state) => state.customization)
+
+ const dispatch = useDispatch()
+ useNotifier()
+
+ const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
+ const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
+
+ const [showCredentialListDialog, setShowCredentialListDialog] = useState(false)
+ const [credentialListDialogProps, setCredentialListDialogProps] = useState({})
+ const [showSpecificCredentialDialog, setShowSpecificCredentialDialog] = useState(false)
+ const [specificCredentialDialogProps, setSpecificCredentialDialogProps] = useState({})
+ const [credentials, setCredentials] = useState([])
+ const [componentsCredentials, setComponentsCredentials] = useState([])
+
+ const { confirm } = useConfirm()
+
+ const getAllCredentialsApi = useApi(credentialsApi.getAllCredentials)
+ const getAllComponentsCredentialsApi = useApi(credentialsApi.getAllComponentsCredentials)
+
+ const listCredential = () => {
+ const dialogProp = {
+ title: 'Add New Credential',
+ componentsCredentials
+ }
+ setCredentialListDialogProps(dialogProp)
+ setShowCredentialListDialog(true)
+ }
+
+ const addNew = (credentialComponent) => {
+ const dialogProp = {
+ type: 'ADD',
+ cancelButtonName: 'Cancel',
+ confirmButtonName: 'Add',
+ credentialComponent
+ }
+ setSpecificCredentialDialogProps(dialogProp)
+ setShowSpecificCredentialDialog(true)
+ }
+
+ const edit = (credential) => {
+ const dialogProp = {
+ type: 'EDIT',
+ cancelButtonName: 'Cancel',
+ confirmButtonName: 'Save',
+ data: credential
+ }
+ setSpecificCredentialDialogProps(dialogProp)
+ setShowSpecificCredentialDialog(true)
+ }
+
+ const deleteCredential = async (credential) => {
+ const confirmPayload = {
+ title: `Delete`,
+ description: `Delete credential ${credential.name}?`,
+ confirmButtonName: 'Delete',
+ cancelButtonName: 'Cancel'
+ }
+ const isConfirmed = await confirm(confirmPayload)
+
+ if (isConfirmed) {
+ try {
+ const deleteResp = await credentialsApi.deleteCredential(credential.id)
+ if (deleteResp.data) {
+ enqueueSnackbar({
+ message: 'Credential deleted',
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'success',
+ action: (key) => (
+
+ )
+ }
+ })
+ onConfirm()
+ }
+ } catch (error) {
+ const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
+ enqueueSnackbar({
+ message: `Failed to delete Credential: ${errorData}`,
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'error',
+ persist: true,
+ action: (key) => (
+
+ )
+ }
+ })
+ onCancel()
+ }
+ }
+ }
+
+ const onCredentialSelected = (credentialComponent) => {
+ setShowCredentialListDialog(false)
+ addNew(credentialComponent)
+ }
+
+ const onConfirm = () => {
+ setShowCredentialListDialog(false)
+ setShowSpecificCredentialDialog(false)
+ getAllCredentialsApi.request()
+ }
+
+ useEffect(() => {
+ getAllCredentialsApi.request()
+ getAllComponentsCredentialsApi.request()
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [])
+
+ useEffect(() => {
+ if (getAllCredentialsApi.data) {
+ setCredentials(getAllCredentialsApi.data)
+ }
+ }, [getAllCredentialsApi.data])
+
+ useEffect(() => {
+ if (getAllComponentsCredentialsApi.data) {
+ setComponentsCredentials(getAllComponentsCredentialsApi.data)
+ dispatch({ type: SET_COMPONENT_CREDENTIALS, componentsCredentials: getAllComponentsCredentialsApi.data })
+ }
+ }, [getAllComponentsCredentialsApi.data, dispatch])
+
+ return (
+ <>
+
+
+ Credentials
+
+
+ }
+ >
+ Add Credential
+
+
+ {credentials.length <= 0 && (
+
+
+
+
+ No Credentials Yet
+
+ )}
+ {credentials.length > 0 && (
+
+
+
+
+ Name
+ Last Updated
+ Created
+
+
+
+
+
+ {credentials.map((credential, index) => (
+
+
+
+
+

+
+ {credential.name}
+
+
+ {moment(credential.updatedDate).format('DD-MMM-YY')}
+ {moment(credential.createdDate).format('DD-MMM-YY')}
+
+ edit(credential)}>
+
+
+
+
+ deleteCredential(credential)}>
+
+
+
+
+ ))}
+
+
+
+ )}
+
+ setShowCredentialListDialog(false)}
+ onCredentialSelected={onCredentialSelected}
+ >
+ setShowSpecificCredentialDialog(false)}
+ onConfirm={onConfirm}
+ >
+
+ >
+ )
+}
+
+export default Credentials
diff --git a/packages/ui/src/views/marketplaces/index.js b/packages/ui/src/views/marketplaces/index.js
index ba9eb3d6..a7836161 100644
--- a/packages/ui/src/views/marketplaces/index.js
+++ b/packages/ui/src/views/marketplaces/index.js
@@ -1,16 +1,19 @@
import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useSelector } from 'react-redux'
+import PropTypes from 'prop-types'
// material-ui
-import { Grid, Box, Stack } from '@mui/material'
+import { Grid, Box, Stack, Tabs, Tab } from '@mui/material'
import { useTheme } from '@mui/material/styles'
+import { IconHierarchy, IconTool } from '@tabler/icons'
// project imports
import MainCard from 'ui-component/cards/MainCard'
import ItemCard from 'ui-component/cards/ItemCard'
import { gridSpacing } from 'store/constant'
import WorkflowEmptySVG from 'assets/images/workflow_empty.svg'
+import ToolDialog from 'views/tools/ToolDialog'
// API
import marketplacesApi from 'api/marketplaces'
@@ -21,6 +24,27 @@ import useApi from 'hooks/useApi'
// const
import { baseURL } from 'store/constant'
+function TabPanel(props) {
+ const { children, value, index, ...other } = props
+ return (
+
+ {value === index && {children}}
+
+ )
+}
+
+TabPanel.propTypes = {
+ children: PropTypes.node,
+ index: PropTypes.number.isRequired,
+ value: PropTypes.number.isRequired
+}
+
// ==============================|| Marketplace ||============================== //
const Marketplace = () => {
@@ -29,29 +53,66 @@ const Marketplace = () => {
const theme = useTheme()
const customization = useSelector((state) => state.customization)
- const [isLoading, setLoading] = useState(true)
+ const [isChatflowsLoading, setChatflowsLoading] = useState(true)
+ const [isToolsLoading, setToolsLoading] = useState(true)
const [images, setImages] = useState({})
+ const tabItems = ['Chatflows', 'Tools']
+ const [value, setValue] = useState(0)
+ const [showToolDialog, setShowToolDialog] = useState(false)
+ const [toolDialogProps, setToolDialogProps] = useState({})
- const getAllMarketplacesApi = useApi(marketplacesApi.getAllMarketplaces)
+ const getAllChatflowsMarketplacesApi = useApi(marketplacesApi.getAllChatflowsMarketplaces)
+ const getAllToolsMarketplacesApi = useApi(marketplacesApi.getAllToolsMarketplaces)
+
+ const onUseTemplate = (selectedTool) => {
+ const dialogProp = {
+ title: 'Add New Tool',
+ type: 'IMPORT',
+ cancelButtonName: 'Cancel',
+ confirmButtonName: 'Add',
+ data: selectedTool
+ }
+ setToolDialogProps(dialogProp)
+ setShowToolDialog(true)
+ }
+
+ const goToTool = (selectedTool) => {
+ const dialogProp = {
+ title: selectedTool.templateName,
+ type: 'TEMPLATE',
+ data: selectedTool
+ }
+ setToolDialogProps(dialogProp)
+ setShowToolDialog(true)
+ }
const goToCanvas = (selectedChatflow) => {
navigate(`/marketplace/${selectedChatflow.id}`, { state: selectedChatflow })
}
+ const handleChange = (event, newValue) => {
+ setValue(newValue)
+ }
+
useEffect(() => {
- getAllMarketplacesApi.request()
+ getAllChatflowsMarketplacesApi.request()
+ getAllToolsMarketplacesApi.request()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
- setLoading(getAllMarketplacesApi.loading)
- }, [getAllMarketplacesApi.loading])
+ setChatflowsLoading(getAllChatflowsMarketplacesApi.loading)
+ }, [getAllChatflowsMarketplacesApi.loading])
useEffect(() => {
- if (getAllMarketplacesApi.data) {
+ setToolsLoading(getAllToolsMarketplacesApi.loading)
+ }, [getAllToolsMarketplacesApi.loading])
+
+ useEffect(() => {
+ if (getAllChatflowsMarketplacesApi.data) {
try {
- const chatflows = getAllMarketplacesApi.data
+ const chatflows = getAllChatflowsMarketplacesApi.data
const images = {}
for (let i = 0; i < chatflows.length; i += 1) {
const flowDataStr = chatflows[i].flowData
@@ -70,31 +131,83 @@ const Marketplace = () => {
console.error(e)
}
}
- }, [getAllMarketplacesApi.data])
+ }, [getAllChatflowsMarketplacesApi.data])
return (
-
-
- Marketplace
-
-
- {!isLoading &&
- getAllMarketplacesApi.data &&
- getAllMarketplacesApi.data.map((data, index) => (
-
- goToCanvas(data)} data={data} images={images[data.id]} />
-
- ))}
-
- {!isLoading && (!getAllMarketplacesApi.data || getAllMarketplacesApi.data.length === 0) && (
-
-
-
-
- No Marketplace Yet
+ <>
+
+
+ Marketplace
- )}
-
+
+ {tabItems.map((item, index) => (
+ : }
+ iconPosition='start'
+ label={{item}}
+ />
+ ))}
+
+ {tabItems.map((item, index) => (
+
+ {item === 'Chatflows' && (
+
+ {!isChatflowsLoading &&
+ getAllChatflowsMarketplacesApi.data &&
+ getAllChatflowsMarketplacesApi.data.map((data, index) => (
+
+ goToCanvas(data)} data={data} images={images[data.id]} />
+
+ ))}
+
+ )}
+ {item === 'Tools' && (
+
+ {!isToolsLoading &&
+ getAllToolsMarketplacesApi.data &&
+ getAllToolsMarketplacesApi.data.map((data, index) => (
+
+ goToTool(data)} />
+
+ ))}
+
+ )}
+
+ ))}
+ {!isChatflowsLoading && (!getAllChatflowsMarketplacesApi.data || getAllChatflowsMarketplacesApi.data.length === 0) && (
+
+
+
+
+ No Marketplace Yet
+
+ )}
+ {!isToolsLoading && (!getAllToolsMarketplacesApi.data || getAllToolsMarketplacesApi.data.length === 0) && (
+
+
+
+
+ No Marketplace Yet
+
+ )}
+
+ setShowToolDialog(false)}
+ onConfirm={() => setShowToolDialog(false)}
+ onUseTemplate={(tool) => onUseTemplate(tool)}
+ >
+ >
)
}
diff --git a/packages/ui/src/views/tools/ToolDialog.js b/packages/ui/src/views/tools/ToolDialog.js
index bd5af355..5e286789 100644
--- a/packages/ui/src/views/tools/ToolDialog.js
+++ b/packages/ui/src/views/tools/ToolDialog.js
@@ -17,7 +17,7 @@ import { LightCodeEditor } from 'ui-component/editor/LightCodeEditor'
import { useTheme } from '@mui/material/styles'
// Icons
-import { IconX } from '@tabler/icons'
+import { IconX, IconFileExport } from '@tabler/icons'
// API
import toolsApi from 'api/tools'
@@ -29,6 +29,7 @@ import useApi from 'hooks/useApi'
// utils
import useNotifier from 'utils/useNotifier'
import { generateRandomGradient } from 'utils/genericHelper'
+import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
const exampleAPIFunc = `/*
* You can use any libraries imported in Flowise
@@ -53,7 +54,7 @@ try {
return '';
}`
-const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
+const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) => {
const portalElement = document.getElementById('portal')
const theme = useTheme()
@@ -73,6 +74,7 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
const [toolId, setToolId] = useState('')
const [toolName, setToolName] = useState('')
const [toolDesc, setToolDesc] = useState('')
+ const [toolIcon, setToolIcon] = useState('')
const [toolSchema, setToolSchema] = useState([])
const [toolFunc, setToolFunc] = useState('')
@@ -154,6 +156,12 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
}
}
+ useEffect(() => {
+ if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
+ else dispatch({ type: HIDE_CANVAS_DIALOG })
+ return () => dispatch({ type: HIDE_CANVAS_DIALOG })
+ }, [show, dispatch])
+
useEffect(() => {
if (getSpecificToolApi.data) {
setToolId(getSpecificToolApi.data.id)
@@ -167,18 +175,39 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
useEffect(() => {
if (dialogProps.type === 'EDIT' && dialogProps.data) {
+ // When tool dialog is opened from Tools dashboard
setToolId(dialogProps.data.id)
setToolName(dialogProps.data.name)
setToolDesc(dialogProps.data.description)
+ setToolIcon(dialogProps.data.iconSrc)
setToolSchema(formatSchema(dialogProps.data.schema))
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
else setToolFunc('')
} else if (dialogProps.type === 'EDIT' && dialogProps.toolId) {
+ // When tool dialog is opened from CustomTool node in canvas
getSpecificToolApi.request(dialogProps.toolId)
+ } else if (dialogProps.type === 'IMPORT' && dialogProps.data) {
+ // When tool dialog is to import existing tool
+ setToolName(dialogProps.data.name)
+ setToolDesc(dialogProps.data.description)
+ setToolIcon(dialogProps.data.iconSrc)
+ setToolSchema(formatSchema(dialogProps.data.schema))
+ if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
+ else setToolFunc('')
+ } else if (dialogProps.type === 'TEMPLATE' && dialogProps.data) {
+ // When tool dialog is a template
+ setToolName(dialogProps.data.name)
+ setToolDesc(dialogProps.data.description)
+ setToolIcon(dialogProps.data.iconSrc)
+ setToolSchema(formatSchema(dialogProps.data.schema))
+ if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
+ else setToolFunc('')
} else if (dialogProps.type === 'ADD') {
+ // When tool dialog is to add a new tool
setToolId('')
setToolName('')
setToolDesc('')
+ setToolIcon('')
setToolSchema([])
setToolFunc('')
}
@@ -186,6 +215,47 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dialogProps])
+ const useToolTemplate = () => {
+ onUseTemplate(dialogProps.data)
+ }
+
+ const exportTool = async () => {
+ try {
+ const toolResp = await toolsApi.getSpecificTool(toolId)
+ if (toolResp.data) {
+ const toolData = toolResp.data
+ delete toolData.id
+ delete toolData.createdDate
+ delete toolData.updatedDate
+ let dataStr = JSON.stringify(toolData)
+ let dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr)
+
+ let exportFileDefaultName = `${toolName}-CustomTool.json`
+
+ let linkElement = document.createElement('a')
+ linkElement.setAttribute('href', dataUri)
+ linkElement.setAttribute('download', exportFileDefaultName)
+ linkElement.click()
+ }
+ } catch (error) {
+ const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
+ enqueueSnackbar({
+ message: `Failed to export Tool: ${errorData}`,
+ options: {
+ key: new Date().getTime() + Math.random(),
+ variant: 'error',
+ persist: true,
+ action: (key) => (
+
+ )
+ }
+ })
+ onCancel()
+ }
+ }
+
const addNewTool = async () => {
try {
const obj = {
@@ -193,7 +263,8 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
description: toolDesc,
color: generateRandomGradient(),
schema: JSON.stringify(toolSchema),
- func: toolFunc
+ func: toolFunc,
+ iconSrc: toolIcon
}
const createResp = await toolsApi.createNewTool(obj)
if (createResp.data) {
@@ -236,7 +307,8 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
name: toolName,
description: toolDesc,
schema: JSON.stringify(toolSchema),
- func: toolFunc
+ func: toolFunc,
+ iconSrc: toolIcon
})
if (saveResp.data) {
enqueueSnackbar({
@@ -330,7 +402,15 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
aria-describedby='alert-dialog-description'
>
- {dialogProps.title}
+
+ {dialogProps.title}
+
+ {dialogProps.type === 'EDIT' && (
+
+ )}
+
@@ -338,12 +418,17 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
Tool Name
*
+
{
Tool description
*
+
{
onChange={(e) => setToolDesc(e.target.value)}
/>
+
+
+ Tool Icon Src
+
+ setToolIcon(e.target.value)}
+ />
+
@@ -376,7 +481,13 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
-
+
@@ -388,12 +499,15 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
/>
-
+ {dialogProps.type !== 'TEMPLATE' && (
+
+ )}
{customization.isDarkMode ? (
setToolFunc(code)}
style={{
fontSize: '0.875rem',
@@ -405,6 +519,7 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
) : (
setToolFunc(code)}
style={{
fontSize: '0.875rem',
@@ -423,13 +538,20 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
Delete
)}
- (dialogProps.type === 'ADD' ? addNewTool() : saveTool())}
- >
- {dialogProps.confirmButtonName}
-
+ {dialogProps.type === 'TEMPLATE' && (
+
+ Use Template
+
+ )}
+ {dialogProps.type !== 'TEMPLATE' && (
+ (dialogProps.type === 'ADD' || dialogProps.type === 'IMPORT' ? addNewTool() : saveTool())}
+ >
+ {dialogProps.confirmButtonName}
+
+ )}
@@ -441,6 +563,7 @@ const ToolDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
ToolDialog.propTypes = {
show: PropTypes.bool,
dialogProps: PropTypes.object,
+ onUseTemplate: PropTypes.func,
onCancel: PropTypes.func,
onConfirm: PropTypes.func
}
diff --git a/packages/ui/src/views/tools/index.js b/packages/ui/src/views/tools/index.js
index efe9e69d..c97ec660 100644
--- a/packages/ui/src/views/tools/index.js
+++ b/packages/ui/src/views/tools/index.js
@@ -1,8 +1,8 @@
-import { useEffect, useState } from 'react'
+import { useEffect, useState, useRef } from 'react'
import { useSelector } from 'react-redux'
// material-ui
-import { Grid, Box, Stack } from '@mui/material'
+import { Grid, Box, Stack, Button } from '@mui/material'
import { useTheme } from '@mui/material/styles'
// project imports
@@ -20,7 +20,7 @@ import toolsApi from 'api/tools'
import useApi from 'hooks/useApi'
// icons
-import { IconPlus } from '@tabler/icons'
+import { IconPlus, IconFileImport } from '@tabler/icons'
// ==============================|| CHATFLOWS ||============================== //
@@ -33,6 +33,40 @@ const Tools = () => {
const [showDialog, setShowDialog] = useState(false)
const [dialogProps, setDialogProps] = useState({})
+ const inputRef = useRef(null)
+
+ const onUploadFile = (file) => {
+ try {
+ const dialogProp = {
+ title: 'Add New Tool',
+ type: 'IMPORT',
+ cancelButtonName: 'Cancel',
+ confirmButtonName: 'Save',
+ data: JSON.parse(file)
+ }
+ setDialogProps(dialogProp)
+ setShowDialog(true)
+ } catch (e) {
+ console.error(e)
+ }
+ }
+
+ const handleFileUpload = (e) => {
+ if (!e.target.files) return
+
+ const file = e.target.files[0]
+
+ const reader = new FileReader()
+ reader.onload = (evt) => {
+ if (!evt?.target?.result) {
+ return
+ }
+ const { result } = evt.target
+ onUploadFile(result)
+ }
+ reader.readAsText(file)
+ }
+
const addNew = () => {
const dialogProp = {
title: 'Add New Tool',
@@ -75,8 +109,17 @@ const Tools = () => {
+
+ handleFileUpload(e)} />
}>
- Create New
+ Create
@@ -86,7 +129,7 @@ const Tools = () => {
getAllToolsApi.data &&
getAllToolsApi.data.map((data, index) => (
- edit(data)} />
+ edit(data)} />
))}