@5minds/node-red-dashboard-2-processcube-chat 0.1.1-add-functionality-94845a-me8hect9 → 0.1.1-develop-e94793-mcvyrm7g

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.
@@ -1,95 +1,110 @@
1
1
  <script type="text/javascript">
2
2
  RED.nodes.registerType('ui-deepchat', {
3
- category: 'ProcessCube AI Chat',
3
+ category: 'dashboard',
4
4
  color: '#00D2B8',
5
5
  defaults: {
6
- group: { type: 'ui-group', required: true },
7
- name: { value: '' },
6
+ group: { type: "ui-group", required: true },
7
+ name: { value: "" },
8
8
  order: { value: 0 },
9
9
  width: { value: 6 },
10
10
  height: { value: 8 },
11
11
  // Deep Chat Konfiguration
12
- introMessage: { value: 'Hello! How can I help you today?' },
13
- placeholder: { value: 'Type a message...' },
14
- model: { value: 'gpt-3.5-turbo' },
12
+ introMessage: { value: "Hello! How can I help you today?" },
13
+ placeholder: { value: "Type a message..." },
14
+ apiUrl: { value: "" },
15
+ apiKey: { value: "" },
16
+ model: { value: "gpt-3.5-turbo" },
15
17
  // Features
18
+ textInput: { value: true },
16
19
  speechToText: { value: false },
17
20
  camera: { value: false },
21
+ microphone: { value: false },
18
22
  attachments: { value: false },
19
23
  // Styling
20
24
  avatars: { value: true },
21
25
  names: { value: true },
22
26
  timestamps: { value: false },
23
- stream: { value: false },
27
+ stream: { value: false }
24
28
  },
25
29
  inputs: 1,
26
30
  outputs: 1,
27
- icon: 'ui_chat.png',
28
- paletteLabel: 'deep chat',
29
- label: function () {
30
- return this.name || 'Deep Chat';
31
+ icon: "ui_chat.png",
32
+ paletteLabel: "deep chat",
33
+ label: function() {
34
+ return this.name || "Deep Chat";
31
35
  },
32
- labelStyle: function () {
33
- return this.name ? 'node_label_italic' : '';
36
+ labelStyle: function() {
37
+ return this.name ? "node_label_italic" : "";
34
38
  },
35
- oneditprepare: function () {
36
- $('#node-input-width').typedInput({
37
- type: 'num',
38
- types: ['num'],
39
- typeField: '#node-input-width-type',
39
+ oneditprepare: function() {
40
+ $("#node-input-width").typedInput({
41
+ type: "num",
42
+ types: ["num"],
43
+ typeField: "#node-input-width-type"
40
44
  });
41
- $('#node-input-height').typedInput({
42
- type: 'num',
43
- types: ['num'],
44
- typeField: '#node-input-height-type',
45
+ $("#node-input-height").typedInput({
46
+ type: "num",
47
+ types: ["num"],
48
+ typeField: "#node-input-height-type"
45
49
  });
46
- },
50
+ }
47
51
  });
48
52
  </script>
49
53
 
50
54
  <script type="text/html" data-template-name="ui-deepchat">
51
55
  <div class="form-row">
52
56
  <label for="node-input-group"><i class="fa fa-table"></i> Group</label>
53
- <input type="text" id="node-input-group" />
57
+ <input type="text" id="node-input-group">
54
58
  </div>
55
-
59
+
56
60
  <div class="form-row">
57
61
  <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
58
- <input type="text" id="node-input-name" placeholder="Deep Chat" />
62
+ <input type="text" id="node-input-name" placeholder="Deep Chat">
59
63
  </div>
60
-
64
+
61
65
  <div class="form-row">
62
66
  <label for="node-input-order"><i class="fa fa-sort"></i> Order</label>
63
- <input type="number" id="node-input-order" placeholder="0" min="0" />
67
+ <input type="number" id="node-input-order" placeholder="0" min="0">
64
68
  </div>
65
-
69
+
66
70
  <div class="form-row">
67
71
  <label for="node-input-width"><i class="fa fa-resize-horizontal"></i> Width</label>
68
- <input type="hidden" id="node-input-width-type" />
69
- <input type="text" id="node-input-width" placeholder="6" />
72
+ <input type="hidden" id="node-input-width-type">
73
+ <input type="text" id="node-input-width" placeholder="6">
70
74
  </div>
71
-
75
+
72
76
  <div class="form-row">
73
77
  <label for="node-input-height"><i class="fa fa-resize-vertical"></i> Height</label>
74
- <input type="hidden" id="node-input-height-type" />
75
- <input type="text" id="node-input-height" placeholder="8" />
78
+ <input type="hidden" id="node-input-height-type">
79
+ <input type="text" id="node-input-height" placeholder="8">
76
80
  </div>
77
-
78
- <hr />
81
+
82
+ <hr>
79
83
  <h4>Chat Configuration</h4>
80
-
84
+
81
85
  <div class="form-row">
82
86
  <label for="node-input-introMessage"><i class="fa fa-comment"></i> Intro Message</label>
83
- <input type="text" id="node-input-introMessage" placeholder="Hello! How can I help you today?" />
87
+ <input type="text" id="node-input-introMessage" placeholder="Hello! How can I help you today?">
84
88
  </div>
85
-
89
+
86
90
  <div class="form-row">
87
91
  <label for="node-input-placeholder"><i class="fa fa-edit"></i> Placeholder</label>
88
- <input type="text" id="node-input-placeholder" placeholder="Type a message..." />
92
+ <input type="text" id="node-input-placeholder" placeholder="Type a message...">
89
93
  </div>
90
-
91
- <hr />
94
+
95
+ <hr>
92
96
  <h4>API Configuration</h4>
97
+
98
+ <div class="form-row">
99
+ <label for="node-input-apiUrl"><i class="fa fa-link"></i> API URL</label>
100
+ <input type="text" id="node-input-apiUrl" placeholder="https://api.openai.com/v1/chat/completions">
101
+ </div>
102
+
103
+ <div class="form-row">
104
+ <label for="node-input-apiKey"><i class="fa fa-key"></i> API Key</label>
105
+ <input type="password" id="node-input-apiKey" placeholder="sk-...">
106
+ </div>
107
+
93
108
  <div class="form-row">
94
109
  <label for="node-input-model"><i class="fa fa-cog"></i> Model</label>
95
110
  <select id="node-input-model">
@@ -97,110 +112,113 @@
97
112
  <option value="gpt-4">GPT-4</option>
98
113
  <option value="gpt-4-turbo">GPT-4 Turbo</option>
99
114
  <option value="claude-3-sonnet">Claude 3 Sonnet</option>
100
- <option value="llama3">LLAMA 3</option>
101
- <option value="gpt-4.1-mini">GPT-4.1 Mini</option>
102
- <option value="llama3.2-vision">LLAMA 3.2 Vision</option>
103
- <option value="gemma3:12b">Gemma 3</option>
104
- <option value="qwen2.5vl">Qwen 2.5vl</option>
105
- <option value="deepseek-r1:14b">DeepSeek-R1</option>
106
- <option value="mistral-small3.1">Mistral 3.1 Small</option>
107
115
  <option value="custom">Custom</option>
108
116
  </select>
109
117
  </div>
110
-
111
- <hr />
118
+
119
+ <hr>
112
120
  <h4>Features</h4>
113
-
121
+
122
+ <div class="form-row">
123
+ <input type="checkbox" id="node-input-textInput" style="width:auto;">
124
+ <label for="node-input-textInput" style="width:auto;"> Text Input</label>
125
+ </div>
126
+
114
127
  <div class="form-row">
115
- <input type="checkbox" id="node-input-speechToText" style="width:auto;" />
128
+ <input type="checkbox" id="node-input-speechToText" style="width:auto;">
116
129
  <label for="node-input-speechToText" style="width:auto;"> Speech to Text</label>
117
130
  </div>
118
-
131
+
119
132
  <div class="form-row">
120
- <input type="checkbox" id="node-input-camera" style="width:auto;" />
133
+ <input type="checkbox" id="node-input-camera" style="width:auto;">
121
134
  <label for="node-input-camera" style="width:auto;"> Camera</label>
122
135
  </div>
123
-
136
+
137
+ <div class="form-row">
138
+ <input type="checkbox" id="node-input-microphone" style="width:auto;">
139
+ <label for="node-input-microphone" style="width:auto;"> Microphone</label>
140
+ </div>
141
+
124
142
  <div class="form-row">
125
- <input type="checkbox" id="node-input-attachments" style="width:auto;" />
143
+ <input type="checkbox" id="node-input-attachments" style="width:auto;">
126
144
  <label for="node-input-attachments" style="width:auto;"> File Attachments</label>
127
145
  </div>
128
-
129
- <hr />
146
+
147
+ <hr>
130
148
  <h4>Appearance</h4>
131
-
149
+
132
150
  <div class="form-row">
133
- <input type="checkbox" id="node-input-avatars" style="width:auto;" />
151
+ <input type="checkbox" id="node-input-avatars" style="width:auto;">
134
152
  <label for="node-input-avatars" style="width:auto;"> Show Avatars</label>
135
153
  </div>
136
-
154
+
137
155
  <div class="form-row">
138
- <input type="checkbox" id="node-input-names" style="width:auto;" />
156
+ <input type="checkbox" id="node-input-names" style="width:auto;">
139
157
  <label for="node-input-names" style="width:auto;"> Show Names</label>
140
158
  </div>
141
-
159
+
142
160
  <div class="form-row">
143
- <input type="checkbox" id="node-input-timestamps" style="width:auto;" />
161
+ <input type="checkbox" id="node-input-timestamps" style="width:auto;">
144
162
  <label for="node-input-timestamps" style="width:auto;"> Show Timestamps</label>
145
163
  </div>
146
-
164
+
147
165
  <div class="form-row">
148
- <input type="checkbox" id="node-input-stream" style="width:auto;" />
166
+ <input type="checkbox" id="node-input-stream" style="width:auto;">
149
167
  <label for="node-input-stream" style="width:auto;"> Stream Responses</label>
150
168
  </div>
151
169
  </script>
152
170
 
153
171
  <script type="text/html" data-help-name="ui-deepchat">
154
172
  <p>Deep Chat integration für Node-RED Dashboard 2.0</p>
155
-
173
+
156
174
  <h3>Eigenschaften</h3>
157
175
  <dl class="message-properties">
158
176
  <dt>Group <span class="property-type">ui-group</span></dt>
159
177
  <dd>Dashboard-Gruppe, zu der dieses Widget gehört</dd>
160
-
178
+
161
179
  <dt>Width/Height <span class="property-type">number</span></dt>
162
180
  <dd>Breite und Höhe des Widgets im Dashboard</dd>
163
-
181
+
164
182
  <dt>Intro Message <span class="property-type">string</span></dt>
165
183
  <dd>Willkommensnachricht beim Laden des Chats</dd>
166
-
184
+
167
185
  <dt>API Configuration <span class="property-type">object</span></dt>
168
186
  <dd>URL, API-Schlüssel und Modell für AI-Service</dd>
169
187
  </dl>
170
-
188
+
171
189
  <h3>Eingabe</h3>
172
190
  <dl class="message-properties">
173
191
  <dt>payload <span class="property-type">string | object</span></dt>
174
192
  <dd>Nachricht, die als AI-Antwort im Chat angezeigt wird</dd>
175
-
193
+
176
194
  <dt>role <span class="property-type">string</span></dt>
177
195
  <dd>"ai", "user" oder "system" - bestimmt Darstellung der Nachricht</dd>
178
-
196
+
179
197
  <dt>html <span class="property-type">boolean</span></dt>
180
198
  <dd>Wenn true, wird payload als HTML gerendert</dd>
181
-
199
+
182
200
  <dt>config <span class="property-type">object</span></dt>
183
201
  <dd>Aktualisiert Chat-Konfiguration zur Laufzeit</dd>
184
-
202
+
185
203
  <dt>clear <span class="property-type">boolean</span></dt>
186
204
  <dd>Wenn true, wird Chat-Verlauf gelöscht</dd>
187
205
  </dl>
188
-
206
+
189
207
  <h3>Ausgabe</h3>
190
208
  <dl class="message-properties">
191
209
  <dt>payload <span class="property-type">string</span></dt>
192
210
  <dd>Benutzer-Nachricht aus dem Chat</dd>
193
-
211
+
194
212
  <dt>topic <span class="property-type">string</span></dt>
195
213
  <dd>"user-message", "new-message", "clear-messages" oder "component-render"</dd>
196
-
214
+
197
215
  <dt>role <span class="property-type">string</span></dt>
198
216
  <dd>Rolle des Nachrichtensenders</dd>
199
-
217
+
200
218
  <dt>_socketId <span class="property-type">string</span></dt>
201
219
  <dd>Eindeutige ID der Dashboard-Verbindung</dd>
202
220
  </dl>
203
-
221
+
204
222
  <h3>Funktionen</h3>
205
223
  <ul>
206
224
  <li>Vollständig anpassbare AI-Chat-Oberfläche</li>
@@ -210,10 +228,7 @@
210
228
  <li>Anpassbare Themes und Styling</li>
211
229
  <li>Event-System für Deep Integration</li>
212
230
  </ul>
213
-
231
+
214
232
  <h3>Beispiel-Flow</h3>
215
- <p>
216
- Verbinden Sie den Ausgang mit einem AI-Service (OpenAI, Anthropic, etc.) und senden Sie die Antwort zurück an
217
- den Eingang.
218
- </p>
219
- </script>
233
+ <p>Verbinden Sie den Ausgang mit einem AI-Service (OpenAI, Anthropic, etc.) und senden Sie die Antwort zurück an den Eingang.</p>
234
+ </script>
@@ -1,25 +1,138 @@
1
- module.exports = function (RED) {
1
+ module.exports = function(RED) {
2
2
  function UIDeepChatNode(config) {
3
3
  RED.nodes.createNode(this, config);
4
-
4
+
5
5
  const node = this;
6
-
7
6
  const group = RED.nodes.getNode(config.group);
8
-
7
+
9
8
  if (!group) {
10
- throw new Error('ui-deepchat must have a group');
9
+ throw new Error("ui-deepchat must have a group");
11
10
  }
12
-
11
+
12
+ // Konfiguration für Deep Chat
13
+ const deepChatConfig = {
14
+ // Basic config
15
+ introMessage: config.introMessage || '',
16
+ placeholder: config.placeholder || 'Type a message...',
17
+ // API Connection
18
+ apiUrl: config.apiUrl || '',
19
+ apiKey: config.apiKey || '',
20
+ model: config.model || 'gpt-3.5-turbo',
21
+ // Features
22
+ textInput: config.textInput !== false,
23
+ speechToText: config.speechToText || false,
24
+ camera: config.camera || false,
25
+ microphone: config.microphone || false,
26
+ attachments: config.attachments || false,
27
+ // Styling
28
+ avatars: config.avatars || true,
29
+ names: config.names || true,
30
+ timestamps: config.timestamps || false,
31
+ submitButtonStyles: config.submitButtonStyles || {},
32
+ // Advanced
33
+ stream: config.stream || false,
34
+ history: config.history || []
35
+ };
36
+
37
+ // Event handlers für Socket-Kommunikation
13
38
  const evts = {
14
39
  onAction: true,
40
+ onInput: function (msg, send) {
41
+ // Input von Dashboard zu Node-RED
42
+ if (msg.payload) {
43
+ send(msg);
44
+ }
45
+ },
46
+ beforeSend: function (msg) {
47
+ // Daten von Node-RED zu Dashboard vorbereiten
48
+ if (msg.payload) {
49
+ const update = {
50
+ msg: msg.payload,
51
+ timestamp: new Date().toISOString(),
52
+ ...msg
53
+ };
54
+ return { msg: update };
55
+ }
56
+ return { msg };
57
+ },
58
+ onSocket: {
59
+ // Chat-Message von Frontend zu Node-RED
60
+ 'chat-message': function (conn, id, msg) {
61
+ node.send({
62
+ payload: msg,
63
+ topic: 'user-message',
64
+ _socketId: conn.id
65
+ });
66
+ },
67
+ // Antwort von Node-RED zu Frontend
68
+ 'chat-response': function (conn, id, msg) {
69
+ // Antwort wird automatisch an Frontend gesendet
70
+ },
71
+ // Deep Chat Events
72
+ 'deepchat-onNewMessage': function (conn, id, data) {
73
+ node.send({
74
+ payload: data.message,
75
+ topic: 'new-message',
76
+ role: data.role,
77
+ _socketId: conn.id
78
+ });
79
+ },
80
+ 'deepchat-onClearMessages': function (conn, id, data) {
81
+ node.send({
82
+ payload: null,
83
+ topic: 'clear-messages',
84
+ _socketId: conn.id
85
+ });
86
+ },
87
+ 'deepchat-onComponentRender': function (conn, id, data) {
88
+ node.send({
89
+ payload: data,
90
+ topic: 'component-render',
91
+ _socketId: conn.id
92
+ });
93
+ }
94
+ }
15
95
  };
16
-
17
- group.register(node, { ...config, passthru: false }, evts);
18
-
19
- node.on('close', function () {
96
+
97
+ // Widget bei Dashboard registrieren
98
+ group.register(node, config, evts);
99
+
100
+ // Node-RED Input Handler
101
+ node.on('input', function(msg) {
102
+ // Nachricht an Dashboard senden
103
+ if (msg.payload) {
104
+ const update = {
105
+ message: msg.payload,
106
+ role: msg.role || 'ai',
107
+ html: msg.html || false,
108
+ files: msg.files || [],
109
+ timestamp: new Date().toISOString()
110
+ };
111
+
112
+ // An alle verbundenen Clients senden
113
+ group.emit('deepchat-newMessage', node.id, update);
114
+ }
115
+
116
+ // Konfiguration updaten
117
+ if (msg.config) {
118
+ const configUpdate = {
119
+ ...deepChatConfig,
120
+ ...msg.config
121
+ };
122
+ group.emit('deepchat-updateConfig', node.id, configUpdate);
123
+ }
124
+
125
+ // Chat löschen
126
+ if (msg.clear === true) {
127
+ group.emit('deepchat-clearMessages', node.id, {});
128
+ }
129
+ });
130
+
131
+ // Cleanup
132
+ node.on('close', function() {
20
133
  group.deregister(node);
21
134
  });
22
135
  }
23
-
24
- RED.nodes.registerType('ui-deepchat', UIDeepChatNode);
25
- };
136
+
137
+ RED.nodes.registerType("ui-deepchat", UIDeepChatNode);
138
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-dashboard-2-processcube-chat",
3
- "version": "0.1.1-add-functionality-94845a-me8hect9",
3
+ "version": "0.1.1-develop-e94793-mcvyrm7g",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {