@clikvn/agent-widget-embedded 0.0.1-dev

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 (130) hide show
  1. package/.eslintrc +34 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +20 -0
  4. package/base.json +21 -0
  5. package/dist/commons/constants/index.d.ts +2 -0
  6. package/dist/commons/constants/index.d.ts.map +1 -0
  7. package/dist/commons/constants/variables.d.ts +5 -0
  8. package/dist/commons/constants/variables.d.ts.map +1 -0
  9. package/dist/components/Agent/index.d.ts +3 -0
  10. package/dist/components/Agent/index.d.ts.map +1 -0
  11. package/dist/components/Chat/Chat.d.ts +10 -0
  12. package/dist/components/Chat/Chat.d.ts.map +1 -0
  13. package/dist/components/Chat/Icons.d.ts +120 -0
  14. package/dist/components/Chat/Icons.d.ts.map +1 -0
  15. package/dist/components/Chat/Markdown.d.ts +7 -0
  16. package/dist/components/Chat/Markdown.d.ts.map +1 -0
  17. package/dist/components/Chat/Message.d.ts +15 -0
  18. package/dist/components/Chat/Message.d.ts.map +1 -0
  19. package/dist/components/Chat/MultimodalInput.d.ts +24 -0
  20. package/dist/components/Chat/MultimodalInput.d.ts.map +1 -0
  21. package/dist/components/Chat/Overview.d.ts +8 -0
  22. package/dist/components/Chat/Overview.d.ts.map +1 -0
  23. package/dist/components/Chat/PreviewAttachment.d.ts +6 -0
  24. package/dist/components/Chat/PreviewAttachment.d.ts.map +1 -0
  25. package/dist/components/Chat/ui/Button.d.ts +12 -0
  26. package/dist/components/Chat/ui/Button.d.ts.map +1 -0
  27. package/dist/components/Chat/ui/Textarea.d.ts +6 -0
  28. package/dist/components/Chat/ui/Textarea.d.ts.map +1 -0
  29. package/dist/constants.d.ts +2 -0
  30. package/dist/constants.d.ts.map +1 -0
  31. package/dist/features/AgentWidget/index.d.ts +16 -0
  32. package/dist/features/AgentWidget/index.d.ts.map +1 -0
  33. package/dist/hooks/useChat.d.ts +25 -0
  34. package/dist/hooks/useChat.d.ts.map +1 -0
  35. package/dist/hooks/useChatData.d.ts +18 -0
  36. package/dist/hooks/useChatData.d.ts.map +1 -0
  37. package/dist/hooks/useConfiguration.d.ts +20 -0
  38. package/dist/hooks/useConfiguration.d.ts.map +1 -0
  39. package/dist/hooks/useConnection.d.ts +15 -0
  40. package/dist/hooks/useConnection.d.ts.map +1 -0
  41. package/dist/hooks/useScrollToBottom.d.ts +6 -0
  42. package/dist/hooks/useScrollToBottom.d.ts.map +1 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/models/FlowiseClient.d.ts +20 -0
  46. package/dist/models/FlowiseClient.d.ts.map +1 -0
  47. package/dist/models.d.ts +2 -0
  48. package/dist/models.d.ts.map +1 -0
  49. package/dist/register.d.ts +30 -0
  50. package/dist/register.d.ts.map +1 -0
  51. package/dist/services/apis.d.ts +7 -0
  52. package/dist/services/apis.d.ts.map +1 -0
  53. package/dist/services/bot.service.d.ts +3 -0
  54. package/dist/services/bot.service.d.ts.map +1 -0
  55. package/dist/services/chat.service.d.ts +32 -0
  56. package/dist/services/chat.service.d.ts.map +1 -0
  57. package/dist/services/user.service.d.ts +3 -0
  58. package/dist/services/user.service.d.ts.map +1 -0
  59. package/dist/types/agentType.d.ts +11 -0
  60. package/dist/types/agentType.d.ts.map +1 -0
  61. package/dist/types/bot.type.d.ts +11 -0
  62. package/dist/types/bot.type.d.ts.map +1 -0
  63. package/dist/types/chat.type.d.ts +10 -0
  64. package/dist/types/chat.type.d.ts.map +1 -0
  65. package/dist/types/common.type.d.ts +11 -0
  66. package/dist/types/common.type.d.ts.map +1 -0
  67. package/dist/types/flowise.type.d.ts +90 -0
  68. package/dist/types/flowise.type.d.ts.map +1 -0
  69. package/dist/types/user.type.d.ts +14 -0
  70. package/dist/types/user.type.d.ts.map +1 -0
  71. package/dist/types.d.ts +1 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/utils/commonUtils.d.ts +7 -0
  74. package/dist/utils/commonUtils.d.ts.map +1 -0
  75. package/dist/utils/functionUtils.d.ts +3 -0
  76. package/dist/utils/functionUtils.d.ts.map +1 -0
  77. package/dist/utils/requestUtils.d.ts +16 -0
  78. package/dist/utils/requestUtils.d.ts.map +1 -0
  79. package/dist/utils/streamUtils.d.ts +5 -0
  80. package/dist/utils/streamUtils.d.ts.map +1 -0
  81. package/dist/web.d.ts +18 -0
  82. package/dist/web.d.ts.map +1 -0
  83. package/dist/web.js +1 -0
  84. package/dist/window.d.ts +29 -0
  85. package/dist/window.d.ts.map +1 -0
  86. package/package.json +91 -0
  87. package/rollup.config.js +56 -0
  88. package/src/assets/common.css +148 -0
  89. package/src/assets/tailwindcss.css +3 -0
  90. package/src/commons/constants/index.ts +1 -0
  91. package/src/commons/constants/variables.ts +20 -0
  92. package/src/components/Agent/index.tsx +14 -0
  93. package/src/components/Chat/Chat.tsx +84 -0
  94. package/src/components/Chat/Icons.tsx +883 -0
  95. package/src/components/Chat/Markdown.tsx +324 -0
  96. package/src/components/Chat/Message.tsx +185 -0
  97. package/src/components/Chat/MultimodalInput.tsx +371 -0
  98. package/src/components/Chat/Overview.tsx +47 -0
  99. package/src/components/Chat/PreviewAttachment.tsx +41 -0
  100. package/src/components/Chat/ui/Button.tsx +55 -0
  101. package/src/components/Chat/ui/Textarea.tsx +23 -0
  102. package/src/constants.ts +1 -0
  103. package/src/env.d.ts +10 -0
  104. package/src/features/AgentWidget/index.tsx +47 -0
  105. package/src/global.d.ts +1 -0
  106. package/src/hooks/useChat.ts +225 -0
  107. package/src/hooks/useChatData.tsx +68 -0
  108. package/src/hooks/useConfiguration.tsx +54 -0
  109. package/src/hooks/useScrollToBottom.ts +31 -0
  110. package/src/index.ts +1 -0
  111. package/src/models/FlowiseClient.ts +103 -0
  112. package/src/models.ts +1 -0
  113. package/src/register.tsx +66 -0
  114. package/src/services/apis.ts +10 -0
  115. package/src/services/bot.service.ts +15 -0
  116. package/src/services/chat.service.ts +164 -0
  117. package/src/types/bot.type.ts +10 -0
  118. package/src/types/chat.type.ts +11 -0
  119. package/src/types/common.type.ts +11 -0
  120. package/src/types/flowise.type.ts +99 -0
  121. package/src/types/user.type.ts +15 -0
  122. package/src/types.ts +0 -0
  123. package/src/utils/commonUtils.ts +47 -0
  124. package/src/utils/functionUtils.ts +17 -0
  125. package/src/utils/requestUtils.ts +113 -0
  126. package/src/utils/streamUtils.ts +18 -0
  127. package/src/web.ts +6 -0
  128. package/src/window.ts +55 -0
  129. package/tailwind.config.cjs +122 -0
  130. package/tsconfig.json +24 -0
@@ -0,0 +1,164 @@
1
+ import FlowiseClient, { StreamResponse } from '../models/FlowiseClient';
2
+ import {
3
+ API_CHAT_MESSAGE,
4
+ API_CHATS,
5
+ API_CREATE_ATTACHMENTS,
6
+ API_PREDICTION,
7
+ API_VERSION,
8
+ } from './apis';
9
+ import { ChatRequestType, ChatType } from '../types/chat.type';
10
+ import { CommonChatType } from '../types/common.type';
11
+ import {
12
+ AttachmentUploadResult,
13
+ ChatMessageType,
14
+ PredictionData,
15
+ } from '../types/flowise.type';
16
+ import { request } from '../utils/requestUtils';
17
+
18
+ export const createChat = async ({
19
+ accessToken,
20
+ req,
21
+ apiHost,
22
+ }: {
23
+ accessToken?: string;
24
+ req: ChatRequestType;
25
+ apiHost: string;
26
+ }): Promise<ChatType> => {
27
+ const url = accessToken ? `${API_CHATS}` : `${API_VERSION}${API_CHATS}`;
28
+ let headers: any = {
29
+ 'Content-Type': 'application/json',
30
+ };
31
+ if (accessToken) {
32
+ headers = {
33
+ ...headers,
34
+ Authorization: `Bearer ${accessToken}`,
35
+ };
36
+ }
37
+
38
+ return request({
39
+ host: apiHost,
40
+ url,
41
+ headers,
42
+ method: 'POST',
43
+ body: JSON.stringify(req),
44
+ });
45
+ };
46
+
47
+ export const predict = async ({
48
+ accessToken,
49
+ req,
50
+ onUpdate,
51
+ apiHost,
52
+ }: {
53
+ accessToken?: string;
54
+ req: PredictionData;
55
+ apiHost: string;
56
+ onUpdate?: (chunk: StreamResponse) => void;
57
+ }): Promise<StreamResponse[]> => {
58
+ const url = accessToken
59
+ ? `${API_PREDICTION}`
60
+ : `${API_VERSION}${API_PREDICTION}`;
61
+ const result: any[] = [];
62
+ const flowise = new FlowiseClient({
63
+ baseUrl: url,
64
+ accessToken: accessToken,
65
+ host: apiHost,
66
+ });
67
+
68
+ try {
69
+ const completion: any = await flowise.createPrediction(req);
70
+ for await (const chunk of completion) {
71
+ result.push(chunk);
72
+ onUpdate?.(chunk);
73
+ }
74
+ } catch (error) {
75
+ console.error('Error:', error);
76
+ }
77
+
78
+ return result;
79
+ };
80
+
81
+ export const getChatMessage = async ({
82
+ accessToken,
83
+ chatId,
84
+ apiHost,
85
+ }: {
86
+ accessToken?: string;
87
+ chatId: string;
88
+ apiHost: string;
89
+ }): Promise<ChatMessageType[]> => {
90
+ const headers = accessToken
91
+ ? {
92
+ Authorization: `Bearer ${accessToken}`,
93
+ 'Content-Type': 'application/json',
94
+ }
95
+ : {};
96
+
97
+ const url = accessToken
98
+ ? `${API_CHAT_MESSAGE}/${chatId}`
99
+ : `${API_VERSION}${API_CHAT_MESSAGE}/${chatId}`;
100
+
101
+ return request({
102
+ host: apiHost,
103
+ url,
104
+ headers,
105
+ method: 'GET',
106
+ });
107
+ };
108
+
109
+ export const createAttachments = async ({
110
+ accessToken,
111
+ chatId,
112
+ body,
113
+ apiHost,
114
+ }: {
115
+ accessToken?: string;
116
+ chatId: string;
117
+ apiHost: string;
118
+ body: any;
119
+ }): Promise<AttachmentUploadResult[]> => {
120
+ const headers = accessToken
121
+ ? {
122
+ Authorization: `Bearer ${accessToken}`,
123
+ // 'Content-Type': 'application/json',
124
+ }
125
+ : {};
126
+ const url = accessToken
127
+ ? `${API_CREATE_ATTACHMENTS}/${chatId}`
128
+ : `${API_VERSION}${API_CREATE_ATTACHMENTS}/${chatId}`;
129
+
130
+ return request({
131
+ host: apiHost,
132
+ url,
133
+ headers,
134
+ method: 'POST',
135
+ body,
136
+ });
137
+ };
138
+
139
+ export const getById = async ({
140
+ accessToken,
141
+ id,
142
+ apiHost,
143
+ }: {
144
+ accessToken?: string;
145
+ id: string;
146
+ apiHost: string;
147
+ }): Promise<CommonChatType> => {
148
+ const headers = accessToken
149
+ ? {
150
+ Authorization: `Bearer ${accessToken}`,
151
+ 'Content-Type': 'application/json',
152
+ }
153
+ : {};
154
+ const url = accessToken
155
+ ? `${API_CHATS}/${id}`
156
+ : `${API_VERSION}${API_CHATS}/${id}`;
157
+
158
+ return request({
159
+ host: apiHost,
160
+ url,
161
+ headers,
162
+ method: 'GET',
163
+ });
164
+ };
@@ -0,0 +1,10 @@
1
+ export interface BotType {
2
+ id: string;
3
+ created: string;
4
+ lastModifiedDate: string;
5
+ name: string;
6
+ chatflowId: string;
7
+ chatflowConfig: any;
8
+ hidden: boolean;
9
+ avatar: string;
10
+ }
@@ -0,0 +1,11 @@
1
+ import { CommonChatType } from './common.type';
2
+ import { UserType } from './user.type';
3
+
4
+ export interface ChatType extends CommonChatType {
5
+ user: UserType;
6
+ }
7
+
8
+ export interface ChatRequestType {
9
+ title: string;
10
+ chatflowId?: string;
11
+ }
@@ -0,0 +1,11 @@
1
+ import { BotType } from './bot.type';
2
+
3
+ export interface CommonChatType {
4
+ id: string;
5
+ created?: Date;
6
+ lastModifiedDate?: Date;
7
+ title: string;
8
+ chatflowId: string;
9
+ type: 'PRIVATE' | 'ANONYMOUS';
10
+ bot: BotType;
11
+ }
@@ -0,0 +1,99 @@
1
+ export type MessageRoleType = 'apiMessage' | 'userMessage';
2
+
3
+ export interface PredictionData {
4
+ chatflowId?: string;
5
+ question: string;
6
+ overrideConfig?: Record<string, any>;
7
+ chatId?: string;
8
+ streaming?: boolean;
9
+ history?: IMessage[];
10
+ uploads?: IFileUpload[];
11
+ leadEmail?: string;
12
+ action?: IAction;
13
+ language?: string;
14
+ }
15
+
16
+ export interface ChatMessageType {
17
+ action?: IAction;
18
+ artifacts?: any;
19
+ chatId?: string;
20
+ chatType?: string;
21
+ chatflowid?: string;
22
+ content?: string;
23
+ createdDate?: string | Date;
24
+ followUpPrompts?: any;
25
+ id?: string;
26
+ leadEmail?: string;
27
+ role: MessageRoleType;
28
+ sessionId?: string;
29
+ usedTools?: ToolUsage[];
30
+ sourceDocuments?: SourceDocument[];
31
+ fileUploads?: IFileUpload[];
32
+ fileAnnotations?: FileAnnotation[];
33
+ agentReasoning?: AgentReasoning[];
34
+ }
35
+
36
+ export interface IAction {
37
+ id?: string;
38
+ elements?: Array<{
39
+ type: string;
40
+ label: string;
41
+ }>;
42
+ mapping?: {
43
+ approve: string;
44
+ reject: string;
45
+ toolCalls: any[];
46
+ };
47
+ }
48
+
49
+ export interface IFileUpload {
50
+ tempId?: string;
51
+ data?: string;
52
+ type: string;
53
+ name: string;
54
+ mime: string;
55
+ }
56
+
57
+ export interface IMessage {
58
+ message: string;
59
+ type: MessageRoleType;
60
+ role?: MessageRoleType;
61
+ content?: string;
62
+ }
63
+
64
+ export interface ToolUsage {
65
+ tool: string;
66
+ toolInput: {
67
+ input: string;
68
+ };
69
+ toolOutput: string;
70
+ }
71
+
72
+ export interface SourceDocument {
73
+ pageContent: string;
74
+ metadata: {
75
+ author: string;
76
+ date: string;
77
+ };
78
+ }
79
+
80
+ export interface AgentReasoning {
81
+ agentName: string;
82
+ messages: string[];
83
+ nodeName: string;
84
+ nodeId: string;
85
+ usedTools: ToolUsage[];
86
+ sourceDocuments: SourceDocument[];
87
+ }
88
+
89
+ export interface FileAnnotation {
90
+ filePath: string;
91
+ fileName: string;
92
+ }
93
+
94
+ export interface AttachmentUploadResult {
95
+ name: string;
96
+ mimeType: string;
97
+ size: string;
98
+ content: string;
99
+ }
@@ -0,0 +1,15 @@
1
+ import { CommonChatType } from './common.type';
2
+
3
+ export interface UserType {
4
+ id: string;
5
+ created?: Date;
6
+ lastModifiedDate?: Date;
7
+ phoneNumber?: string;
8
+ name?: string;
9
+ email: string;
10
+ userClik: number;
11
+ chats?: CommonChatType[];
12
+
13
+ user?: number;
14
+ authorities?: string[];
15
+ }
package/src/types.ts ADDED
File without changes
@@ -0,0 +1,47 @@
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export const cn = (...inputs: ClassValue[]) => {
5
+ return twMerge(clsx(inputs));
6
+ };
7
+
8
+ export function getLocalStorage(key: string) {
9
+ if (typeof window !== 'undefined') {
10
+ return JSON.parse(localStorage.getItem(key) || '[]');
11
+ }
12
+ return [];
13
+ }
14
+
15
+ export function generateUUID(): string {
16
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
17
+ const r = (Math.random() * 16) | 0;
18
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
19
+ return v.toString(16);
20
+ });
21
+ }
22
+
23
+ export const generateExtendedFileName = (originalFileName: string) => {
24
+ // Extract the name and extension from the original file name
25
+ const dotIndex = originalFileName.lastIndexOf('.');
26
+ const baseName =
27
+ dotIndex === -1
28
+ ? originalFileName
29
+ : originalFileName.substring(0, dotIndex);
30
+ const extension = dotIndex === -1 ? '' : originalFileName.substring(dotIndex);
31
+
32
+ // Get the current date and time
33
+ const now = new Date();
34
+ const year = now.getFullYear();
35
+ const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-11
36
+ const day = String(now.getDate()).padStart(2, '0');
37
+ const hours = String(now.getHours()).padStart(2, '0');
38
+ const minutes = String(now.getMinutes()).padStart(2, '0');
39
+ const seconds = String(now.getSeconds()).padStart(2, '0');
40
+
41
+ // Create the new unique file name
42
+ return `${baseName}_${year}${month}${day}_${hours}${minutes}${seconds}${extension}`;
43
+ };
44
+
45
+ export const sleep = async (duration: number): Promise<void> => {
46
+ return new Promise((resolve) => setTimeout(resolve, duration));
47
+ };
@@ -0,0 +1,17 @@
1
+ export const nonNull = (obj: any): boolean => {
2
+ return obj !== null && obj !== undefined;
3
+ };
4
+
5
+ export const toQuery = (params: any, delimiter = '&') => {
6
+ const keys = Object.keys(params);
7
+
8
+ return keys.reduce((str, key, index) => {
9
+ let query = `${str}${key}=${params[key]}`;
10
+
11
+ if (index < keys.length - 1) {
12
+ query += delimiter;
13
+ }
14
+
15
+ return query;
16
+ }, '');
17
+ };
@@ -0,0 +1,113 @@
1
+ import { BE_API, LANGUAGE_HEADER } from '../commons/constants';
2
+ import { processTextStream } from './streamUtils';
3
+
4
+ type RequestPropsTypes = {
5
+ host?: string;
6
+ url?: string;
7
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
8
+ streamProtocol?: 'data' | 'text';
9
+ onStreamUpdate?: (chunks: { content: string }[]) => void;
10
+ onStreamFinish?: (result: { content: string }) => void;
11
+ [x: string]: any;
12
+ };
13
+
14
+ const defaultHeaders = { 'Content-Type': 'application/json' };
15
+
16
+ export const request = async (props: RequestPropsTypes): Promise<any> => {
17
+ const {
18
+ host = BE_API,
19
+ url = '',
20
+ method = 'GET',
21
+ headers = { ...defaultHeaders, ...props.headers },
22
+ params,
23
+ streamProtocol,
24
+ onStreamUpdate,
25
+ onStreamFinish,
26
+ ...options
27
+ } = props;
28
+ let apiLanguage: string = LANGUAGE_HEADER.en;
29
+ if (headers?.language) {
30
+ apiLanguage = LANGUAGE_HEADER[headers.language];
31
+ }
32
+
33
+ const customHeader = { ...headers, language: apiLanguage };
34
+ const requestInit = {
35
+ method,
36
+ headers: customHeader,
37
+ ...options,
38
+ };
39
+
40
+ let queryString = '';
41
+ let apiUrl = '';
42
+
43
+ // Generate query string if params exist
44
+ if (!!params && !!Object.keys(params).length) {
45
+ queryString = Object.keys(params)
46
+ .filter((key) => !!params[key])
47
+ .map((key) => {
48
+ const val: string[] | string = params[key];
49
+ if (Array.isArray(val)) {
50
+ return val
51
+ .map((v) => `${encodeURIComponent(key)}=${encodeURIComponent(v)}`)
52
+ .join('&');
53
+ }
54
+
55
+ return `${encodeURIComponent(key)}=${encodeURIComponent(val)}`;
56
+ })
57
+ .join('&');
58
+
59
+ apiUrl = `${url}?${queryString}`;
60
+ }
61
+
62
+ try {
63
+ const response = await fetch(`${host}${apiUrl || url}`, {
64
+ ...requestInit,
65
+ });
66
+
67
+ if (!response.ok) {
68
+ console.error(
69
+ new Error(`API request failed with status ${response.status}`)
70
+ );
71
+ return null;
72
+ }
73
+
74
+ if (!response.body) {
75
+ console.error(new Error('The response body is empty.'));
76
+ return null;
77
+ }
78
+
79
+ if (!streamProtocol) {
80
+ return response.json();
81
+ }
82
+
83
+ switch (streamProtocol) {
84
+ case 'text': {
85
+ const resultMessage = {
86
+ content: '',
87
+ };
88
+
89
+ await processTextStream({
90
+ stream: response.body as any,
91
+ onTextPart: (chunk) => {
92
+ resultMessage.content += chunk;
93
+
94
+ // note: creating a new message object is required for Solid.js streaming
95
+ onStreamUpdate?.([{ ...resultMessage }]);
96
+ },
97
+ });
98
+
99
+ // in text mode, we don't have usage information or finish reason:
100
+ onStreamFinish?.(resultMessage);
101
+ return;
102
+ }
103
+
104
+ default: {
105
+ console.error(new Error(`Unknown stream protocol: ${streamProtocol}`));
106
+ return null;
107
+ }
108
+ }
109
+ } catch (error) {
110
+ console.error(error);
111
+ return null;
112
+ }
113
+ };
@@ -0,0 +1,18 @@
1
+ export const processTextStream = async ({
2
+ stream,
3
+ onTextPart,
4
+ }: {
5
+ stream: ReadableStream<Uint8Array>;
6
+ onTextPart: (chunk: string) => Promise<void> | void;
7
+ }): Promise<void> => {
8
+ const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
9
+
10
+ // eslint-disable-next-line no-constant-condition
11
+ while (true) {
12
+ const { done, value } = await reader.read();
13
+ if (done) {
14
+ break;
15
+ }
16
+ await onTextPart(value);
17
+ }
18
+ };
package/src/web.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { parseAgentVoice, injectAgentVoiceInWindow } from './window';
2
+
3
+ const agentVoice = parseAgentVoice();
4
+ injectAgentVoiceInWindow(agentVoice);
5
+
6
+ export default agentVoice;
package/src/window.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { agentWidgetElementName } from './constants';
2
+ import { registerWebComponents } from './register';
3
+ import { EVENT_TYPE } from './models';
4
+
5
+ let elementUsed: Element | undefined;
6
+
7
+ type VoiceAgentWidget = {
8
+ apiHost: string;
9
+ agentId: string;
10
+ overrideConfig?: {
11
+ chatId?: string | undefined;
12
+ } & Record<string, unknown>;
13
+ theme?: {
14
+ avatar?: string;
15
+ } & Record<string, unknown>;
16
+ listeners?: Record<EVENT_TYPE, (props: any) => void>;
17
+ };
18
+ export const initWidget = (props: VoiceAgentWidget & { id?: string }) => {
19
+ destroy();
20
+ const element: any = props.id
21
+ ? document.getElementById(props.id)
22
+ : document.querySelector(agentWidgetElementName);
23
+ if (!element) throw new Error(`${agentWidgetElementName} element not found.`);
24
+ if (customElements.get(agentWidgetElementName)) {
25
+ element.updateAttributes(props);
26
+ } else {
27
+ Object.assign(element, props);
28
+ registerWebComponents();
29
+ }
30
+ };
31
+
32
+ export const destroy = () => {
33
+ elementUsed?.remove();
34
+ };
35
+
36
+ type AgentWidget = {
37
+ initWidget: typeof initWidget;
38
+ destroy: typeof destroy;
39
+ };
40
+
41
+ declare const window:
42
+ | {
43
+ AgentWidget: AgentWidget | undefined;
44
+ }
45
+ | undefined;
46
+
47
+ export const parseAgentVoice = () => ({
48
+ initWidget,
49
+ destroy,
50
+ });
51
+
52
+ export const injectAgentVoiceInWindow = (agent: AgentWidget) => {
53
+ if (typeof window === 'undefined') return;
54
+ window.AgentWidget = { ...agent };
55
+ };
@@ -0,0 +1,122 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
2
+ const defaultTheme = require('tailwindcss/defaultTheme');
3
+
4
+ function rem2px(input, fontSize = 16) {
5
+ if (input == null) {
6
+ return input;
7
+ }
8
+ switch (typeof input) {
9
+ case 'object':
10
+ if (Array.isArray(input)) {
11
+ return input.map((val) => rem2px(val, fontSize));
12
+ }
13
+ // eslint-disable-next-line no-case-declarations
14
+ const ret = {};
15
+ for (const key in input) {
16
+ ret[key] = rem2px(input[key], fontSize);
17
+ }
18
+ return ret;
19
+ case 'string':
20
+ return input.replace(
21
+ /(\d*\.?\d+)rem$/,
22
+ (_, val) => `${parseFloat(val) * fontSize}px`
23
+ );
24
+ case 'function':
25
+ return eval(
26
+ input
27
+ .toString()
28
+ .replace(
29
+ /(\d*\.?\d+)rem/g,
30
+ (_, val) => `${parseFloat(val) * fontSize}px`
31
+ )
32
+ );
33
+ default:
34
+ return input;
35
+ }
36
+ }
37
+
38
+ /** @type {import('tailwindcss').Config} */
39
+ module.exports = {
40
+ darkMode: ['class'],
41
+ content: ['./src/**/*.{js,jsx,ts,tsx}'],
42
+ theme: {
43
+ ...rem2px(defaultTheme),
44
+ fontFamily: {
45
+ sans: ['Be Vietnam Pro', 'sans-serif'],
46
+ mono: ['Be Vietnam Pro', 'sans-serif'],
47
+ },
48
+ extend: {
49
+ keyframes: {
50
+ 'fade-in': {
51
+ '0%': {
52
+ opacity: '0',
53
+ },
54
+ '100%': {
55
+ opacity: '1',
56
+ },
57
+ },
58
+ },
59
+ animation: {
60
+ 'fade-in': 'fade-in 0.3s ease-out',
61
+ },
62
+ borderRadius: {
63
+ lg: 'var(--radius)',
64
+ md: 'calc(var(--radius) - 2px)',
65
+ sm: 'calc(var(--radius) - 4px)',
66
+ },
67
+ colors: {
68
+ background: 'hsl(var(--background))',
69
+ foreground: 'hsl(var(--foreground))',
70
+ card: {
71
+ DEFAULT: 'hsl(var(--card))',
72
+ foreground: 'hsl(var(--card-foreground))',
73
+ },
74
+ popover: {
75
+ DEFAULT: 'hsl(var(--popover))',
76
+ foreground: 'hsl(var(--popover-foreground))',
77
+ },
78
+ primary: {
79
+ DEFAULT: 'hsl(var(--primary))',
80
+ foreground: 'hsl(var(--primary-foreground))',
81
+ },
82
+ secondary: {
83
+ DEFAULT: 'hsl(var(--secondary))',
84
+ foreground: 'hsl(var(--secondary-foreground))',
85
+ },
86
+ muted: {
87
+ DEFAULT: 'hsl(var(--muted))',
88
+ foreground: 'hsl(var(--muted-foreground))',
89
+ },
90
+ accent: {
91
+ DEFAULT: 'hsl(var(--accent))',
92
+ foreground: 'hsl(var(--accent-foreground))',
93
+ },
94
+ destructive: {
95
+ DEFAULT: 'hsl(var(--destructive))',
96
+ foreground: 'hsl(var(--destructive-foreground))',
97
+ },
98
+ border: 'hsl(var(--border))',
99
+ input: 'hsl(var(--input))',
100
+ ring: 'hsl(var(--ring))',
101
+ chart: {
102
+ 1: 'hsl(var(--chart-1))',
103
+ 2: 'hsl(var(--chart-2))',
104
+ 3: 'hsl(var(--chart-3))',
105
+ 4: 'hsl(var(--chart-4))',
106
+ 5: 'hsl(var(--chart-5))',
107
+ },
108
+ sidebar: {
109
+ DEFAULT: 'hsl(var(--sidebar-background))',
110
+ foreground: 'hsl(var(--sidebar-foreground))',
111
+ primary: 'hsl(var(--sidebar-primary))',
112
+ 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
113
+ accent: 'hsl(var(--sidebar-accent))',
114
+ 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
115
+ border: 'hsl(var(--sidebar-border))',
116
+ ring: 'hsl(var(--sidebar-ring))',
117
+ },
118
+ },
119
+ },
120
+ },
121
+ plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
122
+ };