Stevross commited on
Commit
1d816ac
·
1 Parent(s): 5b5996f

Upload 309 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. CODE_OF_CONDUCT.md +74 -0
  3. CONTRIBUTING.md +127 -0
  4. LICENSE.md +21 -0
  5. README.md +120 -10
  6. assets/Demo.png +0 -0
  7. assets/FloWiseAI.png +0 -0
  8. assets/FloWiseAI_black.png +0 -0
  9. assets/FloWiseAI_dark.png +0 -0
  10. assets/FloWiseAI_primary.png +0 -0
  11. babel.config.js +13 -0
  12. docker/.env.example +1 -0
  13. docker/Dockerfile +13 -0
  14. docker/docker-compose.yml +13 -0
  15. images/flowise.gif +3 -0
  16. package.json +56 -0
  17. packages/components/.env.example +1 -0
  18. packages/components/README.md +25 -0
  19. packages/components/gulpfile.ts +9 -0
  20. packages/components/nodes/agents/AutoGPT/AutoGPT.ts +98 -0
  21. packages/components/nodes/agents/AutoGPT/autogpt.png +0 -0
  22. packages/components/nodes/agents/BabyAGI/BabyAGI.ts +62 -0
  23. packages/components/nodes/agents/BabyAGI/babyagi.jpg +0 -0
  24. packages/components/nodes/agents/BabyAGI/core.ts +266 -0
  25. packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts +115 -0
  26. packages/components/nodes/agents/ConversationalAgent/agent.svg +9 -0
  27. packages/components/nodes/agents/MRKLAgentChat/MRKLAgentChat.ts +59 -0
  28. packages/components/nodes/agents/MRKLAgentChat/agent.svg +9 -0
  29. packages/components/nodes/agents/MRKLAgentLLM/MRKLAgentLLM.ts +60 -0
  30. packages/components/nodes/agents/MRKLAgentLLM/agent.svg +9 -0
  31. packages/components/nodes/chains/ConversationChain/ConversationChain.ts +97 -0
  32. packages/components/nodes/chains/ConversationChain/chain.svg +6 -0
  33. packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts +99 -0
  34. packages/components/nodes/chains/ConversationalRetrievalQAChain/chain.svg +6 -0
  35. packages/components/nodes/chains/LLMChain/LLMChain.ts +133 -0
  36. packages/components/nodes/chains/LLMChain/chain.svg +6 -0
  37. packages/components/nodes/chains/RetrievalQAChain/RetrievalQAChain.ts +57 -0
  38. packages/components/nodes/chains/RetrievalQAChain/chain.svg +6 -0
  39. packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts +93 -0
  40. packages/components/nodes/chains/SqlDatabaseChain/sqlchain.svg +7 -0
  41. packages/components/nodes/chains/VectorDBQAChain/VectorDBQAChain.ts +57 -0
  42. packages/components/nodes/chains/VectorDBQAChain/chain.svg +6 -0
  43. packages/components/nodes/chatmodels/AzureChatOpenAI/Azure.svg +5 -0
  44. packages/components/nodes/chatmodels/AzureChatOpenAI/AzureChatOpenAI.ts +144 -0
  45. packages/components/nodes/chatmodels/ChatAnthropic/ChatAnthropic.ts +136 -0
  46. packages/components/nodes/chatmodels/ChatAnthropic/chatAnthropic.png +0 -0
  47. packages/components/nodes/chatmodels/ChatLocalAI/ChatLocalAI.ts +92 -0
  48. packages/components/nodes/chatmodels/ChatLocalAI/localai.png +0 -0
  49. packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts +130 -0
  50. packages/components/nodes/chatmodels/ChatOpenAI/openai.png +0 -0
.gitattributes CHANGED
@@ -32,3 +32,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ images/flowise.gif filter=lfs diff=lfs merge=lfs -text
CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ - Using welcoming and inclusive language
18
+ - Being respectful of differing viewpoints and experiences
19
+ - Gracefully accepting constructive criticism
20
+ - Focusing on what is best for the community
21
+ - Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ - The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ - Trolling, insulting/derogatory comments, and personal or political attacks
28
+ - Public or private harassment
29
+ - Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ - Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at hello@flowiseai.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
CONTRIBUTING.md ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- markdownlint-disable MD030 -->
2
+
3
+ # Contributing to Flowise
4
+
5
+ We appreciate any form of contributions.
6
+
7
+ ## ⭐ Star
8
+
9
+ Star and share the [Github Repo](https://github.com/FlowiseAI/Flowise).
10
+
11
+ ## 🙋 Q&A
12
+
13
+ Search up for any questions in [Q&A section](https://github.com/FlowiseAI/Flowise/discussions/categories/q-a), if you can't find one, don't hesitate to create one. It might helps others that have similar question.
14
+
15
+ ## 🙌 Share Chatflow
16
+
17
+ Yes! Sharing how you use Flowise is a way of contribution. Export your chatflow as JSON, attach a screenshot and share it in [Show and Tell section](https://github.com/FlowiseAI/Flowise/discussions/categories/show-and-tell).
18
+
19
+ ## 💡 Ideas
20
+
21
+ Ideas are welcome such as new feature, apps integration, and blockchain networks. Submit in [Ideas section](https://github.com/FlowiseAI/Flowise/discussions/categories/ideas).
22
+
23
+ ## 🐞 Report Bugs
24
+
25
+ Found an issue? [Report it](https://github.com/FlowiseAI/Flowise/issues/new/choose).
26
+
27
+ ## 👨‍💻 Contribute to Code
28
+
29
+ Not sure what to contribute? Some ideas:
30
+
31
+ - Create new components from Langchain
32
+ - Update existing components such as extending functionality, fixing bugs
33
+ - Add new chatflow ideas
34
+
35
+ ### Developers
36
+
37
+ Flowise has 3 different modules in a single mono repository.
38
+
39
+ - `server`: Node backend to serve API logics
40
+ - `ui`: React frontend
41
+ - `components`: Langchain components
42
+
43
+ #### Prerequisite
44
+
45
+ - Install Yarn
46
+ ```bash
47
+ npm i -g yarn
48
+ ```
49
+
50
+ #### Step by step
51
+
52
+ 1. Fork the official [Flowise Github Repository](https://github.com/FlowiseAI/Flowise).
53
+
54
+ 2. Clone your forked repository.
55
+
56
+ 3. Create a new branch, see [guide](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository). Naming conventions:
57
+
58
+ - For feature branch: `feature/<Your New Feature>`
59
+ - For bug fix branch: `bugfix/<Your New Bugfix>`.
60
+
61
+ 4. Switch to the newly created branch.
62
+
63
+ 5. Go into repository folder
64
+
65
+ ```bash
66
+ cd Flowise
67
+ ```
68
+
69
+ 6. Install all dependencies of all modules:
70
+
71
+ ```bash
72
+ yarn install
73
+ ```
74
+
75
+ 7. Build all the code:
76
+
77
+ ```bash
78
+ yarn build
79
+ ```
80
+
81
+ 8. Start the app on [http://localhost:3000](http://localhost:3000)
82
+
83
+ ```bash
84
+ yarn start
85
+ ```
86
+
87
+ 9. For development, run
88
+
89
+ ```bash
90
+ yarn dev
91
+ ```
92
+
93
+ Any changes made in `packages/ui` or `packages/server` will be reflected on [http://localhost:8080](http://localhost:8080)
94
+
95
+ For changes made in `packages/components`, run `yarn build` again to pickup the changes.
96
+
97
+ 10. After making all the changes, run
98
+
99
+ ```bash
100
+ yarn build
101
+ ```
102
+
103
+ and
104
+
105
+ ```bash
106
+ yarn start
107
+ ```
108
+
109
+ to make sure everything works fine in production.
110
+
111
+ 11. Commit code and submit Pull Request from forked branch pointing to [Flowise master](https://github.com/FlowiseAI/Flowise/tree/master).
112
+
113
+ ## 📖 Contribute to Docs
114
+
115
+ In-Progress
116
+
117
+ ## 🏷️ Pull Request process
118
+
119
+ A member of the FlowiseAI team will automatically be notified/assigned when you open a pull request. You can also reach out to us on [Discord](https://discord.gg/jbaHfsRVBW).
120
+
121
+ ## 📃 Contributor License Agreement
122
+
123
+ Before we can merge your contribution you have to sign our [Contributor License Agreement (CLA)](https://cla-assistant.io/FlowiseAI/Flowise). The CLA contains the terms and conditions under which the contribution is submitted. You need to do this only once for your first pull request. Keep in mind that without a signed CLA we cannot merge your contribution.
124
+
125
+ ## 📜 Code of Conduct
126
+
127
+ This project and everyone participating in it are governed by the Code of Conduct which can be found in the [file](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to hello@flowiseai.com.
LICENSE.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License
2
+
3
+ Copyright (c) 2023 FlowiseAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
README.md CHANGED
@@ -1,10 +1,120 @@
1
- ---
2
- title: Langflowise
3
- emoji: 🏆
4
- colorFrom: purple
5
- colorTo: gray
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- markdownlint-disable MD030 -->
2
+
3
+ # Flowise - LangchainJS UI
4
+
5
+ <a href="https://github.com/FlowiseAI/Flowise">
6
+ <img width="100%" src="https://github.com/FlowiseAI/Flowise/blob/main/images/flowise.gif?raw=true"></a>
7
+
8
+ Drag & drop UI to build your customized LLM flow using [LangchainJS](https://github.com/hwchase17/langchainjs)
9
+
10
+ ## ⚡Quick Start
11
+
12
+ 1. Install Flowise
13
+ ```bash
14
+ npm install -g flowise
15
+ ```
16
+ 2. Start Flowise
17
+
18
+ ```bash
19
+ npx flowise start
20
+ ```
21
+
22
+ 3. Open [http://localhost:3000](http://localhost:3000)
23
+
24
+ ## 🐳 Docker
25
+
26
+ 1. Go to `docker` folder at the root of the project
27
+ 2. Create `.env` file and specify the `PORT` (refer to `.env.example`)
28
+ 3. `docker-compose up -d`
29
+ 4. Open [http://localhost:3000](http://localhost:3000)
30
+ 5. You can bring the containers down by `docker-compose stop`
31
+
32
+ ## 👨‍💻 Developers
33
+
34
+ Flowise has 3 different modules in a single mono repository.
35
+
36
+ - `server`: Node backend to serve API logics
37
+ - `ui`: React frontend
38
+ - `components`: Langchain components
39
+
40
+ ### Prerequisite
41
+
42
+ - Install Yarn
43
+ ```bash
44
+ npm i -g yarn
45
+ ```
46
+
47
+ ### Setup
48
+
49
+ 1. Clone the repository
50
+
51
+ ```bash
52
+ git clone https://github.com/FlowiseAI/Flowise.git
53
+ ```
54
+
55
+ 2. Go into repository folder
56
+
57
+ ```bash
58
+ cd Flowise
59
+ ```
60
+
61
+ 3. Install all dependencies of all modules:
62
+
63
+ ```bash
64
+ yarn install
65
+ ```
66
+
67
+ 4. Build all the code:
68
+
69
+ ```bash
70
+ yarn build
71
+ ```
72
+
73
+ 5. Start the app:
74
+
75
+ ```bash
76
+ yarn start
77
+ ```
78
+
79
+ You can now access the app on [http://localhost:3000](http://localhost:3000)
80
+
81
+ 6. For development build:
82
+
83
+ ```bash
84
+ yarn dev
85
+ ```
86
+
87
+ Any code changes will reload the app automatically on [http://localhost:8080](http://localhost:8080)
88
+
89
+ ## 🔒 Authentication
90
+
91
+ To enable app level authentication, add `USERNAME` and `PASSWORD` to the `.env` file in `packages/server`:
92
+
93
+ ```
94
+ USERNAME=user
95
+ PASSWORD=1234
96
+ ```
97
+
98
+ ## 📖 Documentation
99
+
100
+ Coming soon
101
+
102
+ ## 💻 Cloud Hosted
103
+
104
+ Coming soon
105
+
106
+ ## 🌐 Self Host
107
+
108
+ Coming soon
109
+
110
+ ## 🙋 Support
111
+
112
+ Feel free to ask any questions, raise problems, and request new features in [discussion](https://github.com/FlowiseAI/Flowise/discussions)
113
+
114
+ ## 🙌 Contributing
115
+
116
+ See [contributing guide](CONTRIBUTING.md). Reach out to us at [Discord](https://discord.gg/jbaHfsRVBW) if you have any questions or issues.
117
+
118
+ ## 📄 License
119
+
120
+ Source code in this repository is made available under the [MIT License](LICENSE.md).
assets/Demo.png ADDED
assets/FloWiseAI.png ADDED
assets/FloWiseAI_black.png ADDED
assets/FloWiseAI_dark.png ADDED
assets/FloWiseAI_primary.png ADDED
babel.config.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ presets: [
3
+ '@babel/preset-typescript',
4
+ [
5
+ '@babel/preset-env',
6
+ {
7
+ targets: {
8
+ node: 'current'
9
+ }
10
+ }
11
+ ]
12
+ ]
13
+ }
docker/.env.example ADDED
@@ -0,0 +1 @@
 
 
1
+ PORT=3000
docker/Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-alpine
2
+
3
+ USER root
4
+
5
+ RUN apk add --no-cache git
6
+ RUN apk add --no-cache python3 py3-pip make g++
7
+
8
+ # You can install a specific version like: flowise@1.0.0
9
+ RUN npm install -g flowise
10
+
11
+ WORKDIR /data
12
+
13
+ CMD "flowise"
docker/docker-compose.yml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.1'
2
+
3
+ services:
4
+ flowise:
5
+ image: flowiseai/flowise
6
+ restart: always
7
+ environment:
8
+ - PORT=${PORT}
9
+ ports:
10
+ - '${PORT}:${PORT}'
11
+ volumes:
12
+ - ~/.flowise:/root/.flowise
13
+ command: /bin/sh -c "sleep 3; flowise start"
images/flowise.gif ADDED

Git LFS Details

  • SHA256: 9540a0d3514f0840d00ef06acd48f6468baf4f114c01809e7f5ec845a726ee8e
  • Pointer size: 132 Bytes
  • Size of remote file: 4.92 MB
package.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "flowise",
3
+ "version": "1.2.6",
4
+ "private": true,
5
+ "homepage": "https://flowiseai.com",
6
+ "workspaces": [
7
+ "packages/*",
8
+ "flowise",
9
+ "ui",
10
+ "components"
11
+ ],
12
+ "scripts": {
13
+ "build": "turbo run build",
14
+ "build-force": "turbo run build --force",
15
+ "dev": "turbo run dev --parallel",
16
+ "start": "run-script-os",
17
+ "start:windows": "cd packages/server/bin && run start",
18
+ "start:default": "cd packages/server/bin && ./run start",
19
+ "clean": "npm exec -ws -- rimraf dist build",
20
+ "format": "prettier --write \"**/*.{ts,tsx,md}\"",
21
+ "test": "turbo run test",
22
+ "lint": "eslint \"**/*.{js,jsx,ts,tsx,json,md}\"",
23
+ "lint-fix": "yarn lint --fix",
24
+ "quick": "pretty-quick --staged",
25
+ "postinstall": "husky install"
26
+ },
27
+ "lint-staged": {
28
+ "*.{js,jsx,ts,tsx,json,md}": "eslint --fix"
29
+ },
30
+ "devDependencies": {
31
+ "turbo": "1.7.4",
32
+ "@babel/preset-env": "^7.19.4",
33
+ "@babel/preset-typescript": "7.18.6",
34
+ "@types/express": "^4.17.13",
35
+ "@typescript-eslint/typescript-estree": "^5.39.0",
36
+ "eslint": "^8.24.0",
37
+ "eslint-config-prettier": "^8.3.0",
38
+ "eslint-config-react-app": "^7.0.1",
39
+ "eslint-plugin-jsx-a11y": "^6.6.1",
40
+ "eslint-plugin-markdown": "^3.0.0",
41
+ "eslint-plugin-prettier": "^3.4.0",
42
+ "eslint-plugin-react": "^7.26.1",
43
+ "eslint-plugin-react-hooks": "^4.6.0",
44
+ "eslint-plugin-unused-imports": "^2.0.0",
45
+ "husky": "^8.0.1",
46
+ "lint-staged": "^13.0.3",
47
+ "prettier": "^2.7.1",
48
+ "pretty-quick": "^3.1.3",
49
+ "rimraf": "^3.0.2",
50
+ "run-script-os": "^1.1.6",
51
+ "typescript": "^4.8.4"
52
+ },
53
+ "engines": {
54
+ "node": ">=18.15.0"
55
+ }
56
+ }
packages/components/.env.example ADDED
@@ -0,0 +1 @@
 
 
1
+ DEBUG=true
packages/components/README.md ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- markdownlint-disable MD030 -->
2
+
3
+ # Flowise Components
4
+
5
+ Apps integration for Flowise. Contain Nodes and Credentials.
6
+
7
+ ![Flowise](https://github.com/FlowiseAI/Flowise/blob/main/images/flowise.gif?raw=true)
8
+
9
+ Install:
10
+
11
+ ```bash
12
+ npm i flowise-components
13
+ ```
14
+
15
+ ## Debug
16
+
17
+ To view all the logs, create an `.env` file and add:
18
+
19
+ ```
20
+ DEBUG=true
21
+ ```
22
+
23
+ ## License
24
+
25
+ Source code in this repository is made available under the [MIT License](https://github.com/FlowiseAI/Flowise/blob/master/LICENSE.md).
packages/components/gulpfile.ts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import gulp from 'gulp'
2
+
3
+ const { src, dest } = gulp
4
+
5
+ function copyIcons() {
6
+ return src(['nodes/**/*.{jpg,png,svg}']).pipe(dest('dist/nodes'))
7
+ }
8
+
9
+ exports.default = copyIcons
packages/components/nodes/agents/AutoGPT/AutoGPT.ts ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { BaseChatModel } from 'langchain/chat_models/base'
3
+ import { AutoGPT } from 'langchain/experimental/autogpt'
4
+ import { Tool } from 'langchain/tools'
5
+ import { VectorStoreRetriever } from 'langchain/vectorstores/base'
6
+
7
+ class AutoGPT_Agents implements INode {
8
+ label: string
9
+ name: string
10
+ description: string
11
+ type: string
12
+ icon: string
13
+ category: string
14
+ baseClasses: string[]
15
+ inputs: INodeParams[]
16
+
17
+ constructor() {
18
+ this.label = 'AutoGPT'
19
+ this.name = 'autoGPT'
20
+ this.type = 'AutoGPT'
21
+ this.category = 'Agents'
22
+ this.icon = 'autogpt.png'
23
+ this.description = 'Autonomous agent with chain of thoughts for self-guided task completion'
24
+ this.baseClasses = ['AutoGPT']
25
+ this.inputs = [
26
+ {
27
+ label: 'Allowed Tools',
28
+ name: 'tools',
29
+ type: 'Tool',
30
+ list: true
31
+ },
32
+ {
33
+ label: 'Chat Model',
34
+ name: 'model',
35
+ type: 'BaseChatModel'
36
+ },
37
+ {
38
+ label: 'Vector Store Retriever',
39
+ name: 'vectorStoreRetriever',
40
+ type: 'BaseRetriever'
41
+ },
42
+ {
43
+ label: 'AutoGPT Name',
44
+ name: 'aiName',
45
+ type: 'string',
46
+ placeholder: 'Tom',
47
+ optional: true
48
+ },
49
+ {
50
+ label: 'AutoGPT Role',
51
+ name: 'aiRole',
52
+ type: 'string',
53
+ placeholder: 'Assistant',
54
+ optional: true
55
+ },
56
+ {
57
+ label: 'Maximum Loop',
58
+ name: 'maxLoop',
59
+ type: 'number',
60
+ default: 5,
61
+ optional: true
62
+ }
63
+ ]
64
+ }
65
+
66
+ async init(nodeData: INodeData): Promise<any> {
67
+ const model = nodeData.inputs?.model as BaseChatModel
68
+ const vectorStoreRetriever = nodeData.inputs?.vectorStoreRetriever as VectorStoreRetriever
69
+ let tools = nodeData.inputs?.tools as Tool[]
70
+ tools = tools.flat()
71
+ const aiName = (nodeData.inputs?.aiName as string) || 'AutoGPT'
72
+ const aiRole = (nodeData.inputs?.aiRole as string) || 'Assistant'
73
+ const maxLoop = nodeData.inputs?.maxLoop as string
74
+
75
+ const autogpt = AutoGPT.fromLLMAndTools(model, tools, {
76
+ memory: vectorStoreRetriever,
77
+ aiName,
78
+ aiRole
79
+ })
80
+
81
+ autogpt.maxIterations = parseInt(maxLoop, 10)
82
+
83
+ return autogpt
84
+ }
85
+
86
+ async run(nodeData: INodeData, input: string): Promise<string> {
87
+ const executor = nodeData.instance as AutoGPT
88
+ try {
89
+ const res = await executor.run([input])
90
+ return res || 'I have completed all my tasks.'
91
+ } catch (e) {
92
+ console.error(e)
93
+ throw new Error(e)
94
+ }
95
+ }
96
+ }
97
+
98
+ module.exports = { nodeClass: AutoGPT_Agents }
packages/components/nodes/agents/AutoGPT/autogpt.png ADDED
packages/components/nodes/agents/BabyAGI/BabyAGI.ts ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { BabyAGI } from './core'
3
+ import { BaseChatModel } from 'langchain/chat_models/base'
4
+ import { VectorStore } from 'langchain/vectorstores'
5
+
6
+ class BabyAGI_Agents implements INode {
7
+ label: string
8
+ name: string
9
+ description: string
10
+ type: string
11
+ icon: string
12
+ category: string
13
+ baseClasses: string[]
14
+ inputs: INodeParams[]
15
+
16
+ constructor() {
17
+ this.label = 'BabyAGI'
18
+ this.name = 'babyAGI'
19
+ this.type = 'BabyAGI'
20
+ this.category = 'Agents'
21
+ this.icon = 'babyagi.jpg'
22
+ this.description = 'Task Driven Autonomous Agent which creates new task and reprioritizes task list based on objective'
23
+ this.baseClasses = ['BabyAGI']
24
+ this.inputs = [
25
+ {
26
+ label: 'Chat Model',
27
+ name: 'model',
28
+ type: 'BaseChatModel'
29
+ },
30
+ {
31
+ label: 'Vector Store',
32
+ name: 'vectorStore',
33
+ type: 'VectorStore'
34
+ },
35
+ {
36
+ label: 'Task Loop',
37
+ name: 'taskLoop',
38
+ type: 'number',
39
+ default: 3
40
+ }
41
+ ]
42
+ }
43
+
44
+ async init(nodeData: INodeData): Promise<any> {
45
+ const model = nodeData.inputs?.model as BaseChatModel
46
+ const vectorStore = nodeData.inputs?.vectorStore as VectorStore
47
+ const taskLoop = nodeData.inputs?.taskLoop as string
48
+
49
+ const babyAgi = BabyAGI.fromLLM(model, vectorStore, parseInt(taskLoop, 10))
50
+ return babyAgi
51
+ }
52
+
53
+ async run(nodeData: INodeData, input: string): Promise<string> {
54
+ const executor = nodeData.instance as BabyAGI
55
+ const objective = input
56
+
57
+ const res = await executor.call({ objective })
58
+ return res
59
+ }
60
+ }
61
+
62
+ module.exports = { nodeClass: BabyAGI_Agents }
packages/components/nodes/agents/BabyAGI/babyagi.jpg ADDED
packages/components/nodes/agents/BabyAGI/core.ts ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { LLMChain } from 'langchain/chains'
2
+ import { BaseChatModel } from 'langchain/chat_models/base'
3
+ import { VectorStore } from 'langchain/dist/vectorstores/base'
4
+ import { Document } from 'langchain/document'
5
+ import { PromptTemplate } from 'langchain/prompts'
6
+
7
+ class TaskCreationChain extends LLMChain {
8
+ constructor(prompt: PromptTemplate, llm: BaseChatModel) {
9
+ super({ prompt, llm })
10
+ }
11
+
12
+ static from_llm(llm: BaseChatModel): LLMChain {
13
+ const taskCreationTemplate: string =
14
+ 'You are a task creation AI that uses the result of an execution agent' +
15
+ ' to create new tasks with the following objective: {objective},' +
16
+ ' The last completed task has the result: {result}.' +
17
+ ' This result was based on this task description: {task_description}.' +
18
+ ' These are incomplete tasks list: {incomplete_tasks}.' +
19
+ ' Based on the result, create new tasks to be completed' +
20
+ ' by the AI system that do not overlap with incomplete tasks.' +
21
+ ' Return the tasks as an array.'
22
+
23
+ const prompt = new PromptTemplate({
24
+ template: taskCreationTemplate,
25
+ inputVariables: ['result', 'task_description', 'incomplete_tasks', 'objective']
26
+ })
27
+
28
+ return new TaskCreationChain(prompt, llm)
29
+ }
30
+ }
31
+
32
+ class TaskPrioritizationChain extends LLMChain {
33
+ constructor(prompt: PromptTemplate, llm: BaseChatModel) {
34
+ super({ prompt, llm })
35
+ }
36
+
37
+ static from_llm(llm: BaseChatModel): TaskPrioritizationChain {
38
+ const taskPrioritizationTemplate: string =
39
+ 'You are a task prioritization AI tasked with cleaning the formatting of and reprioritizing' +
40
+ ' the following task list: {task_names}.' +
41
+ ' Consider the ultimate objective of your team: {objective}.' +
42
+ ' Do not remove any tasks. Return the result as a numbered list, like:' +
43
+ ' #. First task' +
44
+ ' #. Second task' +
45
+ ' Start the task list with number {next_task_id}.'
46
+ const prompt = new PromptTemplate({
47
+ template: taskPrioritizationTemplate,
48
+ inputVariables: ['task_names', 'next_task_id', 'objective']
49
+ })
50
+ return new TaskPrioritizationChain(prompt, llm)
51
+ }
52
+ }
53
+
54
+ class ExecutionChain extends LLMChain {
55
+ constructor(prompt: PromptTemplate, llm: BaseChatModel) {
56
+ super({ prompt, llm })
57
+ }
58
+
59
+ static from_llm(llm: BaseChatModel): LLMChain {
60
+ const executionTemplate: string =
61
+ 'You are an AI who performs one task based on the following objective: {objective}.' +
62
+ ' Take into account these previously completed tasks: {context}.' +
63
+ ' Your task: {task}.' +
64
+ ' Response:'
65
+
66
+ const prompt = new PromptTemplate({
67
+ template: executionTemplate,
68
+ inputVariables: ['objective', 'context', 'task']
69
+ })
70
+
71
+ return new ExecutionChain(prompt, llm)
72
+ }
73
+ }
74
+
75
+ async function getNextTask(
76
+ taskCreationChain: LLMChain,
77
+ result: string,
78
+ taskDescription: string,
79
+ taskList: string[],
80
+ objective: string
81
+ ): Promise<any[]> {
82
+ const incompleteTasks: string = taskList.join(', ')
83
+ const response: string = await taskCreationChain.predict({
84
+ result,
85
+ task_description: taskDescription,
86
+ incomplete_tasks: incompleteTasks,
87
+ objective
88
+ })
89
+
90
+ const newTasks: string[] = response.split('\n')
91
+
92
+ return newTasks.filter((taskName) => taskName.trim()).map((taskName) => ({ task_name: taskName }))
93
+ }
94
+
95
+ interface Task {
96
+ task_id: number
97
+ task_name: string
98
+ }
99
+
100
+ async function prioritizeTasks(
101
+ taskPrioritizationChain: LLMChain,
102
+ thisTaskId: number,
103
+ taskList: Task[],
104
+ objective: string
105
+ ): Promise<Task[]> {
106
+ const next_task_id = thisTaskId + 1
107
+ const task_names = taskList.map((t) => t.task_name).join(', ')
108
+ const response = await taskPrioritizationChain.predict({ task_names, next_task_id, objective })
109
+ const newTasks = response.split('\n')
110
+ const prioritizedTaskList: Task[] = []
111
+
112
+ for (const taskString of newTasks) {
113
+ if (!taskString.trim()) {
114
+ // eslint-disable-next-line no-continue
115
+ continue
116
+ }
117
+ const taskParts = taskString.trim().split('. ', 2)
118
+ if (taskParts.length === 2) {
119
+ const task_id = parseInt(taskParts[0].trim(), 10)
120
+ const task_name = taskParts[1].trim()
121
+ prioritizedTaskList.push({ task_id, task_name })
122
+ }
123
+ }
124
+
125
+ return prioritizedTaskList
126
+ }
127
+
128
+ export async function get_top_tasks(vectorStore: VectorStore, query: string, k: number): Promise<string[]> {
129
+ const docs = await vectorStore.similaritySearch(query, k)
130
+ let returnDocs: string[] = []
131
+ for (const doc of docs) {
132
+ returnDocs.push(doc.metadata.task)
133
+ }
134
+ return returnDocs
135
+ }
136
+
137
+ async function executeTask(vectorStore: VectorStore, executionChain: LLMChain, objective: string, task: string, k = 5): Promise<string> {
138
+ const context = await get_top_tasks(vectorStore, objective, k)
139
+ return executionChain.predict({ objective, context, task })
140
+ }
141
+
142
+ export class BabyAGI {
143
+ taskList: Array<Task> = []
144
+
145
+ taskCreationChain: TaskCreationChain
146
+
147
+ taskPrioritizationChain: TaskPrioritizationChain
148
+
149
+ executionChain: ExecutionChain
150
+
151
+ taskIdCounter = 1
152
+
153
+ vectorStore: VectorStore
154
+
155
+ maxIterations = 3
156
+
157
+ constructor(
158
+ taskCreationChain: TaskCreationChain,
159
+ taskPrioritizationChain: TaskPrioritizationChain,
160
+ executionChain: ExecutionChain,
161
+ vectorStore: VectorStore,
162
+ maxIterations: number
163
+ ) {
164
+ this.taskCreationChain = taskCreationChain
165
+ this.taskPrioritizationChain = taskPrioritizationChain
166
+ this.executionChain = executionChain
167
+ this.vectorStore = vectorStore
168
+ this.maxIterations = maxIterations
169
+ }
170
+
171
+ addTask(task: Task) {
172
+ this.taskList.push(task)
173
+ }
174
+
175
+ printTaskList() {
176
+ // eslint-disable-next-line no-console
177
+ console.log('\x1b[95m\x1b[1m\n*****TASK LIST*****\n\x1b[0m\x1b[0m')
178
+ // eslint-disable-next-line no-console
179
+ this.taskList.forEach((t) => console.log(`${t.task_id}: ${t.task_name}`))
180
+ }
181
+
182
+ printNextTask(task: Task) {
183
+ // eslint-disable-next-line no-console
184
+ console.log('\x1b[92m\x1b[1m\n*****NEXT TASK*****\n\x1b[0m\x1b[0m')
185
+ // eslint-disable-next-line no-console
186
+ console.log(`${task.task_id}: ${task.task_name}`)
187
+ }
188
+
189
+ printTaskResult(result: string) {
190
+ // eslint-disable-next-line no-console
191
+ console.log('\x1b[93m\x1b[1m\n*****TASK RESULT*****\n\x1b[0m\x1b[0m')
192
+ // eslint-disable-next-line no-console
193
+ console.log(result)
194
+ }
195
+
196
+ getInputKeys(): string[] {
197
+ return ['objective']
198
+ }
199
+
200
+ getOutputKeys(): string[] {
201
+ return []
202
+ }
203
+
204
+ async call(inputs: Record<string, any>): Promise<string> {
205
+ const { objective } = inputs
206
+ const firstTask = inputs.first_task || 'Make a todo list'
207
+ this.addTask({ task_id: 1, task_name: firstTask })
208
+ let numIters = 0
209
+ let loop = true
210
+ let finalResult = ''
211
+
212
+ while (loop) {
213
+ if (this.taskList.length) {
214
+ this.printTaskList()
215
+
216
+ // Step 1: Pull the first task
217
+ const task = this.taskList.shift()
218
+ if (!task) break
219
+ this.printNextTask(task)
220
+
221
+ // Step 2: Execute the task
222
+ const result = await executeTask(this.vectorStore, this.executionChain, objective, task.task_name)
223
+ const thisTaskId = task.task_id
224
+ finalResult = result
225
+ this.printTaskResult(result)
226
+
227
+ // Step 3: Store the result in Pinecone
228
+ const docs = new Document({ pageContent: result, metadata: { task: task.task_name } })
229
+ this.vectorStore.addDocuments([docs])
230
+
231
+ // Step 4: Create new tasks and reprioritize task list
232
+ const newTasks = await getNextTask(
233
+ this.taskCreationChain,
234
+ result,
235
+ task.task_name,
236
+ this.taskList.map((t) => t.task_name),
237
+ objective
238
+ )
239
+ newTasks.forEach((newTask) => {
240
+ this.taskIdCounter += 1
241
+ // eslint-disable-next-line no-param-reassign
242
+ newTask.task_id = this.taskIdCounter
243
+ this.addTask(newTask)
244
+ })
245
+ this.taskList = await prioritizeTasks(this.taskPrioritizationChain, thisTaskId, this.taskList, objective)
246
+ }
247
+
248
+ numIters += 1
249
+ if (this.maxIterations !== null && numIters === this.maxIterations) {
250
+ // eslint-disable-next-line no-console
251
+ console.log('\x1b[91m\x1b[1m\n*****TASK ENDING*****\n\x1b[0m\x1b[0m')
252
+ loop = false
253
+ this.taskList = []
254
+ }
255
+ }
256
+
257
+ return finalResult
258
+ }
259
+
260
+ static fromLLM(llm: BaseChatModel, vectorstore: VectorStore, maxIterations = 3): BabyAGI {
261
+ const taskCreationChain = TaskCreationChain.from_llm(llm)
262
+ const taskPrioritizationChain = TaskPrioritizationChain.from_llm(llm)
263
+ const executionChain = ExecutionChain.from_llm(llm)
264
+ return new BabyAGI(taskCreationChain, taskPrioritizationChain, executionChain, vectorstore, maxIterations)
265
+ }
266
+ }
packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { initializeAgentExecutorWithOptions, AgentExecutor, InitializeAgentExecutorOptions } from 'langchain/agents'
3
+ import { Tool } from 'langchain/tools'
4
+ import { BaseChatMemory, ChatMessageHistory } from 'langchain/memory'
5
+ import { getBaseClasses } from '../../../src/utils'
6
+ import { AIChatMessage, HumanChatMessage } from 'langchain/schema'
7
+ import { BaseLanguageModel } from 'langchain/base_language'
8
+
9
+ class ConversationalAgent_Agents implements INode {
10
+ label: string
11
+ name: string
12
+ description: string
13
+ type: string
14
+ icon: string
15
+ category: string
16
+ baseClasses: string[]
17
+ inputs: INodeParams[]
18
+
19
+ constructor() {
20
+ this.label = 'Conversational Agent'
21
+ this.name = 'conversationalAgent'
22
+ this.type = 'AgentExecutor'
23
+ this.category = 'Agents'
24
+ this.icon = 'agent.svg'
25
+ this.description = 'Conversational agent for a chat model. It will utilize chat specific prompts'
26
+ this.baseClasses = [this.type, ...getBaseClasses(AgentExecutor)]
27
+ this.inputs = [
28
+ {
29
+ label: 'Allowed Tools',
30
+ name: 'tools',
31
+ type: 'Tool',
32
+ list: true
33
+ },
34
+ {
35
+ label: 'Language Model',
36
+ name: 'model',
37
+ type: 'BaseLanguageModel'
38
+ },
39
+ {
40
+ label: 'Memory',
41
+ name: 'memory',
42
+ type: 'BaseChatMemory'
43
+ },
44
+ {
45
+ label: 'System Message',
46
+ name: 'systemMessage',
47
+ type: 'string',
48
+ rows: 4,
49
+ optional: true,
50
+ additionalParams: true
51
+ },
52
+ {
53
+ label: 'Human Message',
54
+ name: 'humanMessage',
55
+ type: 'string',
56
+ rows: 4,
57
+ optional: true,
58
+ additionalParams: true
59
+ }
60
+ ]
61
+ }
62
+
63
+ async init(nodeData: INodeData): Promise<any> {
64
+ const model = nodeData.inputs?.model as BaseLanguageModel
65
+ let tools = nodeData.inputs?.tools as Tool[]
66
+ tools = tools.flat()
67
+ const memory = nodeData.inputs?.memory as BaseChatMemory
68
+ const humanMessage = nodeData.inputs?.humanMessage as string
69
+ const systemMessage = nodeData.inputs?.systemMessage as string
70
+
71
+ const obj: InitializeAgentExecutorOptions = {
72
+ agentType: 'chat-conversational-react-description',
73
+ verbose: process.env.DEBUG === 'true' ? true : false
74
+ }
75
+
76
+ const agentArgs: any = {}
77
+ if (humanMessage) {
78
+ agentArgs.humanMessage = humanMessage
79
+ }
80
+ if (systemMessage) {
81
+ agentArgs.systemMessage = systemMessage
82
+ }
83
+
84
+ if (Object.keys(agentArgs).length) obj.agentArgs = agentArgs
85
+
86
+ const executor = await initializeAgentExecutorWithOptions(tools, model, obj)
87
+ executor.memory = memory
88
+ return executor
89
+ }
90
+
91
+ async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
92
+ const executor = nodeData.instance as AgentExecutor
93
+ const memory = nodeData.inputs?.memory as BaseChatMemory
94
+
95
+ if (options && options.chatHistory) {
96
+ const chatHistory = []
97
+ const histories: IMessage[] = options.chatHistory
98
+
99
+ for (const message of histories) {
100
+ if (message.type === 'apiMessage') {
101
+ chatHistory.push(new AIChatMessage(message.message))
102
+ } else if (message.type === 'userMessage') {
103
+ chatHistory.push(new HumanChatMessage(message.message))
104
+ }
105
+ }
106
+ memory.chatHistory = new ChatMessageHistory(chatHistory)
107
+ executor.memory = memory
108
+ }
109
+ const result = await executor.call({ input })
110
+
111
+ return result?.output
112
+ }
113
+ }
114
+
115
+ module.exports = { nodeClass: ConversationalAgent_Agents }
packages/components/nodes/agents/ConversationalAgent/agent.svg ADDED
packages/components/nodes/agents/MRKLAgentChat/MRKLAgentChat.ts ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { initializeAgentExecutorWithOptions, AgentExecutor } from 'langchain/agents'
3
+ import { getBaseClasses } from '../../../src/utils'
4
+ import { Tool } from 'langchain/tools'
5
+ import { BaseLanguageModel } from 'langchain/base_language'
6
+
7
+ class MRKLAgentChat_Agents implements INode {
8
+ label: string
9
+ name: string
10
+ description: string
11
+ type: string
12
+ icon: string
13
+ category: string
14
+ baseClasses: string[]
15
+ inputs: INodeParams[]
16
+
17
+ constructor() {
18
+ this.label = 'MRKL Agent for Chat Models'
19
+ this.name = 'mrklAgentChat'
20
+ this.type = 'AgentExecutor'
21
+ this.category = 'Agents'
22
+ this.icon = 'agent.svg'
23
+ this.description = 'Agent that uses the ReAct Framework to decide what action to take, optimized to be used with Chat Models'
24
+ this.baseClasses = [this.type, ...getBaseClasses(AgentExecutor)]
25
+ this.inputs = [
26
+ {
27
+ label: 'Allowed Tools',
28
+ name: 'tools',
29
+ type: 'Tool',
30
+ list: true
31
+ },
32
+ {
33
+ label: 'Language Model',
34
+ name: 'model',
35
+ type: 'BaseLanguageModel'
36
+ }
37
+ ]
38
+ }
39
+
40
+ async init(nodeData: INodeData): Promise<any> {
41
+ const model = nodeData.inputs?.model as BaseLanguageModel
42
+ let tools = nodeData.inputs?.tools as Tool[]
43
+ tools = tools.flat()
44
+ const executor = await initializeAgentExecutorWithOptions(tools, model, {
45
+ agentType: 'chat-zero-shot-react-description',
46
+ verbose: process.env.DEBUG === 'true' ? true : false
47
+ })
48
+ return executor
49
+ }
50
+
51
+ async run(nodeData: INodeData, input: string): Promise<string> {
52
+ const executor = nodeData.instance as AgentExecutor
53
+ const result = await executor.call({ input })
54
+
55
+ return result?.output
56
+ }
57
+ }
58
+
59
+ module.exports = { nodeClass: MRKLAgentChat_Agents }
packages/components/nodes/agents/MRKLAgentChat/agent.svg ADDED
packages/components/nodes/agents/MRKLAgentLLM/MRKLAgentLLM.ts ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { initializeAgentExecutorWithOptions, AgentExecutor } from 'langchain/agents'
3
+ import { Tool } from 'langchain/tools'
4
+ import { getBaseClasses } from '../../../src/utils'
5
+ import { BaseLanguageModel } from 'langchain/base_language'
6
+
7
+ class MRKLAgentLLM_Agents implements INode {
8
+ label: string
9
+ name: string
10
+ description: string
11
+ type: string
12
+ icon: string
13
+ category: string
14
+ baseClasses: string[]
15
+ inputs: INodeParams[]
16
+
17
+ constructor() {
18
+ this.label = 'MRKL Agent for LLMs'
19
+ this.name = 'mrklAgentLLM'
20
+ this.type = 'AgentExecutor'
21
+ this.category = 'Agents'
22
+ this.icon = 'agent.svg'
23
+ this.description = 'Agent that uses the ReAct Framework to decide what action to take, optimized to be used with LLMs'
24
+ this.baseClasses = [this.type, ...getBaseClasses(AgentExecutor)]
25
+ this.inputs = [
26
+ {
27
+ label: 'Allowed Tools',
28
+ name: 'tools',
29
+ type: 'Tool',
30
+ list: true
31
+ },
32
+ {
33
+ label: 'Language Model',
34
+ name: 'model',
35
+ type: 'BaseLanguageModel'
36
+ }
37
+ ]
38
+ }
39
+
40
+ async init(nodeData: INodeData): Promise<any> {
41
+ const model = nodeData.inputs?.model as BaseLanguageModel
42
+ let tools = nodeData.inputs?.tools as Tool[]
43
+ tools = tools.flat()
44
+
45
+ const executor = await initializeAgentExecutorWithOptions(tools, model, {
46
+ agentType: 'zero-shot-react-description',
47
+ verbose: process.env.DEBUG === 'true' ? true : false
48
+ })
49
+ return executor
50
+ }
51
+
52
+ async run(nodeData: INodeData, input: string): Promise<string> {
53
+ const executor = nodeData.instance as AgentExecutor
54
+ const result = await executor.call({ input })
55
+
56
+ return result?.output
57
+ }
58
+ }
59
+
60
+ module.exports = { nodeClass: MRKLAgentLLM_Agents }
packages/components/nodes/agents/MRKLAgentLLM/agent.svg ADDED
packages/components/nodes/chains/ConversationChain/ConversationChain.ts ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { ConversationChain } from 'langchain/chains'
3
+ import { getBaseClasses } from '../../../src/utils'
4
+ import { ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate } from 'langchain/prompts'
5
+ import { BufferMemory, ChatMessageHistory } from 'langchain/memory'
6
+ import { BaseChatModel } from 'langchain/chat_models/base'
7
+ import { AIChatMessage, HumanChatMessage } from 'langchain/schema'
8
+
9
+ 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.`
10
+
11
+ class ConversationChain_Chains implements INode {
12
+ label: string
13
+ name: string
14
+ type: string
15
+ icon: string
16
+ category: string
17
+ baseClasses: string[]
18
+ description: string
19
+ inputs: INodeParams[]
20
+
21
+ constructor() {
22
+ this.label = 'Conversation Chain'
23
+ this.name = 'conversationChain'
24
+ this.type = 'ConversationChain'
25
+ this.icon = 'chain.svg'
26
+ this.category = 'Chains'
27
+ this.description = 'Chat models specific conversational chain with memory'
28
+ this.baseClasses = [this.type, ...getBaseClasses(ConversationChain)]
29
+ this.inputs = [
30
+ {
31
+ label: 'Language Model',
32
+ name: 'model',
33
+ type: 'BaseChatModel'
34
+ },
35
+ {
36
+ label: 'Memory',
37
+ name: 'memory',
38
+ type: 'BaseMemory'
39
+ },
40
+ {
41
+ label: 'System Message',
42
+ name: 'systemMessagePrompt',
43
+ type: 'string',
44
+ rows: 4,
45
+ additionalParams: true,
46
+ optional: true,
47
+ placeholder: 'You are a helpful assistant that write codes'
48
+ }
49
+ ]
50
+ }
51
+
52
+ async init(nodeData: INodeData): Promise<any> {
53
+ const model = nodeData.inputs?.model as BaseChatModel
54
+ const memory = nodeData.inputs?.memory as BufferMemory
55
+ const prompt = nodeData.inputs?.systemMessagePrompt as string
56
+
57
+ const obj: any = {
58
+ llm: model,
59
+ memory
60
+ }
61
+
62
+ const chatPrompt = ChatPromptTemplate.fromPromptMessages([
63
+ SystemMessagePromptTemplate.fromTemplate(prompt ? `${prompt}\n${systemMessage}` : systemMessage),
64
+ new MessagesPlaceholder(memory.memoryKey ?? 'chat_history'),
65
+ HumanMessagePromptTemplate.fromTemplate('{input}')
66
+ ])
67
+ obj.prompt = chatPrompt
68
+
69
+ const chain = new ConversationChain(obj)
70
+ return chain
71
+ }
72
+
73
+ async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
74
+ const chain = nodeData.instance as ConversationChain
75
+ const memory = nodeData.inputs?.memory as BufferMemory
76
+
77
+ if (options && options.chatHistory) {
78
+ const chatHistory = []
79
+ const histories: IMessage[] = options.chatHistory
80
+
81
+ for (const message of histories) {
82
+ if (message.type === 'apiMessage') {
83
+ chatHistory.push(new AIChatMessage(message.message))
84
+ } else if (message.type === 'userMessage') {
85
+ chatHistory.push(new HumanChatMessage(message.message))
86
+ }
87
+ }
88
+ memory.chatHistory = new ChatMessageHistory(chatHistory)
89
+ chain.memory = memory
90
+ }
91
+
92
+ const res = await chain.call({ input })
93
+ return res?.response
94
+ }
95
+ }
96
+
97
+ module.exports = { nodeClass: ConversationChain_Chains }
packages/components/nodes/chains/ConversationChain/chain.svg ADDED
packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { BaseLanguageModel } from 'langchain/base_language'
2
+ import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
3
+ import { getBaseClasses } from '../../../src/utils'
4
+ import { ConversationalRetrievalQAChain } from 'langchain/chains'
5
+ import { BaseRetriever } from 'langchain/schema'
6
+
7
+ 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.
8
+
9
+ {context}
10
+
11
+ Question: {question}
12
+ Helpful Answer:`
13
+
14
+ const qa_template = `Use the following pieces of context to answer the question at the end.
15
+
16
+ {context}
17
+
18
+ Question: {question}
19
+ Helpful Answer:`
20
+
21
+ class ConversationalRetrievalQAChain_Chains implements INode {
22
+ label: string
23
+ name: string
24
+ type: string
25
+ icon: string
26
+ category: string
27
+ baseClasses: string[]
28
+ description: string
29
+ inputs: INodeParams[]
30
+
31
+ constructor() {
32
+ this.label = 'Conversational Retrieval QA Chain'
33
+ this.name = 'conversationalRetrievalQAChain'
34
+ this.type = 'ConversationalRetrievalQAChain'
35
+ this.icon = 'chain.svg'
36
+ this.category = 'Chains'
37
+ this.description = 'Document QA - built on RetrievalQAChain to provide a chat history component'
38
+ this.baseClasses = [this.type, ...getBaseClasses(ConversationalRetrievalQAChain)]
39
+ this.inputs = [
40
+ {
41
+ label: 'Language Model',
42
+ name: 'model',
43
+ type: 'BaseLanguageModel'
44
+ },
45
+ {
46
+ label: 'Vector Store Retriever',
47
+ name: 'vectorStoreRetriever',
48
+ type: 'BaseRetriever'
49
+ },
50
+ {
51
+ label: 'System Message',
52
+ name: 'systemMessagePrompt',
53
+ type: 'string',
54
+ rows: 4,
55
+ additionalParams: true,
56
+ optional: true,
57
+ placeholder:
58
+ '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.'
59
+ }
60
+ ]
61
+ }
62
+
63
+ async init(nodeData: INodeData): Promise<any> {
64
+ const model = nodeData.inputs?.model as BaseLanguageModel
65
+ const vectorStoreRetriever = nodeData.inputs?.vectorStoreRetriever as BaseRetriever
66
+ const systemMessagePrompt = nodeData.inputs?.systemMessagePrompt as string
67
+
68
+ const chain = ConversationalRetrievalQAChain.fromLLM(model, vectorStoreRetriever, {
69
+ verbose: process.env.DEBUG === 'true' ? true : false,
70
+ qaTemplate: systemMessagePrompt ? `${systemMessagePrompt}\n${qa_template}` : default_qa_template
71
+ })
72
+ return chain
73
+ }
74
+
75
+ async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
76
+ const chain = nodeData.instance as ConversationalRetrievalQAChain
77
+ let chatHistory = ''
78
+
79
+ if (options && options.chatHistory) {
80
+ const histories: IMessage[] = options.chatHistory
81
+ chatHistory = histories
82
+ .map((item) => {
83
+ return item.message
84
+ })
85
+ .join('')
86
+ }
87
+
88
+ const obj = {
89
+ question: input,
90
+ chat_history: chatHistory ? chatHistory : []
91
+ }
92
+
93
+ const res = await chain.call(obj)
94
+
95
+ return res?.text
96
+ }
97
+ }
98
+
99
+ module.exports = { nodeClass: ConversationalRetrievalQAChain_Chains }
packages/components/nodes/chains/ConversationalRetrievalQAChain/chain.svg ADDED
packages/components/nodes/chains/LLMChain/LLMChain.ts ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface'
2
+ import { getBaseClasses } from '../../../src/utils'
3
+ import { LLMChain } from 'langchain/chains'
4
+ import { BaseLanguageModel } from 'langchain/base_language'
5
+
6
+ class LLMChain_Chains implements INode {
7
+ label: string
8
+ name: string
9
+ type: string
10
+ icon: string
11
+ category: string
12
+ baseClasses: string[]
13
+ description: string
14
+ inputs: INodeParams[]
15
+ outputs: INodeOutputsValue[]
16
+
17
+ constructor() {
18
+ this.label = 'LLM Chain'
19
+ this.name = 'llmChain'
20
+ this.type = 'LLMChain'
21
+ this.icon = 'chain.svg'
22
+ this.category = 'Chains'
23
+ this.description = 'Chain to run queries against LLMs'
24
+ this.baseClasses = [this.type, ...getBaseClasses(LLMChain)]
25
+ this.inputs = [
26
+ {
27
+ label: 'Language Model',
28
+ name: 'model',
29
+ type: 'BaseLanguageModel'
30
+ },
31
+ {
32
+ label: 'Prompt',
33
+ name: 'prompt',
34
+ type: 'BasePromptTemplate'
35
+ },
36
+ {
37
+ label: 'Chain Name',
38
+ name: 'chainName',
39
+ type: 'string',
40
+ placeholder: 'Name Your Chain',
41
+ optional: true
42
+ }
43
+ ]
44
+ this.outputs = [
45
+ {
46
+ label: 'LLM Chain',
47
+ name: 'llmChain',
48
+ baseClasses: [this.type, ...getBaseClasses(LLMChain)]
49
+ },
50
+ {
51
+ label: 'Output Prediction',
52
+ name: 'outputPrediction',
53
+ baseClasses: ['string']
54
+ }
55
+ ]
56
+ }
57
+
58
+ async init(nodeData: INodeData, input: string): Promise<any> {
59
+ const model = nodeData.inputs?.model as BaseLanguageModel
60
+ const prompt = nodeData.inputs?.prompt
61
+ const output = nodeData.outputs?.output as string
62
+ const promptValues = prompt.promptValues as ICommonObject
63
+
64
+ if (output === this.name) {
65
+ const chain = new LLMChain({ llm: model, prompt, verbose: process.env.DEBUG === 'true' ? true : false })
66
+ return chain
67
+ } else if (output === 'outputPrediction') {
68
+ const chain = new LLMChain({ llm: model, prompt, verbose: process.env.DEBUG === 'true' ? true : false })
69
+ const inputVariables = chain.prompt.inputVariables as string[] // ["product"]
70
+ const res = await runPrediction(inputVariables, chain, input, promptValues)
71
+ // eslint-disable-next-line no-console
72
+ console.log('\x1b[92m\x1b[1m\n*****OUTPUT PREDICTION*****\n\x1b[0m\x1b[0m')
73
+ // eslint-disable-next-line no-console
74
+ console.log(res)
75
+ return res
76
+ }
77
+ }
78
+
79
+ async run(nodeData: INodeData, input: string): Promise<string> {
80
+ const inputVariables = nodeData.instance.prompt.inputVariables as string[] // ["product"]
81
+ const chain = nodeData.instance as LLMChain
82
+ const promptValues = nodeData.inputs?.prompt.promptValues as ICommonObject
83
+
84
+ const res = await runPrediction(inputVariables, chain, input, promptValues)
85
+ // eslint-disable-next-line no-console
86
+ console.log('\x1b[93m\x1b[1m\n*****FINAL RESULT*****\n\x1b[0m\x1b[0m')
87
+ // eslint-disable-next-line no-console
88
+ console.log(res)
89
+ return res
90
+ }
91
+ }
92
+
93
+ const runPrediction = async (inputVariables: string[], chain: LLMChain, input: string, promptValues: ICommonObject) => {
94
+ if (inputVariables.length === 1) {
95
+ const res = await chain.run(input)
96
+ return res
97
+ } else if (inputVariables.length > 1) {
98
+ let seen: string[] = []
99
+
100
+ for (const variable of inputVariables) {
101
+ seen.push(variable)
102
+ if (promptValues[variable]) {
103
+ seen.pop()
104
+ }
105
+ }
106
+
107
+ if (seen.length === 0) {
108
+ // All inputVariables have fixed values specified
109
+ const options = {
110
+ ...promptValues
111
+ }
112
+ const res = await chain.call(options)
113
+ return res?.text
114
+ } else if (seen.length === 1) {
115
+ // If one inputVariable is not specify, use input (user's question) as value
116
+ const lastValue = seen.pop()
117
+ if (!lastValue) throw new Error('Please provide Prompt Values')
118
+ const options = {
119
+ ...promptValues,
120
+ [lastValue]: input
121
+ }
122
+ const res = await chain.call(options)
123
+ return res?.text
124
+ } else {
125
+ throw new Error(`Please provide Prompt Values for: ${seen.join(', ')}`)
126
+ }
127
+ } else {
128
+ const res = await chain.run(input)
129
+ return res
130
+ }
131
+ }
132
+
133
+ module.exports = { nodeClass: LLMChain_Chains }
packages/components/nodes/chains/LLMChain/chain.svg ADDED
packages/components/nodes/chains/RetrievalQAChain/RetrievalQAChain.ts ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { RetrievalQAChain } from 'langchain/chains'
3
+ import { BaseRetriever } from 'langchain/schema'
4
+ import { getBaseClasses } from '../../../src/utils'
5
+ import { BaseLanguageModel } from 'langchain/base_language'
6
+
7
+ class RetrievalQAChain_Chains implements INode {
8
+ label: string
9
+ name: string
10
+ type: string
11
+ icon: string
12
+ category: string
13
+ baseClasses: string[]
14
+ description: string
15
+ inputs: INodeParams[]
16
+
17
+ constructor() {
18
+ this.label = 'Retrieval QA Chain'
19
+ this.name = 'retrievalQAChain'
20
+ this.type = 'RetrievalQAChain'
21
+ this.icon = 'chain.svg'
22
+ this.category = 'Chains'
23
+ this.description = 'QA chain to answer a question based on the retrieved documents'
24
+ this.baseClasses = [this.type, ...getBaseClasses(RetrievalQAChain)]
25
+ this.inputs = [
26
+ {
27
+ label: 'Language Model',
28
+ name: 'model',
29
+ type: 'BaseLanguageModel'
30
+ },
31
+ {
32
+ label: 'Vector Store Retriever',
33
+ name: 'vectorStoreRetriever',
34
+ type: 'BaseRetriever'
35
+ }
36
+ ]
37
+ }
38
+
39
+ async init(nodeData: INodeData): Promise<any> {
40
+ const model = nodeData.inputs?.model as BaseLanguageModel
41
+ const vectorStoreRetriever = nodeData.inputs?.vectorStoreRetriever as BaseRetriever
42
+
43
+ const chain = RetrievalQAChain.fromLLM(model, vectorStoreRetriever, { verbose: process.env.DEBUG === 'true' ? true : false })
44
+ return chain
45
+ }
46
+
47
+ async run(nodeData: INodeData, input: string): Promise<string> {
48
+ const chain = nodeData.instance as RetrievalQAChain
49
+ const obj = {
50
+ query: input
51
+ }
52
+ const res = await chain.call(obj)
53
+ return res?.text
54
+ }
55
+ }
56
+
57
+ module.exports = { nodeClass: RetrievalQAChain_Chains }
packages/components/nodes/chains/RetrievalQAChain/chain.svg ADDED
packages/components/nodes/chains/SqlDatabaseChain/SqlDatabaseChain.ts ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { SqlDatabaseChain, SqlDatabaseChainInput } from 'langchain/chains'
3
+ import { getBaseClasses } from '../../../src/utils'
4
+ import { DataSource } from 'typeorm'
5
+ import { SqlDatabase } from 'langchain/sql_db'
6
+ import { BaseLanguageModel } from 'langchain/base_language'
7
+
8
+ class SqlDatabaseChain_Chains implements INode {
9
+ label: string
10
+ name: string
11
+ type: string
12
+ icon: string
13
+ category: string
14
+ baseClasses: string[]
15
+ description: string
16
+ inputs: INodeParams[]
17
+
18
+ constructor() {
19
+ this.label = 'Sql Database Chain'
20
+ this.name = 'sqlDatabaseChain'
21
+ this.type = 'SqlDatabaseChain'
22
+ this.icon = 'sqlchain.svg'
23
+ this.category = 'Chains'
24
+ this.description = 'Answer questions over a SQL database'
25
+ this.baseClasses = [this.type, ...getBaseClasses(SqlDatabaseChain)]
26
+ this.inputs = [
27
+ {
28
+ label: 'Language Model',
29
+ name: 'model',
30
+ type: 'BaseLanguageModel'
31
+ },
32
+ {
33
+ label: 'Database',
34
+ name: 'database',
35
+ type: 'options',
36
+ options: [
37
+ {
38
+ label: 'SQlite',
39
+ name: 'sqlite'
40
+ }
41
+ ],
42
+ default: 'sqlite'
43
+ },
44
+ {
45
+ label: 'Database File Path',
46
+ name: 'dbFilePath',
47
+ type: 'string',
48
+ placeholder: 'C:/Users/chinook.db'
49
+ }
50
+ ]
51
+ }
52
+
53
+ async init(nodeData: INodeData): Promise<any> {
54
+ const databaseType = nodeData.inputs?.database as 'sqlite'
55
+ const model = nodeData.inputs?.model as BaseLanguageModel
56
+ const dbFilePath = nodeData.inputs?.dbFilePath
57
+
58
+ const chain = await getSQLDBChain(databaseType, dbFilePath, model)
59
+ return chain
60
+ }
61
+
62
+ async run(nodeData: INodeData, input: string): Promise<string> {
63
+ const databaseType = nodeData.inputs?.database as 'sqlite'
64
+ const model = nodeData.inputs?.model as BaseLanguageModel
65
+ const dbFilePath = nodeData.inputs?.dbFilePath
66
+
67
+ const chain = await getSQLDBChain(databaseType, dbFilePath, model)
68
+ const res = await chain.run(input)
69
+ return res
70
+ }
71
+ }
72
+
73
+ const getSQLDBChain = async (databaseType: 'sqlite', dbFilePath: string, llm: BaseLanguageModel) => {
74
+ const datasource = new DataSource({
75
+ type: databaseType,
76
+ database: dbFilePath
77
+ })
78
+
79
+ const db = await SqlDatabase.fromDataSourceParams({
80
+ appDataSource: datasource
81
+ })
82
+
83
+ const obj: SqlDatabaseChainInput = {
84
+ llm,
85
+ database: db,
86
+ verbose: process.env.DEBUG === 'true' ? true : false
87
+ }
88
+
89
+ const chain = new SqlDatabaseChain(obj)
90
+ return chain
91
+ }
92
+
93
+ module.exports = { nodeClass: SqlDatabaseChain_Chains }
packages/components/nodes/chains/SqlDatabaseChain/sqlchain.svg ADDED
packages/components/nodes/chains/VectorDBQAChain/VectorDBQAChain.ts ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { getBaseClasses } from '../../../src/utils'
3
+ import { VectorDBQAChain } from 'langchain/chains'
4
+ import { BaseLanguageModel } from 'langchain/base_language'
5
+ import { VectorStore } from 'langchain/vectorstores'
6
+
7
+ class VectorDBQAChain_Chains implements INode {
8
+ label: string
9
+ name: string
10
+ type: string
11
+ icon: string
12
+ category: string
13
+ baseClasses: string[]
14
+ description: string
15
+ inputs: INodeParams[]
16
+
17
+ constructor() {
18
+ this.label = 'VectorDB QA Chain'
19
+ this.name = 'vectorDBQAChain'
20
+ this.type = 'VectorDBQAChain'
21
+ this.icon = 'chain.svg'
22
+ this.category = 'Chains'
23
+ this.description = 'QA chain for vector databases'
24
+ this.baseClasses = [this.type, ...getBaseClasses(VectorDBQAChain)]
25
+ this.inputs = [
26
+ {
27
+ label: 'Language Model',
28
+ name: 'model',
29
+ type: 'BaseLanguageModel'
30
+ },
31
+ {
32
+ label: 'Vector Store',
33
+ name: 'vectorStore',
34
+ type: 'VectorStore'
35
+ }
36
+ ]
37
+ }
38
+
39
+ async init(nodeData: INodeData): Promise<any> {
40
+ const model = nodeData.inputs?.model as BaseLanguageModel
41
+ const vectorStore = nodeData.inputs?.vectorStore as VectorStore
42
+
43
+ const chain = VectorDBQAChain.fromLLM(model, vectorStore, { verbose: process.env.DEBUG === 'true' ? true : false })
44
+ return chain
45
+ }
46
+
47
+ async run(nodeData: INodeData, input: string): Promise<string> {
48
+ const chain = nodeData.instance as VectorDBQAChain
49
+ const obj = {
50
+ query: input
51
+ }
52
+ const res = await chain.call(obj)
53
+ return res?.text
54
+ }
55
+ }
56
+
57
+ module.exports = { nodeClass: VectorDBQAChain_Chains }
packages/components/nodes/chains/VectorDBQAChain/chain.svg ADDED
packages/components/nodes/chatmodels/AzureChatOpenAI/Azure.svg ADDED
packages/components/nodes/chatmodels/AzureChatOpenAI/AzureChatOpenAI.ts ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { OpenAIBaseInput } from 'langchain/dist/types/openai-types'
2
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
3
+ import { getBaseClasses } from '../../../src/utils'
4
+ import { AzureOpenAIInput, ChatOpenAI } from 'langchain/chat_models/openai'
5
+
6
+ class AzureChatOpenAI_ChatModels implements INode {
7
+ label: string
8
+ name: string
9
+ type: string
10
+ icon: string
11
+ category: string
12
+ description: string
13
+ baseClasses: string[]
14
+ inputs: INodeParams[]
15
+
16
+ constructor() {
17
+ this.label = 'Azure ChatOpenAI'
18
+ this.name = 'azureChatOpenAI'
19
+ this.type = 'AzureChatOpenAI'
20
+ this.icon = 'Azure.svg'
21
+ this.category = 'Chat Models'
22
+ this.description = 'Wrapper around Azure OpenAI large language models that use the Chat endpoint'
23
+ this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
24
+ this.inputs = [
25
+ {
26
+ label: 'Azure OpenAI Api Key',
27
+ name: 'azureOpenAIApiKey',
28
+ type: 'password'
29
+ },
30
+ {
31
+ label: 'Model Name',
32
+ name: 'modelName',
33
+ type: 'options',
34
+ options: [
35
+ {
36
+ label: 'gpt-4',
37
+ name: 'gpt-4'
38
+ },
39
+ {
40
+ label: 'gpt-4-32k',
41
+ name: 'gpt-4-32k'
42
+ },
43
+ {
44
+ label: 'gpt-35-turbo',
45
+ name: 'gpt-35-turbo'
46
+ }
47
+ ],
48
+ default: 'gpt-35-turbo',
49
+ optional: true
50
+ },
51
+ {
52
+ label: 'Temperature',
53
+ name: 'temperature',
54
+ type: 'number',
55
+ default: 0.9,
56
+ optional: true
57
+ },
58
+ {
59
+ label: 'Azure OpenAI Api Instance Name',
60
+ name: 'azureOpenAIApiInstanceName',
61
+ type: 'string',
62
+ placeholder: 'YOUR-INSTANCE-NAME'
63
+ },
64
+ {
65
+ label: 'Azure OpenAI Api Deployment Name',
66
+ name: 'azureOpenAIApiDeploymentName',
67
+ type: 'string',
68
+ placeholder: 'YOUR-DEPLOYMENT-NAME'
69
+ },
70
+ {
71
+ label: 'Azure OpenAI Api Version',
72
+ name: 'azureOpenAIApiVersion',
73
+ type: 'options',
74
+ options: [
75
+ {
76
+ label: '2023-03-15-preview',
77
+ name: '2023-03-15-preview'
78
+ }
79
+ ],
80
+ default: '2023-03-15-preview'
81
+ },
82
+ {
83
+ label: 'Max Tokens',
84
+ name: 'maxTokens',
85
+ type: 'number',
86
+ optional: true,
87
+ additionalParams: true
88
+ },
89
+ {
90
+ label: 'Frequency Penalty',
91
+ name: 'frequencyPenalty',
92
+ type: 'number',
93
+ optional: true,
94
+ additionalParams: true
95
+ },
96
+ {
97
+ label: 'Presence Penalty',
98
+ name: 'presencePenalty',
99
+ type: 'number',
100
+ optional: true,
101
+ additionalParams: true
102
+ },
103
+ {
104
+ label: 'Timeout',
105
+ name: 'timeout',
106
+ type: 'number',
107
+ optional: true,
108
+ additionalParams: true
109
+ }
110
+ ]
111
+ }
112
+
113
+ async init(nodeData: INodeData): Promise<any> {
114
+ const azureOpenAIApiKey = nodeData.inputs?.azureOpenAIApiKey as string
115
+ const modelName = nodeData.inputs?.modelName as string
116
+ const temperature = nodeData.inputs?.temperature as string
117
+ const azureOpenAIApiInstanceName = nodeData.inputs?.azureOpenAIApiInstanceName as string
118
+ const azureOpenAIApiDeploymentName = nodeData.inputs?.azureOpenAIApiDeploymentName as string
119
+ const azureOpenAIApiVersion = nodeData.inputs?.azureOpenAIApiVersion as string
120
+ const maxTokens = nodeData.inputs?.maxTokens as string
121
+ const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
122
+ const presencePenalty = nodeData.inputs?.presencePenalty as string
123
+ const timeout = nodeData.inputs?.timeout as string
124
+
125
+ const obj: Partial<AzureOpenAIInput> & Partial<OpenAIBaseInput> = {
126
+ temperature: parseInt(temperature, 10),
127
+ modelName,
128
+ azureOpenAIApiKey,
129
+ azureOpenAIApiInstanceName,
130
+ azureOpenAIApiDeploymentName,
131
+ azureOpenAIApiVersion
132
+ }
133
+
134
+ if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
135
+ if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
136
+ if (presencePenalty) obj.presencePenalty = parseInt(presencePenalty, 10)
137
+ if (timeout) obj.timeout = parseInt(timeout, 10)
138
+
139
+ const model = new ChatOpenAI(obj)
140
+ return model
141
+ }
142
+ }
143
+
144
+ module.exports = { nodeClass: AzureChatOpenAI_ChatModels }
packages/components/nodes/chatmodels/ChatAnthropic/ChatAnthropic.ts ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { getBaseClasses } from '../../../src/utils'
3
+ import { AnthropicInput, ChatAnthropic } from 'langchain/chat_models/anthropic'
4
+
5
+ class ChatAnthropic_ChatModels implements INode {
6
+ label: string
7
+ name: string
8
+ type: string
9
+ icon: string
10
+ category: string
11
+ description: string
12
+ baseClasses: string[]
13
+ inputs: INodeParams[]
14
+
15
+ constructor() {
16
+ this.label = 'ChatAnthropic'
17
+ this.name = 'chatAnthropic'
18
+ this.type = 'ChatAnthropic'
19
+ this.icon = 'chatAnthropic.png'
20
+ this.category = 'Chat Models'
21
+ this.description = 'Wrapper around ChatAnthropic large language models that use the Chat endpoint'
22
+ this.baseClasses = [this.type, ...getBaseClasses(ChatAnthropic)]
23
+ this.inputs = [
24
+ {
25
+ label: 'ChatAnthropic Api Key',
26
+ name: 'anthropicApiKey',
27
+ type: 'password'
28
+ },
29
+ {
30
+ label: 'Model Name',
31
+ name: 'modelName',
32
+ type: 'options',
33
+ options: [
34
+ {
35
+ label: 'claude-v1',
36
+ name: 'claude-v1'
37
+ },
38
+ {
39
+ label: 'claude-v1-100k',
40
+ name: 'claude-v1-100k'
41
+ },
42
+ {
43
+ label: 'claude-v1.0',
44
+ name: 'claude-v1.0'
45
+ },
46
+ {
47
+ label: 'claude-v1.2',
48
+ name: 'claude-v1.2'
49
+ },
50
+ {
51
+ label: 'claude-v1.3',
52
+ name: 'claude-v1.3'
53
+ },
54
+ {
55
+ label: 'claude-v1.3-100k',
56
+ name: 'claude-v1.3-100k'
57
+ },
58
+ {
59
+ label: 'claude-instant-v1',
60
+ name: 'claude-instant-v1'
61
+ },
62
+ {
63
+ label: 'claude-instant-v1-100k',
64
+ name: 'claude-instant-v1-100k'
65
+ },
66
+ {
67
+ label: 'claude-instant-v1.0',
68
+ name: 'claude-instant-v1.0'
69
+ },
70
+ {
71
+ label: 'claude-instant-v1.1',
72
+ name: 'claude-instant-v1.1'
73
+ },
74
+ {
75
+ label: 'claude-instant-v1.1-100k',
76
+ name: 'claude-instant-v1.1-100k'
77
+ }
78
+ ],
79
+ default: 'claude-v1',
80
+ optional: true
81
+ },
82
+ {
83
+ label: 'Temperature',
84
+ name: 'temperature',
85
+ type: 'number',
86
+ default: 0.9,
87
+ optional: true
88
+ },
89
+ {
90
+ label: 'Max Tokens',
91
+ name: 'maxTokensToSample',
92
+ type: 'number',
93
+ optional: true,
94
+ additionalParams: true
95
+ },
96
+ {
97
+ label: 'Top P',
98
+ name: 'topP',
99
+ type: 'number',
100
+ optional: true,
101
+ additionalParams: true
102
+ },
103
+ {
104
+ label: 'Top K',
105
+ name: 'topK',
106
+ type: 'number',
107
+ optional: true,
108
+ additionalParams: true
109
+ }
110
+ ]
111
+ }
112
+
113
+ async init(nodeData: INodeData): Promise<any> {
114
+ const temperature = nodeData.inputs?.temperature as string
115
+ const modelName = nodeData.inputs?.modelName as string
116
+ const anthropicApiKey = nodeData.inputs?.anthropicApiKey as string
117
+ const maxTokensToSample = nodeData.inputs?.maxTokensToSample as string
118
+ const topP = nodeData.inputs?.topP as string
119
+ const topK = nodeData.inputs?.topK as string
120
+
121
+ const obj: Partial<AnthropicInput> & { anthropicApiKey?: string } = {
122
+ temperature: parseInt(temperature, 10),
123
+ modelName,
124
+ anthropicApiKey
125
+ }
126
+
127
+ if (maxTokensToSample) obj.maxTokensToSample = parseInt(maxTokensToSample, 10)
128
+ if (topP) obj.topP = parseInt(topP, 10)
129
+ if (topK) obj.topK = parseInt(topK, 10)
130
+
131
+ const model = new ChatAnthropic(obj)
132
+ return model
133
+ }
134
+ }
135
+
136
+ module.exports = { nodeClass: ChatAnthropic_ChatModels }
packages/components/nodes/chatmodels/ChatAnthropic/chatAnthropic.png ADDED
packages/components/nodes/chatmodels/ChatLocalAI/ChatLocalAI.ts ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { getBaseClasses } from '../../../src/utils'
3
+ import { OpenAIChat } from 'langchain/llms/openai'
4
+ import { OpenAIChatInput } from 'langchain/chat_models/openai'
5
+
6
+ class ChatLocalAI_ChatModels implements INode {
7
+ label: string
8
+ name: string
9
+ type: string
10
+ icon: string
11
+ category: string
12
+ description: string
13
+ baseClasses: string[]
14
+ inputs: INodeParams[]
15
+
16
+ constructor() {
17
+ this.label = 'ChatLocalAI'
18
+ this.name = 'chatLocalAI'
19
+ this.type = 'ChatLocalAI'
20
+ this.icon = 'localai.png'
21
+ this.category = 'Chat Models'
22
+ this.description = 'Use local LLMs like llama.cpp, gpt4all using LocalAI'
23
+ this.baseClasses = [this.type, 'BaseChatModel', ...getBaseClasses(OpenAIChat)]
24
+ this.inputs = [
25
+ {
26
+ label: 'Base Path',
27
+ name: 'basePath',
28
+ type: 'string',
29
+ placeholder: 'http://localhost:8080/v1'
30
+ },
31
+ {
32
+ label: 'Model Name',
33
+ name: 'modelName',
34
+ type: 'string',
35
+ placeholder: 'gpt4all-lora-quantized.bin'
36
+ },
37
+ {
38
+ label: 'Temperature',
39
+ name: 'temperature',
40
+ type: 'number',
41
+ default: 0.9,
42
+ optional: true
43
+ },
44
+ {
45
+ label: 'Max Tokens',
46
+ name: 'maxTokens',
47
+ type: 'number',
48
+ optional: true,
49
+ additionalParams: true
50
+ },
51
+ {
52
+ label: 'Top Probability',
53
+ name: 'topP',
54
+ type: 'number',
55
+ optional: true,
56
+ additionalParams: true
57
+ },
58
+ {
59
+ label: 'Timeout',
60
+ name: 'timeout',
61
+ type: 'number',
62
+ optional: true,
63
+ additionalParams: true
64
+ }
65
+ ]
66
+ }
67
+
68
+ async init(nodeData: INodeData): Promise<any> {
69
+ const temperature = nodeData.inputs?.temperature as string
70
+ const modelName = nodeData.inputs?.modelName as string
71
+ const maxTokens = nodeData.inputs?.maxTokens as string
72
+ const topP = nodeData.inputs?.topP as string
73
+ const timeout = nodeData.inputs?.timeout as string
74
+ const basePath = nodeData.inputs?.basePath as string
75
+
76
+ const obj: Partial<OpenAIChatInput> & { openAIApiKey?: string } = {
77
+ temperature: parseInt(temperature, 10),
78
+ modelName,
79
+ openAIApiKey: 'sk-'
80
+ }
81
+
82
+ if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
83
+ if (topP) obj.topP = parseInt(topP, 10)
84
+ if (timeout) obj.timeout = parseInt(timeout, 10)
85
+
86
+ const model = new OpenAIChat(obj, { basePath })
87
+
88
+ return model
89
+ }
90
+ }
91
+
92
+ module.exports = { nodeClass: ChatLocalAI_ChatModels }
packages/components/nodes/chatmodels/ChatLocalAI/localai.png ADDED
packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { INode, INodeData, INodeParams } from '../../../src/Interface'
2
+ import { getBaseClasses } from '../../../src/utils'
3
+ import { ChatOpenAI, OpenAIChatInput } from 'langchain/chat_models/openai'
4
+
5
+ class ChatOpenAI_ChatModels implements INode {
6
+ label: string
7
+ name: string
8
+ type: string
9
+ icon: string
10
+ category: string
11
+ description: string
12
+ baseClasses: string[]
13
+ inputs: INodeParams[]
14
+
15
+ constructor() {
16
+ this.label = 'ChatOpenAI'
17
+ this.name = 'chatOpenAI'
18
+ this.type = 'ChatOpenAI'
19
+ this.icon = 'openai.png'
20
+ this.category = 'Chat Models'
21
+ this.description = 'Wrapper around OpenAI large language models that use the Chat endpoint'
22
+ this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
23
+ this.inputs = [
24
+ {
25
+ label: 'OpenAI Api Key',
26
+ name: 'openAIApiKey',
27
+ type: 'password'
28
+ },
29
+ {
30
+ label: 'Model Name',
31
+ name: 'modelName',
32
+ type: 'options',
33
+ options: [
34
+ {
35
+ label: 'gpt-4',
36
+ name: 'gpt-4'
37
+ },
38
+ {
39
+ label: 'gpt-4-0314',
40
+ name: 'gpt-4-0314'
41
+ },
42
+ {
43
+ label: 'gpt-4-32k-0314',
44
+ name: 'gpt-4-32k-0314'
45
+ },
46
+ {
47
+ label: 'gpt-3.5-turbo',
48
+ name: 'gpt-3.5-turbo'
49
+ },
50
+ {
51
+ label: 'gpt-3.5-turbo-0301',
52
+ name: 'gpt-3.5-turbo-0301'
53
+ }
54
+ ],
55
+ default: 'gpt-3.5-turbo',
56
+ optional: true
57
+ },
58
+ {
59
+ label: 'Temperature',
60
+ name: 'temperature',
61
+ type: 'number',
62
+ default: 0.9,
63
+ optional: true
64
+ },
65
+ {
66
+ label: 'Max Tokens',
67
+ name: 'maxTokens',
68
+ type: 'number',
69
+ optional: true,
70
+ additionalParams: true
71
+ },
72
+ {
73
+ label: 'Top Probability',
74
+ name: 'topP',
75
+ type: 'number',
76
+ optional: true,
77
+ additionalParams: true
78
+ },
79
+ {
80
+ label: 'Frequency Penalty',
81
+ name: 'frequencyPenalty',
82
+ type: 'number',
83
+ optional: true,
84
+ additionalParams: true
85
+ },
86
+ {
87
+ label: 'Presence Penalty',
88
+ name: 'presencePenalty',
89
+ type: 'number',
90
+ optional: true,
91
+ additionalParams: true
92
+ },
93
+ {
94
+ label: 'Timeout',
95
+ name: 'timeout',
96
+ type: 'number',
97
+ optional: true,
98
+ additionalParams: true
99
+ }
100
+ ]
101
+ }
102
+
103
+ async init(nodeData: INodeData): Promise<any> {
104
+ const temperature = nodeData.inputs?.temperature as string
105
+ const modelName = nodeData.inputs?.modelName as string
106
+ const openAIApiKey = nodeData.inputs?.openAIApiKey as string
107
+ const maxTokens = nodeData.inputs?.maxTokens as string
108
+ const topP = nodeData.inputs?.topP as string
109
+ const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
110
+ const presencePenalty = nodeData.inputs?.presencePenalty as string
111
+ const timeout = nodeData.inputs?.timeout as string
112
+
113
+ const obj: Partial<OpenAIChatInput> & { openAIApiKey?: string } = {
114
+ temperature: parseInt(temperature, 10),
115
+ modelName,
116
+ openAIApiKey
117
+ }
118
+
119
+ if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
120
+ if (topP) obj.topP = parseInt(topP, 10)
121
+ if (frequencyPenalty) obj.frequencyPenalty = parseInt(frequencyPenalty, 10)
122
+ if (presencePenalty) obj.presencePenalty = parseInt(presencePenalty, 10)
123
+ if (timeout) obj.timeout = parseInt(timeout, 10)
124
+
125
+ const model = new ChatOpenAI(obj)
126
+ return model
127
+ }
128
+ }
129
+
130
+ module.exports = { nodeClass: ChatOpenAI_ChatModels }
packages/components/nodes/chatmodels/ChatOpenAI/openai.png ADDED