@clikvn/agent-widget-embedded 0.0.11-dev → 0.0.12-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 (52) hide show
  1. package/dist/components/Chat/MultimodalInput.d.ts.map +1 -1
  2. package/dist/index.html +52 -12
  3. package/dist/web.js +1 -1
  4. package/package.json +3 -3
  5. package/.eslintrc +0 -34
  6. package/.prettierrc +0 -8
  7. package/src/assets/common.css +0 -148
  8. package/src/assets/tailwindcss.css +0 -3
  9. package/src/commons/constants/index.ts +0 -1
  10. package/src/commons/constants/variables.ts +0 -25
  11. package/src/components/Agent/index.tsx +0 -14
  12. package/src/components/Chat/AudioPlayer.tsx +0 -44
  13. package/src/components/Chat/Chat.tsx +0 -91
  14. package/src/components/Chat/Icons.tsx +0 -1796
  15. package/src/components/Chat/Markdown.tsx +0 -335
  16. package/src/components/Chat/Message.tsx +0 -217
  17. package/src/components/Chat/MultimodalInput.tsx +0 -505
  18. package/src/components/Chat/Overview.tsx +0 -46
  19. package/src/components/Chat/PreviewAttachment.tsx +0 -46
  20. package/src/components/Chat/SuggestedActions.tsx +0 -99
  21. package/src/components/Chat/ui/Button.tsx +0 -55
  22. package/src/components/Chat/ui/Textarea.tsx +0 -23
  23. package/src/constants.ts +0 -1
  24. package/src/env.d.ts +0 -10
  25. package/src/features/AgentWidget/index.tsx +0 -63
  26. package/src/global.d.ts +0 -1
  27. package/src/hooks/useAudioRecording.ts +0 -50
  28. package/src/hooks/useChat.ts +0 -262
  29. package/src/hooks/useChatData.tsx +0 -68
  30. package/src/hooks/useConfiguration.tsx +0 -63
  31. package/src/hooks/useScrollToBottom.ts +0 -31
  32. package/src/index.ts +0 -1
  33. package/src/models/FlowiseClient.ts +0 -103
  34. package/src/models.ts +0 -1
  35. package/src/register.tsx +0 -85
  36. package/src/services/apis.ts +0 -12
  37. package/src/services/bot.service.ts +0 -15
  38. package/src/services/chat.service.ts +0 -199
  39. package/src/types/bot.type.ts +0 -10
  40. package/src/types/chat.type.ts +0 -11
  41. package/src/types/common.type.ts +0 -24
  42. package/src/types/flowise.type.ts +0 -108
  43. package/src/types/user.type.ts +0 -15
  44. package/src/types.ts +0 -0
  45. package/src/utils/audioRecording.ts +0 -371
  46. package/src/utils/commonUtils.ts +0 -47
  47. package/src/utils/functionUtils.ts +0 -17
  48. package/src/utils/requestUtils.ts +0 -113
  49. package/src/utils/streamUtils.ts +0 -18
  50. package/src/web.ts +0 -6
  51. package/src/window.ts +0 -43
  52. package/tsconfig.json +0 -24
@@ -1,335 +0,0 @@
1
- import React, { FC, memo, useMemo, useState } from 'react';
2
- import ReactMarkdown, { type Components } from 'react-markdown';
3
- import remarkGfm from 'remark-gfm';
4
- import { ToolUsage } from '../../types/flowise.type';
5
-
6
- const PlaceName = ({ name, data, ...props }: any) => {
7
- const [isDrawerOpen, setDrawerOpen] = useState(false);
8
-
9
- const toggleDrawer = (show: boolean) => {
10
- setDrawerOpen(show);
11
- };
12
-
13
- return (
14
- <div className="relative group">
15
- <a
16
- {...props}
17
- className="draggable-place relative -mx-1 -my-0.5 select-text items-baseline rounded-full px-1 py-0.5 font-semibold no-underline transition-colors hover:bg-foreground/5 data-[state=open]:bg-foreground/5"
18
- data-id={name}
19
- draggable="true"
20
- href={`/attractions/${name}`}
21
- onClick={(e) => {
22
- e.preventDefault();
23
- toggleDrawer(true);
24
- }}
25
- >
26
- <span className="whitespace-nowrap">
27
- <svg
28
- xmlns="http://www.w3.org/2000/svg"
29
- viewBox="0 0 24 24"
30
- fill="none"
31
- stroke="currentColor"
32
- stroke-width="1.5"
33
- stroke-linecap="round"
34
- stroke-linejoin="round"
35
- className="shrink-0 transform-cpu size-[1em] relative mr-0.5 mt-[-.125em] inline-block text-[1.25em]"
36
- >
37
- <path d="M18.75 9c0 3.735-6.75 12.75-6.75 12.75S5.25 12.735 5.25 9a6.75 6.75 0 0 1 13.5 0Z"></path>
38
- <path d="M12 11.25a2.25 2.25 0 1 0 0-4.5 2.25 2.25 0 0 0 0 4.5Z"></path>
39
- </svg>
40
- </span>
41
- <span>{name}</span>
42
- <span className="ml-0.5 whitespace-nowrap">
43
- <span>&#xFEFF;</span>
44
- <span className="relative top-[-.1em] inline-flex size-3 shrink-0 items-center justify-center rounded-full bg-added text-added-foreground">
45
- <svg
46
- xmlns="http://www.w3.org/2000/svg"
47
- width="7"
48
- height="7"
49
- viewBox="0 0 24 24"
50
- fill="none"
51
- stroke="currentColor"
52
- stroke-width="4"
53
- stroke-linecap="round"
54
- stroke-linejoin="round"
55
- className="shrink-0 transform-cpu"
56
- >
57
- <path d="m3.643 13.993 3.51 4.513a1.285 1.285 0 0 0 2.006.038L20.357 4.993"></path>
58
- </svg>
59
- </span>
60
- </span>
61
- </a>
62
- <div
63
- className="absolute left-1/4 translate-y-1/2 bottom-full mb-2 w-80
64
- invisible group-hover:visible opacity-0 group-hover:opacity-100
65
- bg-background border rounded-lg shadow-lg
66
- transition-opacity duration-300 z-10 hidden sm:block"
67
- >
68
- <div className="relative">
69
- {!!(data.photos && data.photos[0]) && (
70
- <img
71
- src={data.photos[0].url}
72
- alt="Card Image"
73
- className="border rounded-lg w-full h-48 object-cover"
74
- />
75
- )}
76
- </div>
77
-
78
- <div className="p-4">
79
- <div className="flex justify-between items-center mb-2">
80
- <h3 className="text-lg font-semibold">{data.name}</h3>
81
- <div className="flex items-center space-x-1">
82
- <svg
83
- xmlns="http://www.w3.org/2000/svg"
84
- fill="currentColor"
85
- className="w-5 h-5 text-yellow-500"
86
- viewBox="0 0 24 24"
87
- >
88
- <path d="M12 17.27l5.18 3.73-1.64-6.81L21 9.24l-7.19-.61L12 2 10.19 8.63 3 9.24l5.46 4.95-1.64 6.81L12 17.27z" />
89
- </svg>
90
- <span className="text-sm">{data.rating}</span>
91
- </div>
92
- </div>
93
-
94
- <p className="text-sm flex items-center">
95
- <svg
96
- xmlns="http://www.w3.org/2000/svg"
97
- fill="currentColor"
98
- className="w-5 h-5 mr-1"
99
- viewBox="0 0 24 24"
100
- >
101
- <path d="M12 2C8.69 2 6 4.69 6 8c0 5.25 6 12 6 12s6-6.75 6-12c0-3.31-2.69-6-6-6zm0 8.5c-1.38 0-2.5-1.12-2.5-2.5S10.62 5.5 12 5.5s2.5 1.12 2.5 2.5S13.38 10.5 12 10.5z" />
102
- </svg>
103
- {data.address}
104
- </p>
105
- </div>
106
- </div>
107
- {isDrawerOpen && (
108
- <div
109
- className="fixed bottom-0 left-0 w-full h-full bg-background border-t
110
- transform transition-transform duration-500 z-20 sm:hidden"
111
- >
112
- <div className="flex flex-col gap-2 p-4 pt-10 relative">
113
- <button
114
- className="font-bold absolute top-2 right-2"
115
- onClick={() => toggleDrawer(false)}
116
- >
117
- Close
118
- </button>
119
- <div className="relative">
120
- {!!(data.photos && data.photos[0]) && (
121
- <img
122
- src={data.photos[0].url}
123
- alt="Card Image"
124
- className="border rounded-lg w-full h-48 object-cover"
125
- />
126
- )}
127
- </div>
128
- <h3 className="text-lg font-semibold">{data.name}</h3>
129
- <p className="text-md">
130
- <div className="flex items-center space-x-1">
131
- <svg
132
- xmlns="http://www.w3.org/2000/svg"
133
- fill="currentColor"
134
- className="w-5 h-5 text-yellow-500"
135
- viewBox="0 0 24 24"
136
- >
137
- <path d="M12 17.27l5.18 3.73-1.64-6.81L21 9.24l-7.19-.61L12 2 10.19 8.63 3 9.24l5.46 4.95-1.64 6.81L12 17.27z" />
138
- </svg>
139
- <span className="text-md">{data.rating}</span>
140
- </div>
141
- </p>
142
- <p className="text-md flex items-center">
143
- <svg
144
- xmlns="http://www.w3.org/2000/svg"
145
- fill="currentColor"
146
- className="w-5 h-5 mr-1"
147
- viewBox="0 0 24 24"
148
- >
149
- <path d="M12 2C8.69 2 6 4.69 6 8c0 5.25 6 12 6 12s6-6.75 6-12c0-3.31-2.69-6-6-6zm0 8.5c-1.38 0-2.5-1.12-2.5-2.5S10.62 5.5 12 5.5s2.5 1.12 2.5 2.5S13.38 10.5 12 10.5z" />
150
- </svg>
151
- {data.address}
152
- </p>
153
- </div>
154
- </div>
155
- )}
156
- </div>
157
- );
158
- };
159
-
160
- const NonMemoizedMarkdown: FC<{
161
- children: string;
162
- usedTools?: ToolUsage[];
163
- }> = (props) => {
164
- const { children: content, usedTools } = props;
165
- const components: Partial<Components> = useMemo(() => {
166
- return {
167
- code: ({ node, inline, className, children, ...rest }: any) => {
168
- const match = /language-(\w+)/.exec(className || '');
169
- return !inline && match ? (
170
- <pre
171
- {...rest}
172
- className={`${className} text-sm w-[80dvw] md:max-w-[500px] overflow-x-scroll bg-zinc-100 p-3 rounded-lg mt-2 dark:bg-zinc-800`}
173
- >
174
- <code className={match[1]}>{children}</code>
175
- </pre>
176
- ) : (
177
- <code
178
- className={`${className} text-sm bg-zinc-100 dark:bg-zinc-800 py-0.5 px-1 rounded-md`}
179
- {...rest}
180
- >
181
- {children}
182
- </code>
183
- );
184
- },
185
- ol: ({ node, children, ...rest }) => {
186
- return (
187
- <ol className="list-decimal list-outside ml-4" {...rest}>
188
- {children}
189
- </ol>
190
- );
191
- },
192
- li: ({ node, children, ...rest }) => {
193
- return (
194
- <li className="py-1" {...rest}>
195
- {children}
196
- </li>
197
- );
198
- },
199
- ul: ({ node, children, ...rest }) => {
200
- return (
201
- <ul className="list-decimal list-outside ml-4" {...rest}>
202
- {children}
203
- </ul>
204
- );
205
- },
206
- strong: ({ node, children, ...rest }) => {
207
- let target = null;
208
- if (usedTools && usedTools.length && typeof children === 'string') {
209
- const targetTools = usedTools.filter(
210
- (usedTool) => usedTool.tool === 'search-traveling-places'
211
- );
212
- if (targetTools && targetTools.length) {
213
- targetTools.find((targetTool) => {
214
- try {
215
- target = JSON.parse(targetTool.toolOutput).find((i: any) => {
216
- const arr = i.description?.split('.') || [];
217
- return (
218
- (children as string).indexOf(i.name) >= 0 ||
219
- (arr[0] && arr[0].indexOf(children as string) >= 0)
220
- );
221
- });
222
- return !!target;
223
- } catch (e) {
224
- console.log(targetTool.toolOutput);
225
- return false;
226
- }
227
- });
228
- }
229
- }
230
- return target ? (
231
- <PlaceName name={children} data={target} {...rest} />
232
- ) : (
233
- <span className="font-semibold" {...rest}>
234
- {children}
235
- </span>
236
- );
237
- },
238
- a: ({ node, children, ...rest }) => {
239
- const content = children as string;
240
- const isImageUrl =
241
- content &&
242
- (content.indexOf('.jpg') >= 0 ||
243
- content.indexOf('.jpeg') >= 0 ||
244
- content.indexOf('.png') >= 0 ||
245
- content.indexOf('.gif') >= 0);
246
- const isAudioUrl =
247
- content &&
248
- (content.indexOf('.mp3') >= 0 ||
249
- content.indexOf('.wav') >= 0 ||
250
- content.indexOf('.ogg') >= 0);
251
- if (isAudioUrl) {
252
- return (
253
- <audio controls>
254
- <source src={content} />
255
- </audio>
256
- );
257
- } else if (isImageUrl) {
258
- return (
259
- <a href={content} target="_blank" rel="noopener noreferrer">
260
- <img
261
- src={content}
262
- alt={content}
263
- style={{ maxWidth: '100%', height: 'auto' }}
264
- />
265
- </a>
266
- );
267
- }
268
- return (
269
- <a
270
- className="text-blue-500 hover:underline"
271
- target="_blank"
272
- rel="noreferrer"
273
- {...rest}
274
- >
275
- {children}
276
- </a>
277
- );
278
- },
279
- h1: ({ node, children, ...rest }) => {
280
- return (
281
- <h1 className="text-3xl font-semibold mt-6 mb-2" {...rest}>
282
- {children}
283
- </h1>
284
- );
285
- },
286
- h2: ({ node, children, ...rest }) => {
287
- return (
288
- <h2 className="text-2xl font-semibold mt-6 mb-2" {...rest}>
289
- {children}
290
- </h2>
291
- );
292
- },
293
- h3: ({ node, children, ...rest }) => {
294
- return (
295
- <h3 className="text-xl font-semibold mt-6 mb-2" {...rest}>
296
- {children}
297
- </h3>
298
- );
299
- },
300
- h4: ({ node, children, ...rest }) => {
301
- return (
302
- <h4 className="text-lg font-semibold mt-6 mb-2" {...rest}>
303
- {children}
304
- </h4>
305
- );
306
- },
307
- h5: ({ node, children, ...rest }) => {
308
- return (
309
- <h5 className="text-base font-semibold mt-6 mb-2" {...rest}>
310
- {children}
311
- </h5>
312
- );
313
- },
314
- h6: ({ node, children, ...rest }) => {
315
- return (
316
- <h6 className="text-sm font-semibold mt-6 mb-2" {...rest}>
317
- {children}
318
- </h6>
319
- );
320
- },
321
- };
322
- }, [usedTools]);
323
- return (
324
- <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
325
- {content}
326
- </ReactMarkdown>
327
- );
328
- };
329
-
330
- export const Markdown = memo(
331
- NonMemoizedMarkdown,
332
- (prevProps, nextProps) =>
333
- prevProps.children === nextProps.children &&
334
- prevProps.usedTools === nextProps.usedTools
335
- );
@@ -1,217 +0,0 @@
1
- import { motion } from 'framer-motion';
2
- import { FC, useMemo } from 'react';
3
- import { SparklesIcon } from './Icons';
4
- import { Markdown } from './Markdown';
5
- import { PreviewAttachment } from './PreviewAttachment';
6
- import { BotType } from '../../types/bot.type';
7
- import {
8
- MessageRoleType,
9
- ChatMessageType,
10
- ToolUsage,
11
- } from '../../types/flowise.type';
12
- import { cn } from '../../utils/commonUtils';
13
- import AudioPlayer from './AudioPlayer';
14
- import { useConfiguration } from 'hooks/useConfiguration';
15
-
16
- type PropsType = {
17
- chatId?: string;
18
- message: ChatMessageType;
19
- isLoading: boolean;
20
- bot: BotType | null;
21
- enableTTS?: boolean;
22
- };
23
-
24
- const getRole = (role?: MessageRoleType) => {
25
- if (role && role === 'userMessage') {
26
- return 'user';
27
- }
28
-
29
- return 'assistant';
30
- };
31
-
32
- export const PreviewMessage: FC<PropsType> = ({
33
- chatId,
34
- message,
35
- isLoading,
36
- bot,
37
- enableTTS,
38
- }) => {
39
- const { theme } = useConfiguration();
40
- const parseOutput = (outputData: any) => {
41
- try {
42
- return JSON.parse(outputData);
43
- } catch (e) {
44
- return null;
45
- }
46
- };
47
-
48
- const usedTools = useMemo(() => {
49
- const customToolResults: ToolUsage[] = [];
50
- const toolResults: ToolUsage[] = [];
51
- (message.usedTools || []).forEach((useTool) => {
52
- if (useTool.tool === 'getWeather') {
53
- customToolResults.push(useTool);
54
- } else {
55
- toolResults.push(useTool);
56
- }
57
- });
58
- return { customToolResults, toolResults };
59
- }, [message.usedTools]);
60
-
61
- const role = useMemo(() => {
62
- return getRole(message.role);
63
- }, [message.role]);
64
-
65
- const assistantAvatar =
66
- role === 'user'
67
- ? theme?.userMessage?.avatarSrc
68
- : theme?.botMessage?.avatarSrc || bot?.avatar;
69
-
70
- return (
71
- <motion.div
72
- className="w-full mx-auto max-w-3xl px-4 group/message"
73
- initial={{ y: 5, opacity: 0 }}
74
- animate={{ y: 0, opacity: 1 }}
75
- data-role={role}
76
- >
77
- <div className="flex justify-end text-[14px]">
78
- {message?.fileUploads && !!message.fileUploads.length && (
79
- <PreviewAttachment attachment={message.fileUploads[0]} />
80
- )}
81
- </div>
82
- <div
83
- className={cn(
84
- `group-data-[role=user]/message:bg-primary group-data-[role=user]/message:text-primary-foreground flex gap-4 px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl py-2 rounded-xl `
85
- )}
86
- style={{
87
- backgroundColor:
88
- role === 'user'
89
- ? theme?.userMessage?.backgroundColor
90
- : theme?.botMessage?.backgroundColor || undefined,
91
- }}
92
- >
93
- {theme?.botMessage?.showAvatar && message.role === 'apiMessage' && (
94
- <div className="size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border">
95
- {assistantAvatar ? (
96
- <img
97
- src={assistantAvatar}
98
- alt={bot?.name ?? 'User Avatar'}
99
- width={24}
100
- height={24}
101
- className="rounded-full"
102
- />
103
- ) : (
104
- <SparklesIcon size={14} />
105
- )}
106
- </div>
107
- )}
108
-
109
- <div className="flex flex-col gap-2 w-full">
110
- {/*{message?.sourceDocuments && !!message.sourceDocuments.length && (*/}
111
- {/* <div className="w-full flex-wrap flex gap-4">*/}
112
- {/* {message.sourceDocuments.map((sourceDocument) => {*/}
113
- {/* return (*/}
114
- {/* <div key={sourceDocument.pageContent}>*/}
115
- {/* <DocumentToolCall*/}
116
- {/* pageContent={sourceDocument.pageContent}*/}
117
- {/* metadata={sourceDocument.metadata}*/}
118
- {/* />*/}
119
- {/* </div>*/}
120
- {/* );*/}
121
- {/* })}*/}
122
- {/* </div>*/}
123
- {/*)}*/}
124
- {/*{usedTools.toolResults && !!usedTools.toolResults.length && (*/}
125
- {/* <div className="w-full flex-wrap flex gap-4">*/}
126
- {/* {usedTools.toolResults.map((usedTool, index) => {*/}
127
- {/* const { tool } = usedTool;*/}
128
- {/* return (*/}
129
- {/* <div key={`${tool}-${index}`}>*/}
130
- {/* <ToolResult {...usedTool} />*/}
131
- {/* </div>*/}
132
- {/* );*/}
133
- {/* })}*/}
134
- {/* </div>*/}
135
- {/*)}*/}
136
- {/*{usedTools.customToolResults &&*/}
137
- {/* !!usedTools.customToolResults.length && (*/}
138
- {/* <div className="flex flex-col gap-4">*/}
139
- {/* {usedTools.customToolResults.map((usedTool, index) => {*/}
140
- {/* const { tool, toolOutput } = usedTool;*/}
141
- {/* const outputData = parseOutput(toolOutput);*/}
142
- {/* return (*/}
143
- {/* <div key={`${tool}-${index}`}>*/}
144
- {/* {!!outputData && tool === 'getWeather' ? (*/}
145
- {/* <Weather weatherAtLocation={outputData} />*/}
146
- {/* ) : null}*/}
147
- {/* </div>*/}
148
- {/* );*/}
149
- {/* })}*/}
150
- {/* </div>*/}
151
- {/* )}*/}
152
- {message.content && (
153
- <div
154
- className="flex flex-col gap-4"
155
- style={{
156
- color:
157
- getRole(message.role) === 'user'
158
- ? theme?.userMessage?.textColor
159
- : theme?.botMessage?.textColor || undefined,
160
- }}
161
- >
162
- <Markdown usedTools={message?.usedTools}>
163
- {message.content as string}
164
- </Markdown>
165
- </div>
166
- )}
167
- {message?.ttsUrl && (
168
- <AudioPlayer src={message.ttsUrl} autoplay={!!enableTTS} />
169
- )}
170
- </div>
171
- </div>
172
- </motion.div>
173
- );
174
- };
175
-
176
- export const ThinkingMessage = ({ bot }: { bot: BotType | null }) => {
177
- const role = 'assistant';
178
-
179
- const { theme } = useConfiguration();
180
-
181
- const assistantAvatar = theme?.botMessage?.avatarSrc || bot?.avatar;
182
-
183
- return (
184
- <motion.div
185
- className="w-full mx-auto max-w-3xl px-4 group/message "
186
- initial={{ y: 5, opacity: 0 }}
187
- animate={{ y: 0, opacity: 1, transition: { delay: 1 } }}
188
- data-role={role}
189
- >
190
- <div
191
- className={cn(
192
- 'flex gap-4 group-data-[role=user]/message:px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl group-data-[role=user]/message:py-2 rounded-xl',
193
- {
194
- 'group-data-[role=user]/message:bg-muted': true,
195
- }
196
- )}
197
- >
198
- {theme?.botMessage?.showAvatar && (
199
- <div className="size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border">
200
- <img
201
- src={assistantAvatar}
202
- alt={bot?.name ?? 'User Avatar'}
203
- width={24}
204
- height={24}
205
- className="rounded-full"
206
- />
207
- </div>
208
- )}
209
- <div className="flex flex-col gap-2 w-full">
210
- <div className="flex flex-col gap-4 text-muted-foreground">
211
- Thinking...
212
- </div>
213
- </div>
214
- </div>
215
- </motion.div>
216
- );
217
- };