|
1 |
| -const createAssistantTab = (function() { |
| 1 | +const createAssistantTab = (function() { |
2 | 2 |
|
3 | 3 | let lastUserQuery;
|
4 |
| - |
| 4 | + let errorList = []; |
5 | 5 | const assistant = {
|
6 | 6 | id: 'assistant',
|
7 | 7 | name: 'Virtual Assistant',
|
|
11 | 11 | id: 'user',
|
12 | 12 | };
|
13 | 13 |
|
| 14 | + |
| 15 | + async function _tryFetch(instance, fetchAction, message) { |
| 16 | + try { |
| 17 | + return await fetchAction(); |
| 18 | + } catch(error) { |
| 19 | + _handleError(instance, { message: error.message, code: message }); |
| 20 | + } |
| 21 | + } |
| 22 | + |
| 23 | + function _handleError(instance, error) { |
| 24 | + const id = "id" + Math.random().toString(16).slice(2) |
| 25 | + setTimeout(() => { |
| 26 | + errorList = errorList.filter(err => err.id !== id); |
| 27 | + instance.option('alerts', errorList); |
| 28 | + }, 10000); |
| 29 | + errorList.push({ |
| 30 | + id: id, |
| 31 | + message: `${error.code} - ${error.message}` |
| 32 | + }); |
| 33 | + instance.option('alerts', errorList); |
| 34 | + } |
| 35 | + |
14 | 36 | function normalizeAIResponse(text) {
|
15 | 37 | text = text.replace(/【\d+:\d+†[^\】]+】/g, "");
|
16 | 38 | let html = marked.parse(text);
|
|
23 | 45 | navigator.clipboard.writeText(text);
|
24 | 46 | }
|
25 | 47 |
|
26 |
| - async function getAIResponse(text, id) { |
| 48 | + async function getAIResponse(instance, text, id) { |
27 | 49 | const formData = new FormData();
|
28 | 50 | formData.append('text', text);
|
29 | 51 | formData.append('chatId', id);
|
30 | 52 | lastUserQuery = text;
|
31 |
| - const response = await fetch(`/AI/GetAnswer`, { |
32 |
| - method: 'POST', |
33 |
| - body: formData |
34 |
| - }); |
35 |
| - return await response.text(); |
| 53 | + return _tryFetch(instance, async () => { |
| 54 | + const response = await fetch('/AI/GetAnswer', { |
| 55 | + method: 'POST', |
| 56 | + body: formData |
| 57 | + }); |
| 58 | + |
| 59 | + if(!response.ok) { |
| 60 | + _handleError(instance, { code: `${response.status}`, message: `Internal server error` }); |
| 61 | + return; |
| 62 | + } |
| 63 | + return await response.text(); |
| 64 | + }, 'GetAnswer'); |
36 | 65 | }
|
37 | 66 |
|
38 | 67 | function RenderAssistantMessage(instance, message) {
|
|
45 | 74 | const newItems = items.slice(0, -1);
|
46 | 75 | instance.option({ items: newItems });
|
47 | 76 | instance.option({ typingUsers: [assistant] });
|
48 |
| - const aiResponse = await getAIResponse(lastUserQuery, assistant.id); |
| 77 | + const aiResponse = await getAIResponse(instance, lastUserQuery, assistant.id); |
49 | 78 | setTimeout(() => {
|
50 | 79 | instance.option({ typingUsers: [] });
|
51 | 80 | RenderAssistantMessage(instance, aiResponse);
|
52 | 81 | }, 200);
|
53 | 82 | }
|
54 | 83 |
|
55 | 84 | function createAssistantTab(chatId) {
|
| 85 | + let lastRefreshButton; |
56 | 86 | assistant.id = chatId;
|
57 | 87 | const model = {
|
58 | 88 | title: 'AI Assistant',
|
|
72 | 102 |
|
73 | 103 | const buttonContainer = document.createElement('div');
|
74 | 104 | buttonContainer.classList.add('dx-bubble-button-container');
|
| 105 | + lastRefreshButton?.remove(); |
75 | 106 | const copyBtnElement = document.createElement('div');
|
76 | 107 | new DevExpress.ui.dxButton(copyBtnElement, {
|
77 | 108 | icon: 'copy',
|
|
94 | 125 | onMessageEntered: async (e) => {
|
95 | 126 | lastRefreshButton?.remove();
|
96 | 127 | const instance = e.component;
|
| 128 | + instance.option('alerts', []); |
97 | 129 | instance.renderMessage(e.message);
|
98 | 130 | instance.option({ typingUsers: [assistant] });
|
99 | 131 | const userInput = e.message.text;
|
|
0 commit comments