@5minds/node-red-dashboard-2-processcube-chat 0.1.1-add-functionality-94845a-me8hect9 → 0.1.1-develop-bd0cb7-mcvkuzxr
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/nodes/ui-deepchat.html +102 -87
- package/nodes/ui-deepchat.js +126 -13
- package/package.json +1 -2
- package/resources/ui-deepchat.umd.js +2 -273
- package/ui/components/UIDeepChat.vue +297 -322
- package/resources/ui-deepchat.umd.js.map +0 -1
|
@@ -1,374 +1,349 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
2
|
+
<div ref="deepChatContainer" class="ui-deepchat-container" :style="containerStyle">
|
|
3
3
|
<deep-chat
|
|
4
|
-
|
|
5
|
-
:
|
|
6
|
-
:
|
|
4
|
+
ref="deepChat"
|
|
5
|
+
:intro-message="config.introMessage"
|
|
6
|
+
:placeholder-text="config.placeholder"
|
|
7
|
+
:text-input="config.textInput"
|
|
8
|
+
:speech-to-text="speechToTextConfig"
|
|
9
|
+
:camera="cameraConfig"
|
|
10
|
+
:microphone="microphoneConfig"
|
|
11
|
+
:mixedFiles="attachmentsConfig"
|
|
12
|
+
:avatars="config.avatars"
|
|
13
|
+
:names="config.names"
|
|
14
|
+
:timestamps="config.timestamps"
|
|
15
|
+
:stream="config.stream"
|
|
7
16
|
:connect="connectConfig"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
:timestamps="props.timestamps"
|
|
14
|
-
:stream="props.stream"
|
|
17
|
+
@onNewMessage="handleNewMessage"
|
|
18
|
+
@onClearMessages="handleClearMessages"
|
|
19
|
+
@onComponentRender="handleComponentRender"
|
|
20
|
+
@onResponse="handleResponse"
|
|
21
|
+
@onError="handleError"
|
|
15
22
|
></deep-chat>
|
|
16
23
|
</div>
|
|
17
24
|
</template>
|
|
18
25
|
|
|
19
26
|
<script>
|
|
20
|
-
import 'deep-chat';
|
|
21
|
-
|
|
22
27
|
export default {
|
|
23
28
|
name: 'UIDeepChat',
|
|
24
29
|
props: ['id', 'props', 'state'],
|
|
25
|
-
|
|
30
|
+
|
|
26
31
|
data() {
|
|
27
32
|
return {
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
config: {
|
|
34
|
+
introMessage: 'Hello! How can I help you today?',
|
|
35
|
+
placeholder: 'Type a message...',
|
|
36
|
+
apiUrl: '',
|
|
37
|
+
apiKey: '',
|
|
38
|
+
model: 'gpt-3.5-turbo',
|
|
39
|
+
textInput: true,
|
|
40
|
+
speechToText: false,
|
|
41
|
+
camera: false,
|
|
42
|
+
microphone: false,
|
|
43
|
+
attachments: false,
|
|
44
|
+
avatars: true,
|
|
45
|
+
names: true,
|
|
46
|
+
timestamps: false,
|
|
47
|
+
stream: false
|
|
48
|
+
},
|
|
49
|
+
isDeepChatLoaded: false,
|
|
50
|
+
messages: []
|
|
51
|
+
}
|
|
30
52
|
},
|
|
31
|
-
|
|
53
|
+
|
|
32
54
|
computed: {
|
|
33
|
-
|
|
55
|
+
containerStyle() {
|
|
34
56
|
return {
|
|
35
57
|
width: '100%',
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
58
|
+
height: '100%',
|
|
59
|
+
minHeight: '400px'
|
|
60
|
+
}
|
|
40
61
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
};
|
|
62
|
+
|
|
63
|
+
speechToTextConfig() {
|
|
64
|
+
return this.config.speechToText ? {
|
|
65
|
+
button: true,
|
|
66
|
+
displayInterimResults: true
|
|
67
|
+
} : false
|
|
48
68
|
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
|
|
53
|
-
}
|
|
69
|
+
|
|
70
|
+
cameraConfig() {
|
|
71
|
+
return this.config.camera ? {
|
|
72
|
+
button: true
|
|
73
|
+
} : false
|
|
54
74
|
},
|
|
55
|
-
|
|
75
|
+
|
|
76
|
+
microphoneConfig() {
|
|
77
|
+
return this.config.microphone ? {
|
|
78
|
+
button: true,
|
|
79
|
+
audio: true
|
|
80
|
+
} : false
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
attachmentsConfig() {
|
|
84
|
+
return this.config.attachments ? {
|
|
85
|
+
button: true,
|
|
86
|
+
acceptedFormats: ".jpeg,.jpg,.png,.gif,.pdf,.txt,.doc,.docx"
|
|
87
|
+
} : false
|
|
88
|
+
},
|
|
89
|
+
|
|
56
90
|
connectConfig() {
|
|
91
|
+
if (this.config.apiUrl && this.config.apiKey) {
|
|
92
|
+
return {
|
|
93
|
+
url: this.config.apiUrl,
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: {
|
|
96
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
97
|
+
'Content-Type': 'application/json'
|
|
98
|
+
},
|
|
99
|
+
body: {
|
|
100
|
+
model: this.config.model,
|
|
101
|
+
max_tokens: 2000,
|
|
102
|
+
temperature: 0.7
|
|
103
|
+
},
|
|
104
|
+
stream: this.config.stream
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Custom Handler für Node-RED Integration
|
|
57
109
|
return {
|
|
58
|
-
handler: this.
|
|
59
|
-
|
|
60
|
-
|
|
110
|
+
handler: this.handleCustomConnection,
|
|
111
|
+
stream: this.config.stream
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
mounted() {
|
|
117
|
+
this.loadDeepChat()
|
|
118
|
+
this.setupSocketListeners()
|
|
119
|
+
this.applyConfiguration()
|
|
61
120
|
},
|
|
121
|
+
|
|
62
122
|
beforeUnmount() {
|
|
63
|
-
this
|
|
123
|
+
this.removeSocketListeners()
|
|
64
124
|
},
|
|
65
|
-
|
|
125
|
+
|
|
66
126
|
methods: {
|
|
67
|
-
async
|
|
127
|
+
async loadDeepChat() {
|
|
68
128
|
try {
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
newMessages.push(messageContent);
|
|
79
|
-
} catch (e) {
|
|
80
|
-
console.error('Error parsing message:', e);
|
|
81
|
-
}
|
|
82
|
-
} else if (key === 'files') {
|
|
83
|
-
files.push(value);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Process files if present
|
|
88
|
-
if (files.length > 0 && newMessages.length > 0) {
|
|
89
|
-
const lastMessage = newMessages[newMessages.length - 1];
|
|
90
|
-
lastMessage.files = await this.processFiles(files);
|
|
129
|
+
// Deep Chat von CDN laden
|
|
130
|
+
if (!window.DeepChat) {
|
|
131
|
+
const script = document.createElement('script')
|
|
132
|
+
script.src = 'https://unpkg.com/deep-chat@latest/dist/deepChat.bundle.js'
|
|
133
|
+
script.onload = () => {
|
|
134
|
+
this.isDeepChatLoaded = true
|
|
135
|
+
this.$nextTick(() => {
|
|
136
|
+
this.initializeDeepChat()
|
|
137
|
+
})
|
|
91
138
|
}
|
|
92
|
-
|
|
93
|
-
|
|
139
|
+
document.head.appendChild(script)
|
|
140
|
+
} else {
|
|
141
|
+
this.isDeepChatLoaded = true
|
|
142
|
+
this.$nextTick(() => {
|
|
143
|
+
this.initializeDeepChat()
|
|
144
|
+
})
|
|
94
145
|
}
|
|
95
|
-
|
|
96
|
-
// Add to conversation history
|
|
97
|
-
this.conversation.push(...newMessages);
|
|
98
|
-
|
|
99
|
-
// Send to Node-RED
|
|
100
|
-
const payload = this.formatForChatGPT(this.conversation);
|
|
101
|
-
this.sendToNodeRED(payload, signals);
|
|
102
146
|
} catch (error) {
|
|
103
|
-
console.error('Error
|
|
104
|
-
this.sendErrorResponse(signals, 'Sorry, there was an error processing your message.');
|
|
147
|
+
console.error('Error loading Deep Chat:', error)
|
|
105
148
|
}
|
|
106
149
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return await this.processAudioFile(file);
|
|
118
|
-
} else {
|
|
119
|
-
// Handle other file types (PDFs, documents, etc.)
|
|
120
|
-
return await this.processDocumentFile(file);
|
|
121
|
-
}
|
|
122
|
-
})
|
|
123
|
-
);
|
|
124
|
-
} catch (error) {
|
|
125
|
-
console.error('Error processing files:', error);
|
|
126
|
-
return [];
|
|
150
|
+
|
|
151
|
+
initializeDeepChat() {
|
|
152
|
+
if (this.$refs.deepChat) {
|
|
153
|
+
// Deep Chat ist bereit
|
|
154
|
+
console.log('Deep Chat initialized for widget:', this.id)
|
|
155
|
+
|
|
156
|
+
// Intro Message senden falls konfiguriert
|
|
157
|
+
if (this.config.introMessage) {
|
|
158
|
+
this.addMessage(this.config.introMessage, 'ai')
|
|
159
|
+
}
|
|
127
160
|
}
|
|
128
161
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
162
|
+
|
|
163
|
+
setupSocketListeners() {
|
|
164
|
+
// Neue Nachricht von Node-RED empfangen
|
|
165
|
+
this.$socket.on('deepchat-newMessage:' + this.id, (data) => {
|
|
166
|
+
this.addMessage(data.message, data.role || 'ai', data.html, data.files)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
// Konfiguration aktualisieren
|
|
170
|
+
this.$socket.on('deepchat-updateConfig:' + this.id, (newConfig) => {
|
|
171
|
+
this.config = { ...this.config, ...newConfig }
|
|
172
|
+
this.applyConfiguration()
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
// Chat löschen
|
|
176
|
+
this.$socket.on('deepchat-clearMessages:' + this.id, () => {
|
|
177
|
+
this.clearMessages()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
// Standard Dashboard Message Input
|
|
181
|
+
this.$socket.on('msg-input:' + this.id, (msg) => {
|
|
182
|
+
if (msg.payload) {
|
|
183
|
+
this.addMessage(msg.payload, msg.role || 'ai', msg.html, msg.files)
|
|
184
|
+
}
|
|
185
|
+
if (msg.config) {
|
|
186
|
+
this.config = { ...this.config, ...msg.config }
|
|
187
|
+
}
|
|
188
|
+
if (msg.clear) {
|
|
189
|
+
this.clearMessages()
|
|
190
|
+
}
|
|
191
|
+
})
|
|
143
192
|
},
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const result = e.target.result;
|
|
151
|
-
const commaIndex = result.indexOf(',');
|
|
152
|
-
if (commaIndex === -1) {
|
|
153
|
-
throw new Error('Invalid data URL format: missing comma separator');
|
|
154
|
-
}
|
|
155
|
-
const base64Data = result.split(',')[1]; // Remove data URL prefix
|
|
156
|
-
|
|
157
|
-
resolve({
|
|
158
|
-
name: file.name,
|
|
159
|
-
type: file.type,
|
|
160
|
-
size: file.size,
|
|
161
|
-
base64Data: base64Data,
|
|
162
|
-
});
|
|
163
|
-
} catch (error) {
|
|
164
|
-
reject(error);
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
reader.onerror = () => reject(new Error('Failed to read audio'));
|
|
168
|
-
reader.readAsDataURL(file);
|
|
169
|
-
});
|
|
193
|
+
|
|
194
|
+
removeSocketListeners() {
|
|
195
|
+
this.$socket.off('deepchat-newMessage:' + this.id)
|
|
196
|
+
this.$socket.off('deepchat-updateConfig:' + this.id)
|
|
197
|
+
this.$socket.off('deepchat-clearMessages:' + this.id)
|
|
198
|
+
this.$socket.off('msg-input:' + this.id)
|
|
170
199
|
},
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
resolve({
|
|
180
|
-
name: file.name,
|
|
181
|
-
type: file.type,
|
|
182
|
-
size: file.size,
|
|
183
|
-
fileData: base64Data, // Use fileData for documents
|
|
184
|
-
});
|
|
185
|
-
} catch (error) {
|
|
186
|
-
reject(error);
|
|
200
|
+
|
|
201
|
+
applyConfiguration() {
|
|
202
|
+
// Konfiguration aus props übernehmen
|
|
203
|
+
if (this.props) {
|
|
204
|
+
Object.keys(this.props).forEach(key => {
|
|
205
|
+
if (this.config.hasOwnProperty(key)) {
|
|
206
|
+
this.config[key] = this.props[key]
|
|
187
207
|
}
|
|
188
|
-
}
|
|
189
|
-
reader.onerror = () => reject(new Error('Failed to read document'));
|
|
190
|
-
reader.readAsDataURL(file);
|
|
191
|
-
});
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
formatForChatGPT(conversation, textOnly = false) {
|
|
195
|
-
const payload = {
|
|
196
|
-
messages: conversation.map((msg) => this.formatMessage(msg, textOnly)),
|
|
197
|
-
model: this.props.model,
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
// Add ChatGPT API extensions
|
|
201
|
-
if (this.props.tools) {
|
|
202
|
-
payload.tools = this.props.tools;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (this.props.tool_choice) {
|
|
206
|
-
payload.tool_choice = this.props.tool_choice;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (this.props.temperature !== undefined) {
|
|
210
|
-
payload.temperature = this.props.temperature;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (this.props.max_tokens) {
|
|
214
|
-
payload.max_tokens = this.props.max_tokens;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
if (this.props.top_p !== undefined) {
|
|
218
|
-
payload.top_p = this.props.top_p;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (this.props.frequency_penalty !== undefined) {
|
|
222
|
-
payload.frequency_penalty = this.props.frequency_penalty;
|
|
208
|
+
})
|
|
223
209
|
}
|
|
224
|
-
|
|
225
|
-
if (this.props.presence_penalty !== undefined) {
|
|
226
|
-
payload.presence_penalty = this.props.presence_penalty;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (this.props.response_format) {
|
|
230
|
-
payload.response_format = this.props.response_format;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return payload;
|
|
234
210
|
},
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return message;
|
|
211
|
+
|
|
212
|
+
addMessage(content, role = 'ai', isHtml = false, files = []) {
|
|
213
|
+
try {
|
|
214
|
+
if (this.$refs.deepChat) {
|
|
215
|
+
const message = {
|
|
216
|
+
text: content,
|
|
217
|
+
role: role
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (isHtml) {
|
|
221
|
+
message.html = content
|
|
222
|
+
delete message.text
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (files && files.length > 0) {
|
|
226
|
+
message.files = files
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Nachricht zu Deep Chat hinzufügen
|
|
230
|
+
this.$refs.deepChat.addMessage(message)
|
|
231
|
+
this.messages.push(message)
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error('Error adding message to Deep Chat:', error)
|
|
260
235
|
}
|
|
261
|
-
|
|
262
|
-
// Handle text-only messages
|
|
263
|
-
message.content = msg.text || msg.content || '';
|
|
264
|
-
return message;
|
|
265
236
|
},
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
content.push({
|
|
273
|
-
type: 'image_url',
|
|
274
|
-
image_url: { url: file.src },
|
|
275
|
-
});
|
|
276
|
-
} else if (!textOnly && file.type && file.type.startsWith('audio/') && file.base64Data) {
|
|
277
|
-
const format = this.getAudioFormat(file.type);
|
|
278
|
-
content.push({
|
|
279
|
-
type: 'input_audio',
|
|
280
|
-
input_audio: {
|
|
281
|
-
data: file.base64Data,
|
|
282
|
-
format: format,
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
|
-
} else if (!textOnly && file.fileData) {
|
|
286
|
-
content.push({
|
|
287
|
-
type: 'file',
|
|
288
|
-
file: {
|
|
289
|
-
filename: file.name,
|
|
290
|
-
file_data: file.fileData,
|
|
291
|
-
},
|
|
292
|
-
});
|
|
237
|
+
|
|
238
|
+
clearMessages() {
|
|
239
|
+
try {
|
|
240
|
+
if (this.$refs.deepChat) {
|
|
241
|
+
this.$refs.deepChat.clearMessages()
|
|
242
|
+
this.messages = []
|
|
293
243
|
}
|
|
294
|
-
})
|
|
295
|
-
|
|
296
|
-
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error('Error clearing Deep Chat messages:', error)
|
|
246
|
+
}
|
|
297
247
|
},
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
248
|
+
|
|
249
|
+
handleCustomConnection(body, signals) {
|
|
250
|
+
// Node-RED Integration: Nachricht an Node-RED senden
|
|
251
|
+
this.$socket.emit('chat-message', this.id, {
|
|
252
|
+
message: body.messages || body,
|
|
253
|
+
timestamp: new Date().toISOString(),
|
|
254
|
+
files: body.files || []
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
// Temporary loading message
|
|
258
|
+
signals.onOpen({
|
|
259
|
+
text: 'Processing...',
|
|
260
|
+
role: 'ai'
|
|
261
|
+
})
|
|
305
262
|
},
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
263
|
+
|
|
264
|
+
handleNewMessage(event) {
|
|
265
|
+
// Event an Node-RED weiterleiten
|
|
266
|
+
this.$socket.emit('deepchat-onNewMessage', this.id, {
|
|
267
|
+
message: event.message,
|
|
268
|
+
role: event.role || 'user',
|
|
269
|
+
timestamp: new Date().toISOString()
|
|
270
|
+
})
|
|
313
271
|
},
|
|
272
|
+
|
|
273
|
+
handleClearMessages() {
|
|
274
|
+
// Event an Node-RED weiterleiten
|
|
275
|
+
this.$socket.emit('deepchat-onClearMessages', this.id, {
|
|
276
|
+
timestamp: new Date().toISOString()
|
|
277
|
+
})
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
handleComponentRender(event) {
|
|
281
|
+
// Event an Node-RED weiterleiten
|
|
282
|
+
this.$socket.emit('deepchat-onComponentRender', this.id, {
|
|
283
|
+
event: event,
|
|
284
|
+
timestamp: new Date().toISOString()
|
|
285
|
+
})
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
handleResponse(event) {
|
|
289
|
+
console.log('Deep Chat Response:', event)
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
handleError(error) {
|
|
293
|
+
console.error('Deep Chat Error:', error)
|
|
294
|
+
|
|
295
|
+
// Fehler an Node-RED melden
|
|
296
|
+
this.$socket.emit('chat-message', this.id, {
|
|
297
|
+
error: error.message || error,
|
|
298
|
+
timestamp: new Date().toISOString()
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
</script>
|
|
314
304
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
role: 'ai',
|
|
323
|
-
content: fullResponse.message?.content || fullResponse.content,
|
|
324
|
-
text: fullResponse.message?.content || fullResponse.content,
|
|
325
|
-
fullResponse: fullResponse,
|
|
326
|
-
};
|
|
305
|
+
<style scoped>
|
|
306
|
+
.ui-deepchat-container {
|
|
307
|
+
position: relative;
|
|
308
|
+
border-radius: 8px;
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
background: var(--v-theme-surface);
|
|
311
|
+
}
|
|
327
312
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
313
|
+
/* Deep Chat Styling Integration */
|
|
314
|
+
.ui-deepchat-container :deep(deep-chat) {
|
|
315
|
+
width: 100% !important;
|
|
316
|
+
height: 100% !important;
|
|
317
|
+
border: none !important;
|
|
318
|
+
border-radius: 8px;
|
|
319
|
+
font-family: var(--v-font-family) !important;
|
|
320
|
+
}
|
|
333
321
|
|
|
334
|
-
|
|
322
|
+
/* Dark theme support */
|
|
323
|
+
.ui-deepchat-container :deep(deep-chat) {
|
|
324
|
+
--chat-background-color: var(--v-theme-surface);
|
|
325
|
+
--user-message-color: var(--v-theme-primary);
|
|
326
|
+
--ai-message-color: var(--v-theme-secondary);
|
|
327
|
+
--border-color: var(--v-theme-outline);
|
|
328
|
+
--text-color: var(--v-theme-on-surface);
|
|
329
|
+
--placeholder-color: var(--v-theme-on-surface-variant);
|
|
330
|
+
}
|
|
335
331
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
role: 'ai',
|
|
342
|
-
});
|
|
343
|
-
} else if (fullResponse.message?.content || fullResponse.content) {
|
|
344
|
-
// Normal text response
|
|
345
|
-
signals.onResponse({
|
|
346
|
-
text: fullResponse.message?.content || fullResponse.content,
|
|
347
|
-
role: 'ai',
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
} catch (error) {
|
|
351
|
-
console.error('Error handling response:', error);
|
|
352
|
-
this.sendErrorResponse(signals, 'Error processing response');
|
|
353
|
-
}
|
|
354
|
-
},
|
|
332
|
+
/* Input area styling */
|
|
333
|
+
.ui-deepchat-container :deep(.text-input-container) {
|
|
334
|
+
border-top: 1px solid var(--v-theme-outline) !important;
|
|
335
|
+
background: var(--v-theme-surface) !important;
|
|
336
|
+
}
|
|
355
337
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
role: 'ai',
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
};
|
|
366
|
-
</script>
|
|
338
|
+
/* Message bubbles */
|
|
339
|
+
.ui-deepchat-container :deep(.message-bubble) {
|
|
340
|
+
border-radius: 12px !important;
|
|
341
|
+
}
|
|
367
342
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
343
|
+
/* Responsive design */
|
|
344
|
+
@media (max-width: 768px) {
|
|
345
|
+
.ui-deepchat-container {
|
|
346
|
+
border-radius: 0;
|
|
347
|
+
}
|
|
373
348
|
}
|
|
374
|
-
</style>
|
|
349
|
+
</style>
|