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.
Files changed (29) hide show
  1. package/dist/Presentation/Views/Base/BaseViewModel.d.ts +2 -1
  2. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.d.ts +8 -0
  3. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/ErrorMessageIcon.d.ts +11 -0
  4. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.d.ts +9 -0
  5. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultTextInputWidget.d.ts +2 -0
  6. package/dist/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/useDefaultVoiceInputWidget.d.ts +2 -0
  7. package/dist/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.d.ts +10 -0
  8. package/dist/Presentation/components/UI/Dialogs/MessagesView/MessagesView.d.ts +4 -0
  9. package/dist/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.d.ts +9 -0
  10. package/dist/index-ui.js +47 -3
  11. package/dist/utils/utils.d.ts +3 -0
  12. package/package.json +1 -1
  13. package/src/App.tsx +0 -19
  14. package/src/Presentation/Views/Base/BaseViewModel.ts +11 -3
  15. package/src/Presentation/Views/Dialogs/Dialogs.tsx +0 -1
  16. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/AIWidget.ts +13 -0
  17. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/ErrorMessageIcon.tsx +98 -0
  18. package/src/Presentation/components/UI/Dialogs/MessagesView/AIWidgets/UseDefaultAIAssistAnswerWidgetWithProxy.tsx +136 -0
  19. package/src/Presentation/components/UI/Dialogs/MessagesView/{InputWidget → AIWidgets}/UseDefaultTextInputWidget.tsx +4 -4
  20. package/src/Presentation/components/UI/Dialogs/MessagesView/{InputWidget → AIWidgets}/useDefaultVoiceInputWidget.tsx +4 -4
  21. package/src/Presentation/components/UI/Dialogs/MessagesView/ContextMenu.tsx +96 -0
  22. package/src/Presentation/components/UI/Dialogs/MessagesView/MessagesView.tsx +117 -62
  23. package/src/Presentation/components/layouts/Desktop/QuickBloxUIKitDesktopLayout.tsx +68 -36
  24. package/src/QBconfig.ts +3 -4
  25. package/src/utils/utils.ts +39 -0
  26. package/dist/Presentation/components/UI/Dialogs/MessagesView/InputWidget/InputWidget.d.ts +0 -8
  27. package/dist/Presentation/components/UI/Dialogs/MessagesView/InputWidget/UseDefaultTextInputWidget.d.ts +0 -2
  28. package/dist/Presentation/components/UI/Dialogs/MessagesView/InputWidget/useDefaultVoiceInputWidget.d.ts +0 -2
  29. 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 { FunctionTypeVoidToVoid } from '../../../../Views/Base/BaseViewModel';
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
- // import CompanyLogo from '../../../layouts/TestStage/CompanyLogo/CompanyLogo';
54
+ import { loopToLimitTokens } from '../../../../../utils/utils';
51
55
 
52
56
  type HeaderDialogsMessagesProps = {
53
- // InputWidgetToLeftPlaceHolder?: InputWidget;
54
- // InputWidgetToRightPlaceHolder?: InputWidget;
55
- // IncomingMessageWidgetToRightPlaceHolder?: InputWidget;
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
- // InputWidgetToLeftPlaceHolder,
71
+ AIEditMessage,
68
72
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
69
- // InputWidgetToRightPlaceHolder,
73
+ AITranslation,
70
74
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
71
- // IncomingMessageWidgetToRightPlaceHolder,
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
- // IncomingMessageWidgetToRightPlaceHolder?.textToWidget(
361
- // message.message,
362
- // );
407
+ if (!waitAIWidget) {
408
+ setWaitAIWidget(true);
409
+ AIAnswerToMessage?.textToWidget(
410
+ message.message,
411
+ messageEntitiesToIChatMessageCollection(messagesToView),
412
+ );
413
+ }
363
414
  }}
364
415
  >
365
- {/* {IncomingMessageWidgetToRightPlaceHolder?.renderWidget()} */}
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
- // InputWidgetToRightPlaceHolder?.fileToWidget(voiceMessage);
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
- // useEffect(() => {
703
- // if (
704
- // InputWidgetToLeftPlaceHolder?.textToInput &&
705
- // InputWidgetToLeftPlaceHolder?.textToInput.length > 0
706
- // ) {
707
- // setMessageText(InputWidgetToLeftPlaceHolder?.textToInput);
708
- // setWidgetTextContent(InputWidgetToLeftPlaceHolder?.textToInput);
709
- // setTimeout(() => {
710
- // setWidgetTextContent('');
711
- // }, 45 * 1000);
712
- // }
713
- // }, [InputWidgetToLeftPlaceHolder?.textToInput]);
714
- //
715
- // useEffect(() => {
716
- // if (
717
- // InputWidgetToRightPlaceHolder?.textToInput &&
718
- // InputWidgetToRightPlaceHolder?.textToInput.length > 0
719
- // ) {
720
- // setMessageText(InputWidgetToRightPlaceHolder?.textToInput);
721
- // setWidgetTextContent(InputWidgetToRightPlaceHolder?.textToInput);
722
- // setTimeout(() => {
723
- // setWidgetTextContent('');
724
- // }, 45 * 1000);
725
- // }
726
- // }, [InputWidgetToRightPlaceHolder?.textToInput]);
727
- //
728
- // useEffect(() => {
729
- // if (
730
- // IncomingMessageWidgetToRightPlaceHolder?.textToInput &&
731
- // IncomingMessageWidgetToRightPlaceHolder?.textToInput.length > 0
732
- // ) {
733
- // setWidgetTextContent(
734
- // IncomingMessageWidgetToRightPlaceHolder?.textToInput,
735
- // );
736
- // setTimeout(() => {
737
- // setWidgetTextContent('');
738
- // }, 45 * 1000);
739
- // }
740
- // }, [IncomingMessageWidgetToRightPlaceHolder?.textToInput]);
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 InputWidgetToRightPlaceHolder */}
945
- {/* {InputWidgetToRightPlaceHolder && ( */}
999
+ {/* start AITranslation */}
1000
+ {/* {AITranslation && ( */}
946
1001
  {/* <div> */}
947
1002
  {/* <ActiveSvg */}
948
- {/* content={InputWidgetToRightPlaceHolder.renderWidget()} */}
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 InputWidgetToRightPlaceHolder */}
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
- {/* InputWidgetToRightPlaceHolder start InputWidgetToLeftPlaceHolder */}
1007
- {/* {InputWidgetToLeftPlaceHolder && ( */}
1061
+ {/* AITranslation start AIEditMessage */}
1062
+ {/* {AIEditMessage && ( */}
1008
1063
  {/* <div> */}
1009
1064
  {/* <ActiveSvg */}
1010
- {/* content={InputWidgetToLeftPlaceHolder.renderWidget()} */}
1065
+ {/* content={AIEditMessage.renderWidget()} */}
1011
1066
  {/* clickAction={() => { */}
1012
1067
  {/* console.log('click left place golder widget'); */}
1013
- {/* InputWidgetToLeftPlaceHolder?.textToWidget(messageText); */}
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
- // import { InputWidget } from '../../UI/Dialogs/MessagesView/InputWidget/InputWidget';
21
- // import useDefaultTextInputWidget from '../../UI/Dialogs/MessagesView/InputWidget/UseDefaultTextInputWidget';
22
- // import useDefaultVoiceInputWidget from '../../UI/Dialogs/MessagesView/InputWidget/useDefaultVoiceInputWidget';
23
- // import UseDefaultIncomingMessageWidget from '../../UI/Dialogs/MessagesView/InputWidget/UseDefaultIncomingMessageWidget';
24
- // import CompanyLogo from '../TestStage/CompanyLogo/CompanyLogo';
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
- // InputWidgetToLeftPlaceHolder?: InputWidget;
29
- // InputWidgetToRightPlaceHolder?: InputWidget;
30
- // IncomingMessageWidgetToRightPlaceHolder?: InputWidget;
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
- > = ({ theme = undefined }: QuickBloxUIKitDesktopLayoutProps) => {
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
- // let defaultLeftPlaceHolderInputWidget = InputWidgetToLeftPlaceHolder; // useDefaultTextInputWidget();
54
- //
55
- // if (!defaultLeftPlaceHolderInputWidget) {
56
- // defaultLeftPlaceHolderInputWidget = useDefaultTextInputWidget();
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
- // InputWidgetToLeftPlaceHolder={defaultLeftPlaceHolderInputWidget}
239
- // InputWidgetToRightPlaceHolder={defaultRightPlaceHolderInputWidget}
240
- // IncomingMessageWidgetToRightPlaceHolder={
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://myproxy.com',
17
- port: '4032',
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,2 +0,0 @@
1
- import { InputWidget } from './InputWidget';
2
- export default function useDefaultTextInputWidget(): InputWidget;
@@ -1,2 +0,0 @@
1
- import { InputWidget } from './InputWidget';
2
- export default function useDefaultVoiceInputWidget(): InputWidget;
@@ -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
-