@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.
Files changed (104) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.cjs +51 -0
  3. package/.np-config.json +5 -0
  4. package/.storybook/main.ts +27 -0
  5. package/.storybook/preview.scss +4 -0
  6. package/.storybook/preview.ts +16 -0
  7. package/.vscode/extensions.json +3 -0
  8. package/README.md +4 -21
  9. package/env.d.ts +1 -0
  10. package/index.html +13 -0
  11. package/package.json +2 -62
  12. package/resources/workflow.json +293 -0
  13. package/scripts/pack.js +11 -0
  14. package/scripts/postbuild.js +16 -0
  15. package/src/App.vue +23 -0
  16. package/src/__stories__/App.stories.ts +43 -0
  17. package/src/__tests__/index.spec.ts +223 -0
  18. package/src/__tests__/setup.ts +1 -0
  19. package/src/__tests__/utils/create.ts +16 -0
  20. package/src/__tests__/utils/fetch.ts +18 -0
  21. package/src/__tests__/utils/selectors.ts +53 -0
  22. package/src/api/generic.ts +64 -0
  23. package/src/api/message.ts +31 -0
  24. package/src/components/Button.vue +41 -0
  25. package/src/components/Chat.vue +48 -0
  26. package/src/components/ChatWindow.vue +125 -0
  27. package/src/components/GetStarted.vue +24 -0
  28. package/src/components/GetStartedFooter.vue +20 -0
  29. package/src/components/Input.vue +93 -0
  30. package/src/components/Layout.vue +82 -0
  31. package/src/components/Message.vue +97 -0
  32. package/src/components/MessageTyping.vue +109 -0
  33. package/src/components/MessagesList.vue +37 -0
  34. package/src/components/PoweredBy.vue +17 -0
  35. package/src/composables/useChat.ts +7 -0
  36. package/src/composables/useI18n.ts +16 -0
  37. package/src/composables/useOptions.ts +11 -0
  38. package/src/constants/defaults.ts +25 -0
  39. package/src/constants/localStorage.ts +2 -0
  40. package/src/constants/symbols.ts +8 -0
  41. package/src/event-buses/chatEventBus.ts +3 -0
  42. package/src/index.ts +42 -0
  43. package/src/main.scss +40 -0
  44. package/src/plugins/chat.ts +101 -0
  45. package/src/shims.d.ts +6 -0
  46. package/src/types/chat.ts +12 -0
  47. package/src/types/messages.ts +6 -0
  48. package/src/types/options.ts +23 -0
  49. package/src/types/webhook.ts +17 -0
  50. package/src/utils/event-bus.ts +51 -0
  51. package/src/utils/mount.ts +16 -0
  52. package/tsconfig.json +27 -0
  53. package/vite.config.ts +51 -0
  54. package/vitest.config.ts +20 -0
  55. package/chat.bundle.es.js +0 -10760
  56. package/chat.bundle.umd.js +0 -18
  57. package/chat.es.js +0 -6870
  58. package/chat.umd.js +0 -18
  59. package/style.css +0 -1
  60. package/types/App.vue.d.ts +0 -8
  61. package/types/__stories__/App.stories.d.ts +0 -17
  62. package/types/__tests__/index.spec.d.ts +0 -1
  63. package/types/__tests__/setup.d.ts +0 -0
  64. package/types/__tests__/utils/create.d.ts +0 -5
  65. package/types/__tests__/utils/fetch.d.ts +0 -4
  66. package/types/__tests__/utils/selectors.d.ts +0 -12
  67. package/types/api/generic.d.ts +0 -6
  68. package/types/api/message.d.ts +0 -3
  69. package/types/components/Button.vue.d.ts +0 -9
  70. package/types/components/Chat.vue.d.ts +0 -2
  71. package/types/components/ChatWindow.vue.d.ts +0 -2
  72. package/types/components/GetStarted.vue.d.ts +0 -2
  73. package/types/components/GetStartedFooter.vue.d.ts +0 -2
  74. package/types/components/Input.vue.d.ts +0 -2
  75. package/types/components/Layout.vue.d.ts +0 -11
  76. package/types/components/Message.vue.d.ts +0 -21
  77. package/types/components/MessageTyping.vue.d.ts +0 -15
  78. package/types/components/MessagesList.vue.d.ts +0 -14
  79. package/types/components/PoweredBy.vue.d.ts +0 -2
  80. package/types/composables/useChat.d.ts +0 -2
  81. package/types/composables/useI18n.d.ts +0 -4
  82. package/types/composables/useOptions.d.ts +0 -4
  83. package/types/constants/defaults.d.ts +0 -3
  84. package/types/constants/localStorage.d.ts +0 -2
  85. package/types/constants/symbols.d.ts +0 -4
  86. package/types/event-buses/chatEventBus.d.ts +0 -1
  87. package/types/index.d.ts +0 -2
  88. package/types/plugins/chat.d.ts +0 -3
  89. package/types/types/chat.d.ts +0 -11
  90. package/types/types/messages.d.ts +0 -6
  91. package/types/types/options.d.ts +0 -25
  92. package/types/types/webhook.d.ts +0 -15
  93. package/types/utils/event-bus.d.ts +0 -8
  94. package/types/utils/mount.d.ts +0 -1
  95. /package/{favicon.ico → public/favicon.ico} +0 -0
  96. /package/{types/__tests__/utils/index.d.ts → src/__tests__/utils/index.ts} +0 -0
  97. /package/{types/api/index.d.ts → src/api/index.ts} +0 -0
  98. /package/{types/components/index.d.ts → src/components/index.ts} +0 -0
  99. /package/{types/composables/index.d.ts → src/composables/index.ts} +0 -0
  100. /package/{types/constants/index.d.ts → src/constants/index.ts} +0 -0
  101. /package/{types/event-buses/index.d.ts → src/event-buses/index.ts} +0 -0
  102. /package/{types/plugins/index.d.ts → src/plugins/index.ts} +0 -0
  103. /package/{types/types/index.d.ts → src/types/index.ts} +0 -0
  104. /package/{types/utils/index.d.ts → src/utils/index.ts} +0 -0
package/.eslintignore ADDED
@@ -0,0 +1,2 @@
1
+ .eslintrc.cjs
2
+ vitest.config.ts
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
+ };
@@ -0,0 +1,5 @@
1
+ {
2
+ "yarn": false,
3
+ "tests": false,
4
+ "contents": "./dist"
5
+ }
@@ -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,4 @@
1
+ html, body, #storybook-root, #n8n-chat {
2
+ width: 100%;
3
+ height: 100%;
4
+ }
@@ -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;
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
3
+ }
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 **Chat Trigger** node.
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 **Chat Trigger** node and add your domain to the **Allowed Origins (CORS)** field. This makes sure that only requests from your domain are accepted.
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.5.1",
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
+ }
@@ -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
+ };