quickblox-react-ui-kit 0.1.8 → 0.2.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/dist/Presentation/Views/Base/BaseViewModel.d.ts +2 -1
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.d.ts +8 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/ErrorMessageIcon.d.ts +11 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.d.ts +9 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultTextInputWidget.d.ts +2 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/useDefaultVoiceInputWidget.d.ts +2 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.d.ts +10 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/MessagesView.d.ts +4 -0
- package/dist/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.d.ts +9 -0
- package/dist/index-ui.js +47 -3
- package/dist/utils/utils.d.ts +3 -0
- package/package.json +1 -1
- package/src/App.tsx +0 -19
- package/src/Presentation/Views/Base/BaseViewModel.ts +11 -3
- package/src/Presentation/Views/Dialogs/Dialogs.tsx +0 -1
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.ts +13 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/ErrorMessageIcon.tsx +98 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.tsx +136 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/{InputWidget → AIWidgets}/UseDefaultTextInputWidget.tsx +4 -4
- package/src/Presentation/components/UI/Dialogs/MessagesView/{InputWidget → AIWidgets}/useDefaultVoiceInputWidget.tsx +4 -4
- package/src/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.tsx +96 -0
- package/src/Presentation/components/UI/Dialogs/MessagesView/MessagesView.tsx +117 -62
- package/src/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.tsx +68 -36
- package/src/QBconfig.ts +3 -4
- package/src/utils/utils.ts +39 -0
- package/dist/Presentation/components/UI/Dialogs/MessagesView/InputWidget/InputWidget.d.ts +0 -8
- package/dist/Presentation/components/UI/Dialogs/MessagesView/InputWidget/UseDefaultTextInputWidget.d.ts +0 -2
- package/dist/Presentation/components/UI/Dialogs/MessagesView/InputWidget/useDefaultVoiceInputWidget.d.ts +0 -2
- package/src/Presentation/components/UI/Dialogs/MessagesView/InputWidget/InputWidget.ts +0 -15
|
@@ -15,7 +15,10 @@ import useMessagesViewModel from './useMessagesViewModel';
|
|
|
15
15
|
import LoaderComponent from '../../Placeholders/LoaderComponent/LoaderComponent';
|
|
16
16
|
import ErrorComponent from '../../Placeholders/ErrorComponent/ErrorComponent';
|
|
17
17
|
import HeaderMessages from './HeaderMessages/HeaderMessages';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
FunctionTypeVoidToVoid,
|
|
20
|
+
IChatMessage,
|
|
21
|
+
} from '../../../../Views/Base/BaseViewModel';
|
|
19
22
|
import VideoAttachmentComponent from './VideoAttachmentComponent/VideoAttachmentComponent';
|
|
20
23
|
import ImageAttachmentComponent from './ImageAttachmentComponent/ImageAttachmentComponent';
|
|
21
24
|
import { DialogType } from '../../../../../Domain/entity/DialogTypes';
|
|
@@ -45,14 +48,15 @@ import ViewedDelivered from '../../svgs/Icons/Status/ViewedDelivered';
|
|
|
45
48
|
import { stringifyError } from '../../../../../utils/parse';
|
|
46
49
|
import VoiceRecordingProgress from './VoiceRecordingProgress/VoiceRecordingProgress';
|
|
47
50
|
import UiKitTheme from '../../../../assets/UiKitTheme';
|
|
51
|
+
import { AIWidget } from './AIWidgets/AIWidget';
|
|
48
52
|
import { DialogsViewModel } from '../../../../Views/Dialogs/DialogViewModel';
|
|
49
53
|
import { HighLightLink, messageHasUrls } from './HighLightLink/HighLightLink';
|
|
50
|
-
|
|
54
|
+
import { loopToLimitTokens } from '../../../../../utils/utils';
|
|
51
55
|
|
|
52
56
|
type HeaderDialogsMessagesProps = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
AIEditMessage?: AIWidget;
|
|
58
|
+
AITranslation?: AIWidget;
|
|
59
|
+
AIAnswerToMessage?: AIWidget;
|
|
56
60
|
dialogsViewModel: DialogsViewModel;
|
|
57
61
|
onDialogInformationHandler?: FunctionTypeVoidToVoid;
|
|
58
62
|
maxWidthToResize?: string;
|
|
@@ -64,11 +68,11 @@ type HeaderDialogsMessagesProps = {
|
|
|
64
68
|
// eslint-disable-next-line react/function-component-definition
|
|
65
69
|
const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
66
70
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
67
|
-
|
|
71
|
+
AIEditMessage,
|
|
68
72
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
69
|
-
|
|
73
|
+
AITranslation,
|
|
70
74
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
71
|
-
|
|
75
|
+
AIAnswerToMessage,
|
|
72
76
|
dialogsViewModel,
|
|
73
77
|
onDialogInformationHandler,
|
|
74
78
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -96,6 +100,32 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
96
100
|
const [messagesToView, setMessagesToView] = React.useState<MessageEntity[]>(
|
|
97
101
|
[],
|
|
98
102
|
);
|
|
103
|
+
const [waitAIWidget, setWaitAIWidget] = useState<boolean>(false);
|
|
104
|
+
|
|
105
|
+
const messageEntitiesToIChatMessageCollection = (
|
|
106
|
+
messageEntities: MessageEntity[],
|
|
107
|
+
): IChatMessage[] => {
|
|
108
|
+
const MAX_TOKENS = 3584;
|
|
109
|
+
const items = messageEntities.filter(
|
|
110
|
+
(it) =>
|
|
111
|
+
!it.notification_type ||
|
|
112
|
+
(it.notification_type && it.notification_type.length === 0),
|
|
113
|
+
);
|
|
114
|
+
const messages = loopToLimitTokens(
|
|
115
|
+
MAX_TOKENS,
|
|
116
|
+
items,
|
|
117
|
+
({ message }) => message || '',
|
|
118
|
+
).reverse();
|
|
119
|
+
const chatCompletionMessages: IChatMessage[] = messages.map(
|
|
120
|
+
({ message, sender_id }) => ({
|
|
121
|
+
role: sender_id === currentUserId ? 'user' : 'assistant',
|
|
122
|
+
content: message,
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
//
|
|
127
|
+
return chatCompletionMessages;
|
|
128
|
+
};
|
|
99
129
|
|
|
100
130
|
const messagesViewModel: MessagesViewModel = useMessagesViewModel(
|
|
101
131
|
dialogsViewModel.entity?.type,
|
|
@@ -181,6 +211,23 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
181
211
|
}
|
|
182
212
|
}, [dialogMessagesCount]);
|
|
183
213
|
//
|
|
214
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
215
|
+
const menuItems = [
|
|
216
|
+
{
|
|
217
|
+
title: 'Item 1',
|
|
218
|
+
action: () => {
|
|
219
|
+
console.log('Clicked on Item 1');
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
title: 'Item 2',
|
|
224
|
+
action: () => {
|
|
225
|
+
console.log('Clicked on Item 2');
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
// ... добавьте дополнительные элементы меню
|
|
229
|
+
];
|
|
230
|
+
//
|
|
184
231
|
|
|
185
232
|
const getSenderName = (sender?: UserEntity): string | undefined => {
|
|
186
233
|
if (!sender) return undefined;
|
|
@@ -357,13 +404,18 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
357
404
|
<div
|
|
358
405
|
className="message-view-container__incoming-time"
|
|
359
406
|
onClick={() => {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
407
|
+
if (!waitAIWidget) {
|
|
408
|
+
setWaitAIWidget(true);
|
|
409
|
+
AIAnswerToMessage?.textToWidget(
|
|
410
|
+
message.message,
|
|
411
|
+
messageEntitiesToIChatMessageCollection(messagesToView),
|
|
412
|
+
);
|
|
413
|
+
}
|
|
363
414
|
}}
|
|
364
415
|
>
|
|
365
|
-
{
|
|
416
|
+
{AIAnswerToMessage?.renderWidget()}
|
|
366
417
|
</div>
|
|
418
|
+
{/* <ContextMenu items={menuItems} /> */}
|
|
367
419
|
</div>
|
|
368
420
|
);
|
|
369
421
|
} else {
|
|
@@ -634,7 +686,10 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
634
686
|
setFileToSend(voiceMessage);
|
|
635
687
|
if (useAudioWidget) {
|
|
636
688
|
setUseAudioWidget(false);
|
|
637
|
-
|
|
689
|
+
AITranslation?.fileToWidget(
|
|
690
|
+
voiceMessage,
|
|
691
|
+
messageEntitiesToIChatMessageCollection(messagesToView),
|
|
692
|
+
);
|
|
638
693
|
}
|
|
639
694
|
//
|
|
640
695
|
}
|
|
@@ -699,45 +754,45 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
699
754
|
}
|
|
700
755
|
}
|
|
701
756
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
757
|
+
useEffect(() => {
|
|
758
|
+
if (
|
|
759
|
+
AIEditMessage?.textToContent &&
|
|
760
|
+
AIEditMessage?.textToContent.length > 0
|
|
761
|
+
) {
|
|
762
|
+
setMessageText(AIEditMessage?.textToContent);
|
|
763
|
+
setWidgetTextContent(AIEditMessage?.textToContent);
|
|
764
|
+
setTimeout(() => {
|
|
765
|
+
setWidgetTextContent('');
|
|
766
|
+
}, 45 * 1000);
|
|
767
|
+
}
|
|
768
|
+
}, [AIEditMessage?.textToContent]);
|
|
769
|
+
|
|
770
|
+
useEffect(() => {
|
|
771
|
+
if (
|
|
772
|
+
AITranslation?.textToContent &&
|
|
773
|
+
AITranslation?.textToContent.length > 0
|
|
774
|
+
) {
|
|
775
|
+
setMessageText(AITranslation?.textToContent);
|
|
776
|
+
setWidgetTextContent(AITranslation?.textToContent);
|
|
777
|
+
setTimeout(() => {
|
|
778
|
+
setWidgetTextContent('');
|
|
779
|
+
}, 45 * 1000);
|
|
780
|
+
}
|
|
781
|
+
}, [AITranslation?.textToContent]);
|
|
782
|
+
|
|
783
|
+
useEffect(() => {
|
|
784
|
+
setWaitAIWidget(false);
|
|
785
|
+
if (
|
|
786
|
+
AIAnswerToMessage?.textToContent &&
|
|
787
|
+
AIAnswerToMessage?.textToContent.length > 0
|
|
788
|
+
) {
|
|
789
|
+
setMessageText(AIAnswerToMessage?.textToContent);
|
|
790
|
+
setWidgetTextContent(AIAnswerToMessage?.textToContent);
|
|
791
|
+
setTimeout(() => {
|
|
792
|
+
setWidgetTextContent('');
|
|
793
|
+
}, 45 * 1000);
|
|
794
|
+
}
|
|
795
|
+
}, [AIAnswerToMessage?.textToContent]);
|
|
741
796
|
|
|
742
797
|
const useSubContent = subHeaderContent || false;
|
|
743
798
|
const useUpContent = upHeaderContent || false;
|
|
@@ -850,7 +905,7 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
850
905
|
}
|
|
851
906
|
className="message-view-container--messages"
|
|
852
907
|
>
|
|
853
|
-
{messagesViewModel?.error && (
|
|
908
|
+
{messagesViewModel?.error && !messagesViewModel.loading && (
|
|
854
909
|
<ErrorComponent
|
|
855
910
|
title={messagesViewModel?.error}
|
|
856
911
|
ClickActionHandler={() => {
|
|
@@ -872,7 +927,7 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
872
927
|
autoScrollToBottom={scrollUpToDown}
|
|
873
928
|
/>
|
|
874
929
|
)}
|
|
875
|
-
{messagesViewModel?.loading && (
|
|
930
|
+
{(messagesViewModel?.loading || waitAIWidget) && (
|
|
876
931
|
<div
|
|
877
932
|
style={{
|
|
878
933
|
height: '44px',
|
|
@@ -941,11 +996,11 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
941
996
|
}}
|
|
942
997
|
/>
|
|
943
998
|
</label>
|
|
944
|
-
{/* start
|
|
945
|
-
{/* {
|
|
999
|
+
{/* start AITranslation */}
|
|
1000
|
+
{/* {AITranslation && ( */}
|
|
946
1001
|
{/* <div> */}
|
|
947
1002
|
{/* <ActiveSvg */}
|
|
948
|
-
{/* content={
|
|
1003
|
+
{/* content={AITranslation.renderWidget()} */}
|
|
949
1004
|
{/* clickAction={() => { */}
|
|
950
1005
|
{/* console.log('click left place golder widget'); */}
|
|
951
1006
|
{/* if (messagesViewModel?.loading) return; */}
|
|
@@ -958,7 +1013,7 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
958
1013
|
{/* /> */}
|
|
959
1014
|
{/* </div> */}
|
|
960
1015
|
{/* )} */}
|
|
961
|
-
{/* end
|
|
1016
|
+
{/* end AITranslation */}
|
|
962
1017
|
{!isRecording && (
|
|
963
1018
|
<textarea
|
|
964
1019
|
style={theme ? { backgroundColor: theme.chatInput() } : {}}
|
|
@@ -1003,14 +1058,14 @@ const MessagesView: React.FC<HeaderDialogsMessagesProps> = ({
|
|
|
1003
1058
|
}}
|
|
1004
1059
|
/>
|
|
1005
1060
|
)}
|
|
1006
|
-
{/*
|
|
1007
|
-
{/* {
|
|
1061
|
+
{/* AITranslation start AIEditMessage */}
|
|
1062
|
+
{/* {AIEditMessage && ( */}
|
|
1008
1063
|
{/* <div> */}
|
|
1009
1064
|
{/* <ActiveSvg */}
|
|
1010
|
-
{/* content={
|
|
1065
|
+
{/* content={AIEditMessage.renderWidget()} */}
|
|
1011
1066
|
{/* clickAction={() => { */}
|
|
1012
1067
|
{/* console.log('click left place golder widget'); */}
|
|
1013
|
-
{/*
|
|
1068
|
+
{/* AIEditMessage?.textToWidget(messageText); */}
|
|
1014
1069
|
{/* }} */}
|
|
1015
1070
|
{/* touchAction={() => { */}
|
|
1016
1071
|
{/* console.log('touch left place golder widget'); */}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
// import { Configuration, OpenAIApi } from 'openai';
|
|
3
2
|
import useQbInitializedDataContext from '../../providers/QuickBloxUIKitProvider/useQbInitializedDataContext';
|
|
4
3
|
import { DialogEntity } from '../../../../Domain/entity/DialogEntity';
|
|
5
4
|
import { DialogsViewModel } from '../../../Views/Dialogs/DialogViewModel';
|
|
@@ -17,23 +16,34 @@ import { Pagination } from '../../../../Domain/repository/Pagination';
|
|
|
17
16
|
// import { DialogEventInfo } from '../../../../Domain/entity/DialogEventInfo';
|
|
18
17
|
import UiKitTheme from '../../../assets/UiKitTheme';
|
|
19
18
|
import BaseViewModel from '../../../Views/Base/BaseViewModel';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
import { AIWidget } from '../../UI/Dialogs/MessagesView/AIWidgets/AIWidget';
|
|
20
|
+
import { QBConfig } from '../../../../QBconfig';
|
|
21
|
+
import UseDefaultAIAssistAnswerWidgetWithProxy from '../../UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy';
|
|
22
|
+
|
|
23
|
+
type AIWidgetPlaceHolder = {
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
default: boolean;
|
|
26
|
+
AIWidget?: AIWidget;
|
|
27
|
+
};
|
|
25
28
|
|
|
26
29
|
type QuickBloxUIKitDesktopLayoutProps = {
|
|
27
30
|
theme?: UiKitTheme;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
AIEditMessage?: AIWidgetPlaceHolder;
|
|
32
|
+
AITranslation?: AIWidgetPlaceHolder;
|
|
33
|
+
AIAnswerToMessage?: AIWidgetPlaceHolder;
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
const QuickBloxUIKitDesktopLayout: React.FC<
|
|
34
37
|
QuickBloxUIKitDesktopLayoutProps
|
|
35
38
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars,react/function-component-definition
|
|
36
|
-
> = ({
|
|
39
|
+
> = ({
|
|
40
|
+
theme = undefined,
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
42
|
+
AITranslation = undefined,
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
|
+
AIEditMessage = undefined,
|
|
45
|
+
AIAnswerToMessage = undefined,
|
|
46
|
+
}: QuickBloxUIKitDesktopLayoutProps) => {
|
|
37
47
|
console.log('create QuickBloxUIKitDesktopLayout');
|
|
38
48
|
const [selectedDialog, setSelectedDialog] =
|
|
39
49
|
React.useState<BaseViewModel<DialogEntity>>();
|
|
@@ -46,32 +56,56 @@ const QuickBloxUIKitDesktopLayout: React.FC<
|
|
|
46
56
|
currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.userName;
|
|
47
57
|
const userId =
|
|
48
58
|
currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.userId;
|
|
59
|
+
const sessionToken =
|
|
60
|
+
currentContext.storage.REMOTE_DATA_SOURCE.authInformation?.sessionToken;
|
|
49
61
|
|
|
50
62
|
const dialogsViewModel: DialogsViewModel =
|
|
51
63
|
useDialogsViewModel(currentContext);
|
|
52
64
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// if (!
|
|
56
|
-
//
|
|
57
|
-
// }
|
|
58
|
-
// const defaultRightPlaceHolderInputWidget =
|
|
59
|
-
// InputWidgetToRightPlaceHolder || useDefaultVoiceInputWidget();
|
|
60
|
-
// let defaultIncomingMessageWidget = IncomingMessageWidgetToRightPlaceHolder;
|
|
61
|
-
//
|
|
62
|
-
// if (!defaultIncomingMessageWidget) {
|
|
63
|
-
// const apiKey = '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'; // Замените на ваш реальный ключ API
|
|
64
|
-
//
|
|
65
|
-
// const openAIConfiguration = new Configuration({
|
|
66
|
-
// apiKey,
|
|
67
|
-
// });
|
|
68
|
-
//
|
|
69
|
-
// const openAIApi = new OpenAIApi(openAIConfiguration);
|
|
70
|
-
//
|
|
71
|
-
// defaultIncomingMessageWidget = UseDefaultIncomingMessageWidget({
|
|
72
|
-
// openAIApi,
|
|
73
|
-
// });
|
|
65
|
+
const defaultAIEditMessageWidget = AIEditMessage?.AIWidget; // useDefaultTextInputWidget();
|
|
66
|
+
const defaultAITranslateWidget = AITranslation?.AIWidget;
|
|
67
|
+
// if (!defaultAIEditMessageWidget) {
|
|
68
|
+
// defaultAIEditMessageWidget = useDefaultTextInputWidget();
|
|
74
69
|
// }
|
|
70
|
+
// const defaultAITranslateWidget =
|
|
71
|
+
// AITranslation?.AIWidget || useDefaultVoiceInputWidget();
|
|
72
|
+
let defaultAIAnswerToMessageWidget;
|
|
73
|
+
|
|
74
|
+
const getAIAssistAnswer = (): void => {
|
|
75
|
+
if (AIAnswerToMessage?.enabled && !AIAnswerToMessage?.default) {
|
|
76
|
+
defaultAIAnswerToMessageWidget = AIAnswerToMessage.AIWidget;
|
|
77
|
+
} else if (
|
|
78
|
+
AIAnswerToMessage?.enabled ||
|
|
79
|
+
QBConfig.configAIApi.AIAnswerAssistWidgetConfig.useDefault
|
|
80
|
+
) {
|
|
81
|
+
if (
|
|
82
|
+
!QBConfig.configAIApi.AIAnswerAssistWidgetConfig.useDefault ||
|
|
83
|
+
(AIAnswerToMessage && !AIAnswerToMessage?.default)
|
|
84
|
+
) {
|
|
85
|
+
defaultAIAnswerToMessageWidget = undefined;
|
|
86
|
+
} else {
|
|
87
|
+
const { apiKey } = QBConfig.configAIApi.AIAnswerAssistWidgetConfig;
|
|
88
|
+
let token = '';
|
|
89
|
+
|
|
90
|
+
if (apiKey) {
|
|
91
|
+
token = apiKey;
|
|
92
|
+
} else {
|
|
93
|
+
token =
|
|
94
|
+
QBConfig.configAIApi.AIAnswerAssistWidgetConfig.proxyConfig
|
|
95
|
+
.sessionToken ||
|
|
96
|
+
sessionToken ||
|
|
97
|
+
'';
|
|
98
|
+
}
|
|
99
|
+
defaultAIAnswerToMessageWidget =
|
|
100
|
+
UseDefaultAIAssistAnswerWidgetWithProxy({
|
|
101
|
+
...QBConfig.configAIApi.AIAnswerAssistWidgetConfig.proxyConfig,
|
|
102
|
+
sessionToken: token,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
getAIAssistAnswer();
|
|
75
109
|
|
|
76
110
|
const selectDialogActions = (item: BaseViewModel<DialogEntity>): void => {
|
|
77
111
|
if (!dialogsViewModel.loading) {
|
|
@@ -235,11 +269,9 @@ const QuickBloxUIKitDesktopLayout: React.FC<
|
|
|
235
269
|
maxWidthToResize={
|
|
236
270
|
selectedDialog && needDialogInformation ? undefined : '1040px'
|
|
237
271
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
// defaultIncomingMessageWidget
|
|
242
|
-
// }
|
|
272
|
+
AIEditMessage={defaultAIEditMessageWidget}
|
|
273
|
+
AITranslation={defaultAITranslateWidget}
|
|
274
|
+
AIAnswerToMessage={defaultAIAnswerToMessageWidget}
|
|
243
275
|
theme={theme}
|
|
244
276
|
/> // 1 Get Messages + 1 Get User by Id
|
|
245
277
|
) : (
|
package/src/QBconfig.ts
CHANGED
|
@@ -8,13 +8,12 @@ export const QBConfig = {
|
|
|
8
8
|
},
|
|
9
9
|
configAIApi: {
|
|
10
10
|
AIAnswerAssistWidgetConfig: {
|
|
11
|
-
apiKey: '',
|
|
11
|
+
apiKey: '', // Replace with your real API key
|
|
12
12
|
useDefault: true,
|
|
13
13
|
proxyConfig: {
|
|
14
|
-
// https://api.openai.com/v1/chat/completions'
|
|
15
14
|
api: 'v1/chat/completions',
|
|
16
|
-
servername: 'https://
|
|
17
|
-
port: '
|
|
15
|
+
servername: 'https://api.openai.com/',
|
|
16
|
+
port: '',
|
|
18
17
|
sessionToken: '',
|
|
19
18
|
},
|
|
20
19
|
},
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// import { encode } from 'gpt-3-encoder';
|
|
2
|
+
|
|
3
|
+
export const completeSentence = (text?: string) =>
|
|
4
|
+
text?.replace(/([^.!?;]+)[^.!?;]*$/, ' ...') || '';
|
|
5
|
+
|
|
6
|
+
// export const tokenCounter = (text?: string) => (text ? encode(text).length : 0);
|
|
7
|
+
|
|
8
|
+
export const tokenCounter = (text?: string) => (text ? text.length / 4 : 0);
|
|
9
|
+
|
|
10
|
+
export const loopToLimitTokens = <T>(
|
|
11
|
+
limit: number,
|
|
12
|
+
data: T[],
|
|
13
|
+
getValue: (item: T) => string = (item) =>
|
|
14
|
+
typeof item === 'string' ? item : String(item),
|
|
15
|
+
tokens = 0,
|
|
16
|
+
): T[] => {
|
|
17
|
+
if (!data.length) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const [firstItem, ...lastItems] = data;
|
|
22
|
+
|
|
23
|
+
const itemValue = getValue(firstItem);
|
|
24
|
+
const itemTokens = tokenCounter(itemValue);
|
|
25
|
+
const amountTokens = tokens + itemTokens;
|
|
26
|
+
|
|
27
|
+
if (amountTokens <= limit) {
|
|
28
|
+
const nextData = loopToLimitTokens(
|
|
29
|
+
limit,
|
|
30
|
+
lastItems,
|
|
31
|
+
getValue,
|
|
32
|
+
amountTokens,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return itemTokens === 0 ? nextData : [firstItem, ...nextData];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return [];
|
|
39
|
+
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { FunctionTypeFileToToVoid, FunctionTypeJSXElement, FunctionTypeStringToVoid } from '../../../../../Views/Base/BaseViewModel';
|
|
2
|
-
export interface InputWidget {
|
|
3
|
-
renderWidget: FunctionTypeJSXElement;
|
|
4
|
-
textToWidget: FunctionTypeStringToVoid;
|
|
5
|
-
fileToWidget: FunctionTypeFileToToVoid;
|
|
6
|
-
textToInput: string | undefined;
|
|
7
|
-
fileToInput: File | undefined;
|
|
8
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FunctionTypeFileToToVoid,
|
|
3
|
-
FunctionTypeJSXElement,
|
|
4
|
-
FunctionTypeStringToVoid,
|
|
5
|
-
} from '../../../../../Views/Base/BaseViewModel';
|
|
6
|
-
|
|
7
|
-
export interface InputWidget {
|
|
8
|
-
renderWidget: FunctionTypeJSXElement;
|
|
9
|
-
textToWidget: FunctionTypeStringToVoid;
|
|
10
|
-
fileToWidget: FunctionTypeFileToToVoid;
|
|
11
|
-
textToInput: string | undefined;
|
|
12
|
-
fileToInput: File | undefined;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|