@n8n/chat 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +2 -0
- package/.eslintrc.cjs +51 -0
- package/.np-config.json +5 -0
- package/.storybook/main.ts +27 -0
- package/.storybook/preview.scss +4 -0
- package/.storybook/preview.ts +16 -0
- package/.vscode/extensions.json +3 -0
- package/README.md +4 -21
- package/env.d.ts +1 -0
- package/index.html +13 -0
- package/package.json +2 -62
- package/resources/workflow.json +293 -0
- package/scripts/pack.js +11 -0
- package/scripts/postbuild.js +16 -0
- package/src/App.vue +23 -0
- package/src/__stories__/App.stories.ts +43 -0
- package/src/__tests__/index.spec.ts +223 -0
- package/src/__tests__/setup.ts +1 -0
- package/src/__tests__/utils/create.ts +16 -0
- package/src/__tests__/utils/fetch.ts +18 -0
- package/src/__tests__/utils/selectors.ts +53 -0
- package/src/api/generic.ts +64 -0
- package/src/api/message.ts +31 -0
- package/src/components/Button.vue +41 -0
- package/src/components/Chat.vue +48 -0
- package/src/components/ChatWindow.vue +125 -0
- package/src/components/GetStarted.vue +24 -0
- package/src/components/GetStartedFooter.vue +20 -0
- package/src/components/Input.vue +93 -0
- package/src/components/Layout.vue +82 -0
- package/src/components/Message.vue +97 -0
- package/src/components/MessageTyping.vue +109 -0
- package/src/components/MessagesList.vue +37 -0
- package/src/components/PoweredBy.vue +17 -0
- package/src/composables/useChat.ts +7 -0
- package/src/composables/useI18n.ts +16 -0
- package/src/composables/useOptions.ts +11 -0
- package/src/constants/defaults.ts +25 -0
- package/src/constants/localStorage.ts +2 -0
- package/src/constants/symbols.ts +8 -0
- package/src/event-buses/chatEventBus.ts +3 -0
- package/src/index.ts +42 -0
- package/src/main.scss +40 -0
- package/src/plugins/chat.ts +101 -0
- package/src/shims.d.ts +6 -0
- package/src/types/chat.ts +12 -0
- package/src/types/messages.ts +6 -0
- package/src/types/options.ts +23 -0
- package/src/types/webhook.ts +17 -0
- package/src/utils/event-bus.ts +51 -0
- package/src/utils/mount.ts +16 -0
- package/tsconfig.json +27 -0
- package/vite.config.ts +51 -0
- package/vitest.config.ts +20 -0
- package/chat.bundle.es.js +0 -10760
- package/chat.bundle.umd.js +0 -18
- package/chat.es.js +0 -6870
- package/chat.umd.js +0 -18
- package/style.css +0 -1
- package/types/App.vue.d.ts +0 -8
- package/types/__stories__/App.stories.d.ts +0 -17
- package/types/__tests__/index.spec.d.ts +0 -1
- package/types/__tests__/setup.d.ts +0 -0
- package/types/__tests__/utils/create.d.ts +0 -5
- package/types/__tests__/utils/fetch.d.ts +0 -4
- package/types/__tests__/utils/selectors.d.ts +0 -12
- package/types/api/generic.d.ts +0 -6
- package/types/api/message.d.ts +0 -3
- package/types/components/Button.vue.d.ts +0 -9
- package/types/components/Chat.vue.d.ts +0 -2
- package/types/components/ChatWindow.vue.d.ts +0 -2
- package/types/components/GetStarted.vue.d.ts +0 -2
- package/types/components/GetStartedFooter.vue.d.ts +0 -2
- package/types/components/Input.vue.d.ts +0 -2
- package/types/components/Layout.vue.d.ts +0 -11
- package/types/components/Message.vue.d.ts +0 -21
- package/types/components/MessageTyping.vue.d.ts +0 -15
- package/types/components/MessagesList.vue.d.ts +0 -14
- package/types/components/PoweredBy.vue.d.ts +0 -2
- package/types/composables/useChat.d.ts +0 -2
- package/types/composables/useI18n.d.ts +0 -4
- package/types/composables/useOptions.d.ts +0 -4
- package/types/constants/defaults.d.ts +0 -3
- package/types/constants/localStorage.d.ts +0 -2
- package/types/constants/symbols.d.ts +0 -4
- package/types/event-buses/chatEventBus.d.ts +0 -1
- package/types/index.d.ts +0 -2
- package/types/plugins/chat.d.ts +0 -3
- package/types/types/chat.d.ts +0 -11
- package/types/types/messages.d.ts +0 -6
- package/types/types/options.d.ts +0 -25
- package/types/types/webhook.d.ts +0 -15
- package/types/utils/event-bus.d.ts +0 -8
- package/types/utils/mount.d.ts +0 -1
- /package/{favicon.ico → public/favicon.ico} +0 -0
- /package/{types/__tests__/utils/index.d.ts → src/__tests__/utils/index.ts} +0 -0
- /package/{types/api/index.d.ts → src/api/index.ts} +0 -0
- /package/{types/components/index.d.ts → src/components/index.ts} +0 -0
- /package/{types/composables/index.d.ts → src/composables/index.ts} +0 -0
- /package/{types/constants/index.d.ts → src/constants/index.ts} +0 -0
- /package/{types/event-buses/index.d.ts → src/event-buses/index.ts} +0 -0
- /package/{types/plugins/index.d.ts → src/plugins/index.ts} +0 -0
- /package/{types/types/index.d.ts → src/types/index.ts} +0 -0
- /package/{types/utils/index.d.ts → src/utils/index.ts} +0 -0
package/.eslintignore
ADDED
package/.eslintrc.cjs
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const sharedOptions = require('@n8n_io/eslint-config/shared');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @type {import('@types/eslint').ESLint.ConfigData}
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: ['@n8n_io/eslint-config/frontend'],
|
|
8
|
+
|
|
9
|
+
...sharedOptions(__dirname, 'frontend'),
|
|
10
|
+
|
|
11
|
+
rules: {
|
|
12
|
+
'n8n-local-rules/dangerously-use-html-string-missing': 'off',
|
|
13
|
+
|
|
14
|
+
// TODO: Remove these
|
|
15
|
+
'id-denylist': 'warn',
|
|
16
|
+
'import/extensions': 'warn',
|
|
17
|
+
'import/no-default-export': 'warn',
|
|
18
|
+
'import/order': 'off',
|
|
19
|
+
'import/no-cycle': 'warn',
|
|
20
|
+
'import/no-duplicates': 'warn',
|
|
21
|
+
'@typescript-eslint/ban-types': 'warn',
|
|
22
|
+
'@typescript-eslint/dot-notation': 'warn',
|
|
23
|
+
'@typescript-eslint/lines-between-class-members': 'warn',
|
|
24
|
+
'@typescript-eslint/member-delimiter-style': 'warn',
|
|
25
|
+
'@typescript-eslint/naming-convention': 'warn',
|
|
26
|
+
'@typescript-eslint/no-empty-interface': 'warn',
|
|
27
|
+
'@typescript-eslint/no-for-in-array': 'warn',
|
|
28
|
+
'@typescript-eslint/no-loop-func': 'warn',
|
|
29
|
+
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
30
|
+
'@typescript-eslint/no-shadow': 'warn',
|
|
31
|
+
'@typescript-eslint/no-this-alias': 'warn',
|
|
32
|
+
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn',
|
|
33
|
+
'@typescript-eslint/no-unnecessary-type-assertion': 'warn',
|
|
34
|
+
'@typescript-eslint/no-unsafe-argument': 'warn',
|
|
35
|
+
'@typescript-eslint/no-unsafe-call': 'warn',
|
|
36
|
+
'@typescript-eslint/no-unsafe-return': 'warn',
|
|
37
|
+
'@typescript-eslint/no-unused-expressions': 'warn',
|
|
38
|
+
'@typescript-eslint/no-unused-vars': 'warn',
|
|
39
|
+
'@typescript-eslint/no-use-before-define': 'warn',
|
|
40
|
+
'@typescript-eslint/no-var-requires': 'warn',
|
|
41
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'warn',
|
|
42
|
+
'@typescript-eslint/prefer-optional-chain': 'warn',
|
|
43
|
+
'@typescript-eslint/restrict-plus-operands': 'warn',
|
|
44
|
+
'@typescript-eslint/unbound-method': 'warn',
|
|
45
|
+
'@typescript-eslint/ban-ts-comment': ['warn', { 'ts-ignore': true }],
|
|
46
|
+
'@typescript-eslint/no-redundant-type-constituents': 'warn',
|
|
47
|
+
'@typescript-eslint/no-base-to-string': 'warn',
|
|
48
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
49
|
+
'@typescript-eslint/no-unsafe-enum-comparison': 'warn',
|
|
50
|
+
},
|
|
51
|
+
};
|
package/.np-config.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { StorybookConfig } from '@storybook/vue3-vite';
|
|
2
|
+
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This function is used to resolve the absolute path of a package.
|
|
7
|
+
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
|
|
8
|
+
*/
|
|
9
|
+
function getAbsolutePath(value: string): any {
|
|
10
|
+
return dirname(require.resolve(join(value, 'package.json')));
|
|
11
|
+
}
|
|
12
|
+
const config: StorybookConfig = {
|
|
13
|
+
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
|
|
14
|
+
addons: [
|
|
15
|
+
getAbsolutePath('@storybook/addon-links'),
|
|
16
|
+
getAbsolutePath('@storybook/addon-essentials'),
|
|
17
|
+
getAbsolutePath('@storybook/addon-interactions'),
|
|
18
|
+
],
|
|
19
|
+
framework: {
|
|
20
|
+
name: getAbsolutePath('@storybook/vue3-vite'),
|
|
21
|
+
options: {},
|
|
22
|
+
},
|
|
23
|
+
docs: {
|
|
24
|
+
autodocs: 'tag',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
export default config;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Preview } from '@storybook/vue3';
|
|
2
|
+
import './preview.scss';
|
|
3
|
+
|
|
4
|
+
const preview: Preview = {
|
|
5
|
+
parameters: {
|
|
6
|
+
actions: { argTypesRegex: '^on[A-Z].*' },
|
|
7
|
+
controls: {
|
|
8
|
+
matchers: {
|
|
9
|
+
color: /(background|color)$/i,
|
|
10
|
+
date: /Date$/,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default preview;
|
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
This is an embeddable Chat widget for n8n. It allows the execution of AI-Powered Workflows through a Chat window.
|
|
3
3
|
|
|
4
4
|
## Prerequisites
|
|
5
|
-
Create a n8n workflow which you want to execute via chat. The workflow has to be triggered using a **
|
|
5
|
+
Create a n8n workflow which you want to execute via chat. The workflow has to be triggered using a **Webhook** node and return data using the **Respond to Webhook** node.
|
|
6
6
|
|
|
7
|
-
Open the **
|
|
7
|
+
Open the **Webhook** node and add your domain to the **Domain Allowlist** field. This makes sure that only requests from your domain are accepted.
|
|
8
8
|
|
|
9
9
|
[See example workflow](https://github.com/n8n-io/n8n/blob/master/packages/%40n8n/chat/resources/workflow.json)
|
|
10
10
|
|
|
@@ -17,6 +17,8 @@ Each request is accompanied by an `action` query parameter, where `action` can b
|
|
|
17
17
|
- `loadPreviousSession` - When the user opens the Chatbot again and the previous chat session should be loaded
|
|
18
18
|
- `sendMessage` - When the user sends a message
|
|
19
19
|
|
|
20
|
+
We use the `Switch` node to handle the different actions.
|
|
21
|
+
|
|
20
22
|
## Installation
|
|
21
23
|
|
|
22
24
|
Open the **Webhook** node and replace `YOUR_PRODUCTION_WEBHOOK_URL` with your production URL. This is the URL that the Chat widget will use to send requests to.
|
|
@@ -104,10 +106,6 @@ createChat({
|
|
|
104
106
|
},
|
|
105
107
|
target: '#n8n-chat',
|
|
106
108
|
mode: 'window',
|
|
107
|
-
chatInputKey: 'chatInput',
|
|
108
|
-
chatSessionKey: 'sessionId',
|
|
109
|
-
metadata: {},
|
|
110
|
-
showWelcomeScreen: false,
|
|
111
109
|
defaultLanguage: 'en',
|
|
112
110
|
initialMessages: [
|
|
113
111
|
'Hi there! 👋',
|
|
@@ -150,21 +148,6 @@ createChat({
|
|
|
150
148
|
- In `window` mode, the Chat window will be embedded in the target element as a chat toggle button and a fixed size chat window.
|
|
151
149
|
- In `fullscreen` mode, the Chat will take up the entire width and height of its target container.
|
|
152
150
|
|
|
153
|
-
### `showWelcomeScreen`
|
|
154
|
-
- **Type**: `boolean`
|
|
155
|
-
- **Default**: `false`
|
|
156
|
-
- **Description**: Whether to show the welcome screen when the Chat window is opened.
|
|
157
|
-
|
|
158
|
-
### `chatSessionKey`
|
|
159
|
-
- **Type**: `string`
|
|
160
|
-
- **Default**: `'sessionId'`
|
|
161
|
-
- **Description**: The key to use for sending the chat history session ID for the AI Memory node.
|
|
162
|
-
|
|
163
|
-
### `chatInputKey`
|
|
164
|
-
- **Type**: `string`
|
|
165
|
-
- **Default**: `'chatInput'`
|
|
166
|
-
- **Description**: The key to use for sending the chat input for the AI Agent node.
|
|
167
|
-
|
|
168
151
|
### `defaultLanguage`
|
|
169
152
|
- **Type**: `string`
|
|
170
153
|
- **Default**: `'en'`
|
package/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<link rel="icon" href="/favicon.ico">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Vite App</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n/chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"main": "./chat.umd.cjs",
|
|
5
5
|
"module": "./chat.es.js",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
@@ -14,70 +14,10 @@
|
|
|
14
14
|
"require": "./style.css"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
|
-
"dependencies": {
|
|
18
|
-
"highlight.js": "^11.8.0",
|
|
19
|
-
"uuid": "^8.3.2",
|
|
20
|
-
"vue": "^3.3.4",
|
|
21
|
-
"vue-markdown-render": "^2.0.1"
|
|
22
|
-
},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"@iconify-json/mdi": "^1.1.54",
|
|
25
|
-
"@rushstack/eslint-patch": "^1.3.2",
|
|
26
|
-
"@storybook/addon-essentials": "^7.4.0",
|
|
27
|
-
"@storybook/addon-interactions": "^7.4.0",
|
|
28
|
-
"@storybook/addon-links": "^7.4.0",
|
|
29
|
-
"@storybook/blocks": "^7.4.0",
|
|
30
|
-
"@storybook/testing-library": "^0.2.0",
|
|
31
|
-
"@storybook/vue3": "^7.4.0",
|
|
32
|
-
"@storybook/vue3-vite": "^7.4.0",
|
|
33
|
-
"@testing-library/jest-dom": "^5.17.0",
|
|
34
|
-
"@testing-library/vue": "^7.0.0",
|
|
35
|
-
"@tsconfig/node18": "^18.2.0",
|
|
36
|
-
"@types/jsdom": "^21.1.1",
|
|
37
|
-
"@types/markdown-it": "^12.2.3",
|
|
38
|
-
"@types/node": "^18.17.0",
|
|
39
|
-
"@vitejs/plugin-vue": "^4.2.3",
|
|
40
|
-
"@vue/eslint-config-prettier": "^8.0.0",
|
|
41
|
-
"@vue/eslint-config-typescript": "^11.0.3",
|
|
42
|
-
"@vue/test-utils": "^2.4.1",
|
|
43
|
-
"@vue/tsconfig": "^0.4.0",
|
|
44
|
-
"eslint": "^8.45.0",
|
|
45
|
-
"eslint-plugin-vue": "^9.15.1",
|
|
46
|
-
"jsdom": "^22.1.0",
|
|
47
|
-
"npm-run-all": "^4.1.5",
|
|
48
|
-
"prettier": "^3.0.0",
|
|
49
|
-
"react": "^18.2.0",
|
|
50
|
-
"react-dom": "^18.2.0",
|
|
51
|
-
"shelljs": "^0.8.5",
|
|
52
|
-
"storybook": "^7.4.0",
|
|
53
|
-
"typescript": "~5.1.6",
|
|
54
|
-
"unplugin-icons": "^0.17.0",
|
|
55
|
-
"vite": "^4.4.6",
|
|
56
|
-
"vite-plugin-dts": "^3.6.0",
|
|
57
|
-
"vitest": "^0.33.0",
|
|
58
|
-
"vue-tsc": "^1.8.6"
|
|
59
|
-
},
|
|
60
17
|
"repository": {
|
|
61
18
|
"type": "git",
|
|
62
19
|
"url": "git+https://github.com/n8n-io/n8n.git"
|
|
63
20
|
},
|
|
64
21
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
65
|
-
"homepage": "https://n8n.io"
|
|
66
|
-
"scripts": {
|
|
67
|
-
"dev": "pnpm run storybook",
|
|
68
|
-
"build": "run-p type-check build:vite && npm run build:prepare",
|
|
69
|
-
"build:vite": "vite build && npm run build:vite:full",
|
|
70
|
-
"build:vite:full": "INCLUDE_VUE=true vite build",
|
|
71
|
-
"build:prepare": "node scripts/postbuild.js",
|
|
72
|
-
"build:pack": "node scripts/pack.js",
|
|
73
|
-
"preview": "vite preview",
|
|
74
|
-
"test:dev": "vitest",
|
|
75
|
-
"test": "vitest run --coverage",
|
|
76
|
-
"type-check": "vue-tsc --noEmit -p tsconfig.json --composite false",
|
|
77
|
-
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore --ignore-path .eslintignore",
|
|
78
|
-
"format": "prettier --write src/",
|
|
79
|
-
"storybook": "storybook dev -p 6006 --no-open",
|
|
80
|
-
"build:storybook": "storybook build",
|
|
81
|
-
"release": "pnpm run build && cd dist && pnpm publish"
|
|
82
|
-
}
|
|
22
|
+
"homepage": "https://n8n.io"
|
|
83
23
|
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "AI Webhook Chat",
|
|
3
|
+
"nodes": [
|
|
4
|
+
{
|
|
5
|
+
"parameters": {
|
|
6
|
+
"httpMethod": "POST",
|
|
7
|
+
"path": "513107b3-6f3a-4a1e-af21-659f0ed14183",
|
|
8
|
+
"responseMode": "responseNode",
|
|
9
|
+
"options": {
|
|
10
|
+
"domainAllowlist": "*.localhost"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"id": "51ab2689-647d-4cff-9d6f-0ba4df45e904",
|
|
14
|
+
"name": "Webhook",
|
|
15
|
+
"type": "n8n-nodes-base.webhook",
|
|
16
|
+
"typeVersion": 1,
|
|
17
|
+
"position": [
|
|
18
|
+
900,
|
|
19
|
+
200
|
|
20
|
+
],
|
|
21
|
+
"webhookId": "513107b3-6f3a-4a1e-af21-659f0ed14183"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"parameters": {
|
|
25
|
+
"options": {}
|
|
26
|
+
},
|
|
27
|
+
"id": "3c7fd563-f610-41fa-b198-7fcf100e2815",
|
|
28
|
+
"name": "Chat OpenAI",
|
|
29
|
+
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
|
|
30
|
+
"typeVersion": 1,
|
|
31
|
+
"position": [
|
|
32
|
+
1720,
|
|
33
|
+
620
|
|
34
|
+
],
|
|
35
|
+
"credentials": {
|
|
36
|
+
"openAiApi": {
|
|
37
|
+
"id": "B5Fiv70Adfg6htxn",
|
|
38
|
+
"name": "Alex's OpenAI Account"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"parameters": {
|
|
44
|
+
"sessionKey": "={{ $json.body.sessionId }}"
|
|
45
|
+
},
|
|
46
|
+
"id": "ebc23ffa-3bcf-494f-bcb8-51a5fff91885",
|
|
47
|
+
"name": "Window Buffer Memory",
|
|
48
|
+
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
|
|
49
|
+
"typeVersion": 1,
|
|
50
|
+
"position": [
|
|
51
|
+
1920,
|
|
52
|
+
620
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"parameters": {
|
|
57
|
+
"simplifyOutput": false
|
|
58
|
+
},
|
|
59
|
+
"id": "d6721a60-159b-4a93-ac6b-b81e16d9f16f",
|
|
60
|
+
"name": "Memory Chat Retriever",
|
|
61
|
+
"type": "@n8n/n8n-nodes-langchain.memoryChatRetriever",
|
|
62
|
+
"typeVersion": 1,
|
|
63
|
+
"position": [
|
|
64
|
+
1780,
|
|
65
|
+
-40
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"parameters": {
|
|
70
|
+
"sessionKey": "={{ $json.body.sessionId }}"
|
|
71
|
+
},
|
|
72
|
+
"id": "347edc3a-1dda-4996-b778-dcdc447ecfd8",
|
|
73
|
+
"name": "Memory Chat Retriever Window Buffer Memory",
|
|
74
|
+
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
|
|
75
|
+
"typeVersion": 1,
|
|
76
|
+
"position": [
|
|
77
|
+
1800,
|
|
78
|
+
160
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"parameters": {
|
|
83
|
+
"options": {
|
|
84
|
+
"responseCode": 200,
|
|
85
|
+
"responseHeaders": {
|
|
86
|
+
"entries": [
|
|
87
|
+
{
|
|
88
|
+
"name": "sessionId",
|
|
89
|
+
"value": "={{ $json.body.sessionId }}"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "Access-Control-Allow-Headers",
|
|
93
|
+
"value": "*"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"id": "d229963e-e2f1-4381-87d2-47043bd6ccc7",
|
|
100
|
+
"name": "Respond to Webhook",
|
|
101
|
+
"type": "n8n-nodes-base.respondToWebhook",
|
|
102
|
+
"typeVersion": 1,
|
|
103
|
+
"position": [
|
|
104
|
+
2460,
|
|
105
|
+
220
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"parameters": {
|
|
110
|
+
"dataType": "string",
|
|
111
|
+
"value1": "={{ $json.body.action }}",
|
|
112
|
+
"rules": {
|
|
113
|
+
"rules": [
|
|
114
|
+
{
|
|
115
|
+
"value2": "loadPreviousSession"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"value2": "sendMessage",
|
|
119
|
+
"output": 1
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"id": "fc4ad994-5f38-4dce-b1e5-397acc512687",
|
|
125
|
+
"name": "Chatbot Action",
|
|
126
|
+
"type": "n8n-nodes-base.switch",
|
|
127
|
+
"typeVersion": 1,
|
|
128
|
+
"position": [
|
|
129
|
+
1320,
|
|
130
|
+
200
|
|
131
|
+
]
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"parameters": {
|
|
135
|
+
"jsCode": "const response = { data: [] };\n\nfor (const item of $input.all()) {\n response.data.push(item.json);\n}\n\nreturn {\n json: response,\n pairedItem: 0\n};"
|
|
136
|
+
},
|
|
137
|
+
"id": "e1a80bdc-411a-42df-88dd-36915b1ae8f4",
|
|
138
|
+
"name": "Code",
|
|
139
|
+
"type": "n8n-nodes-base.code",
|
|
140
|
+
"typeVersion": 2,
|
|
141
|
+
"position": [
|
|
142
|
+
2160,
|
|
143
|
+
-40
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"parameters": {
|
|
148
|
+
"text": "={{ $json.body.message }}",
|
|
149
|
+
"options": {}
|
|
150
|
+
},
|
|
151
|
+
"id": "f28f5c00-c742-41d5-8ddb-f0f59ab111a3",
|
|
152
|
+
"name": "Agent",
|
|
153
|
+
"type": "@n8n/n8n-nodes-langchain.agent",
|
|
154
|
+
"typeVersion": 1,
|
|
155
|
+
"position": [
|
|
156
|
+
1780,
|
|
157
|
+
340
|
|
158
|
+
]
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"parameters": {
|
|
162
|
+
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.body = JSON.parse(item.json.body);\n}\n\nreturn $input.all();"
|
|
163
|
+
},
|
|
164
|
+
"id": "415c071b-18b2-4ac5-8634-e3d939bf36ac",
|
|
165
|
+
"name": "Transform request body",
|
|
166
|
+
"type": "n8n-nodes-base.code",
|
|
167
|
+
"typeVersion": 2,
|
|
168
|
+
"position": [
|
|
169
|
+
1120,
|
|
170
|
+
200
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
"pinData": {},
|
|
175
|
+
"connections": {
|
|
176
|
+
"Webhook": {
|
|
177
|
+
"main": [
|
|
178
|
+
[
|
|
179
|
+
{
|
|
180
|
+
"node": "Transform request body",
|
|
181
|
+
"type": "main",
|
|
182
|
+
"index": 0
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
"Memory Chat Retriever": {
|
|
188
|
+
"main": [
|
|
189
|
+
[
|
|
190
|
+
{
|
|
191
|
+
"node": "Code",
|
|
192
|
+
"type": "main",
|
|
193
|
+
"index": 0
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
]
|
|
197
|
+
},
|
|
198
|
+
"Memory Chat Retriever Window Buffer Memory": {
|
|
199
|
+
"ai_memory": [
|
|
200
|
+
[
|
|
201
|
+
{
|
|
202
|
+
"node": "Memory Chat Retriever",
|
|
203
|
+
"type": "ai_memory",
|
|
204
|
+
"index": 0
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
"Chatbot Action": {
|
|
210
|
+
"main": [
|
|
211
|
+
[
|
|
212
|
+
{
|
|
213
|
+
"node": "Memory Chat Retriever",
|
|
214
|
+
"type": "main",
|
|
215
|
+
"index": 0
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
[
|
|
219
|
+
{
|
|
220
|
+
"node": "Agent",
|
|
221
|
+
"type": "main",
|
|
222
|
+
"index": 0
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
"Code": {
|
|
228
|
+
"main": [
|
|
229
|
+
[
|
|
230
|
+
{
|
|
231
|
+
"node": "Respond to Webhook",
|
|
232
|
+
"type": "main",
|
|
233
|
+
"index": 0
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
]
|
|
237
|
+
},
|
|
238
|
+
"Chat OpenAI": {
|
|
239
|
+
"ai_languageModel": [
|
|
240
|
+
[
|
|
241
|
+
{
|
|
242
|
+
"node": "Agent",
|
|
243
|
+
"type": "ai_languageModel",
|
|
244
|
+
"index": 0
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
"Window Buffer Memory": {
|
|
250
|
+
"ai_memory": [
|
|
251
|
+
[
|
|
252
|
+
{
|
|
253
|
+
"node": "Agent",
|
|
254
|
+
"type": "ai_memory",
|
|
255
|
+
"index": 0
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
"Agent": {
|
|
261
|
+
"main": [
|
|
262
|
+
[
|
|
263
|
+
{
|
|
264
|
+
"node": "Respond to Webhook",
|
|
265
|
+
"type": "main",
|
|
266
|
+
"index": 0
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
]
|
|
270
|
+
},
|
|
271
|
+
"Transform request body": {
|
|
272
|
+
"main": [
|
|
273
|
+
[
|
|
274
|
+
{
|
|
275
|
+
"node": "Chatbot Action",
|
|
276
|
+
"type": "main",
|
|
277
|
+
"index": 0
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"active": true,
|
|
284
|
+
"settings": {
|
|
285
|
+
"executionOrder": "v1"
|
|
286
|
+
},
|
|
287
|
+
"versionId": "12c145a2-74bf-48b5-a87a-ba707949eaed",
|
|
288
|
+
"id": "L3FlJuFOxZcHtoFT",
|
|
289
|
+
"meta": {
|
|
290
|
+
"instanceId": "374b43d8b8d6299cc777811a4ad220fc688ee2d54a308cfb0de4450a5233ca9e"
|
|
291
|
+
},
|
|
292
|
+
"tags": []
|
|
293
|
+
}
|
package/scripts/pack.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const shelljs = require('shelljs');
|
|
3
|
+
|
|
4
|
+
const rootDirPath = path.resolve(__dirname, '..');
|
|
5
|
+
const distDirPath = path.resolve(rootDirPath, 'dist');
|
|
6
|
+
|
|
7
|
+
shelljs.cd(rootDirPath);
|
|
8
|
+
shelljs.exec('npm run build');
|
|
9
|
+
|
|
10
|
+
shelljs.cd(distDirPath);
|
|
11
|
+
shelljs.exec('npm pack');
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const shelljs = require('shelljs');
|
|
3
|
+
|
|
4
|
+
const rootDirPath = path.resolve(__dirname, '..');
|
|
5
|
+
const n8nRootDirPath = path.resolve(rootDirPath, '..', '..', '..');
|
|
6
|
+
const distDirPath = path.resolve(rootDirPath, 'dist');
|
|
7
|
+
|
|
8
|
+
const packageJsonFilePath = path.resolve(rootDirPath, 'package.json');
|
|
9
|
+
const readmeFilePath = path.resolve(rootDirPath, 'README.md');
|
|
10
|
+
const licenseFilePath = path.resolve(n8nRootDirPath, 'LICENSE.md');
|
|
11
|
+
|
|
12
|
+
shelljs.cp(packageJsonFilePath, distDirPath);
|
|
13
|
+
shelljs.cp(readmeFilePath, distDirPath);
|
|
14
|
+
shelljs.cp(licenseFilePath, distDirPath);
|
|
15
|
+
|
|
16
|
+
shelljs.mv(path.resolve(distDirPath, 'src'), path.resolve(distDirPath, 'types'));
|
package/src/App.vue
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Chat, ChatWindow } from '@/components';
|
|
3
|
+
import { computed, onMounted } from 'vue';
|
|
4
|
+
import hljs from 'highlight.js/lib/core';
|
|
5
|
+
import hljsXML from 'highlight.js/lib/languages/xml';
|
|
6
|
+
import hljsJavascript from 'highlight.js/lib/languages/javascript';
|
|
7
|
+
import { useOptions } from '@/composables';
|
|
8
|
+
|
|
9
|
+
defineProps({});
|
|
10
|
+
|
|
11
|
+
const { options } = useOptions();
|
|
12
|
+
|
|
13
|
+
const isFullscreen = computed<boolean>(() => options.mode === 'fullscreen');
|
|
14
|
+
|
|
15
|
+
onMounted(() => {
|
|
16
|
+
hljs.registerLanguage('xml', hljsXML);
|
|
17
|
+
hljs.registerLanguage('javascript', hljsJavascript);
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
<template>
|
|
21
|
+
<Chat v-if="isFullscreen" class="n8n-chat" />
|
|
22
|
+
<ChatWindow v-else class="n8n-chat" />
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
|
+
import type { StoryObj } from '@storybook/vue3';
|
|
3
|
+
import type { ChatOptions } from '@/types';
|
|
4
|
+
import { createChat } from '@/index';
|
|
5
|
+
import { onMounted } from 'vue';
|
|
6
|
+
|
|
7
|
+
const webhookUrl = 'http://localhost:5678/webhook/513107b3-6f3a-4a1e-af21-659f0ed14183';
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Chat',
|
|
11
|
+
render: (args: Partial<ChatOptions>) => ({
|
|
12
|
+
setup() {
|
|
13
|
+
onMounted(() => {
|
|
14
|
+
createChat(args);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return {};
|
|
18
|
+
},
|
|
19
|
+
template: '<div id="n8n-chat" />',
|
|
20
|
+
}),
|
|
21
|
+
parameters: {
|
|
22
|
+
layout: 'fullscreen',
|
|
23
|
+
},
|
|
24
|
+
tags: ['autodocs'],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line import/no-default-export
|
|
28
|
+
export default meta;
|
|
29
|
+
type Story = StoryObj<typeof meta>;
|
|
30
|
+
|
|
31
|
+
export const Fullscreen: Story = {
|
|
32
|
+
args: {
|
|
33
|
+
webhookUrl,
|
|
34
|
+
mode: 'fullscreen',
|
|
35
|
+
} satisfies Partial<ChatOptions>,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const Windowed: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
webhookUrl,
|
|
41
|
+
mode: 'window',
|
|
42
|
+
} satisfies Partial<ChatOptions>,
|
|
43
|
+
};
|