yt-chat-components 1.3.0 → 1.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yt-chat-components",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "main": "build/static/js/bundle.min.js",
5
5
  "module": "build/static/js/bundle.min.js",
6
6
  "types": "build/static/js/index.d.ts",
@@ -6,7 +6,7 @@ import remarkGfm from 'remark-gfm';
6
6
  import rehypeMathjax from 'rehype-mathjax';
7
7
  // import './index.module.css';
8
8
  import upFilePng from '../../../../assets/aicenter/upfile.png';
9
- import {Button, Collapse, DatePicker, Form, Image, Input, message as messageTip, Select, Skeleton} from 'antd';
9
+ import {Button, Collapse, DatePicker, Form, Image, Input, message as messageTip, Select, Skeleton, Avatar} from 'antd';
10
10
  import React, {useRef, useState} from 'react';
11
11
  import typePdfPng from '../../../../assets/aicenter/type-pdf.png';
12
12
  import typeWordPng from '../../../../assets/aicenter/type-word.png';
@@ -30,6 +30,20 @@ const isEmpty = (o) => {
30
30
  return !o || (typeof o === 'object' && Object.keys(o).length === 0) || (typeof o === 'string' && o.trim().length === 0);
31
31
  }
32
32
 
33
+ // 使用 for 循环生成头像图片数组
34
+ const avatarImages = [];
35
+ for (let i = 1; i <= 68; i++) {
36
+ avatarImages.push(`https://ai-file.yuntu.cn/yt-ai/system/${i}.png`);
37
+ }
38
+
39
+ // 根据name生成固定的颜色索引
40
+ const getAvatarByName = (name: string) => {
41
+ const total = name.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
42
+ const index = total % avatarImages.length;
43
+ const img = avatarImages[index];
44
+ return <Avatar shape="square" src={img} style={{marginRight: 8}}/>
45
+ };
46
+
33
47
  export default function ChatMessage({
34
48
  receivingMessage,
35
49
  setReceivingMessage,
@@ -314,7 +328,10 @@ export default function ChatMessage({
314
328
  }
315
329
 
316
330
  const resultItem: ThoughtChainItem = {
317
- title: name,
331
+ title: <div style={{display:"flex", flexDirection: 'row', alignItems: 'center'}}>
332
+ {getAvatarByName(name)}
333
+ <span>{name}</span>
334
+ </div>,
318
335
  description: toolCallInfo,
319
336
  icon: getStatusIcon(status),
320
337
  status: status,
@@ -355,7 +372,7 @@ export default function ChatMessage({
355
372
  };
356
373
  return resultItem
357
374
  });
358
- return <ThoughtChain items={items} />
375
+ return <ThoughtChain items={items} size={'small'} />
359
376
  }
360
377
 
361
378
  const renderBotFormMessage = (form_config) => {
@@ -163,7 +163,7 @@ const extractAndParseJSON = (buffer, handleMessageContent) => {
163
163
  handleMessageContent(parsedJson['event'], parsedJson['data']);
164
164
  parsedData.push(parsedJson); // 添加到解析结果中
165
165
  } catch (error) {
166
- console.warn('无法解析 JSON 数据:', error);
166
+ console.warn('无法解析 JSON 数据:', error, jsonString);
167
167
  }
168
168
 
169
169
  // 更新剩余缓冲区的起始位置
@@ -83,6 +83,8 @@ export default function ChatWindow({
83
83
  modalWidth,
84
84
  isMobile = false,
85
85
  isShowChatHeader = true,
86
+ tipTitle,
87
+ tipContent,
86
88
  }: {
87
89
  is_enable_call:boolean;
88
90
  tags: [];
@@ -127,6 +129,8 @@ export default function ChatWindow({
127
129
  modalWidth: number;
128
130
  isMobile: boolean;
129
131
  isShowChatHeader: boolean;
132
+ tipTitle?: string;
133
+ tipContent?: string;
130
134
  }) {
131
135
  const ref = useRef<HTMLDivElement>(null);
132
136
  const lastMessage = useRef<HTMLDivElement>(null);
@@ -195,7 +199,7 @@ export default function ChatWindow({
195
199
  }
196
200
 
197
201
  const addMessageItem = ({chunk, id, name, status = null, isThinkChunk = false, loadingMessage = null}) => {
198
- // console.log("--- addMessageItem", chunk, status, loadingMessage)
202
+ // console.log("--- addMessageItem", chunk, status, loadingMessage)
199
203
  setNowAIContentList((prevState) => {
200
204
  const content = {}
201
205
  if(isThinkChunk){
@@ -220,7 +224,11 @@ export default function ChatWindow({
220
224
  }
221
225
 
222
226
  const updateMessageItem = ({chunk, status = null, isThinkChunk = false, loadingMessage = null}) => {
223
- // console.log("--- updateMessageItem", chunk, status)
227
+ // console.log("--- updateMessageItem", chunk, status, loadingMessage)
228
+ // chunk 和 status 都为空,则不更新
229
+ if(isEmpty(chunk) && isEmpty(status)){
230
+ return
231
+ }
224
232
  setNowAIContentList((prevState) => {
225
233
  const latestMessageItem = prevState[prevState.length - 1]
226
234
  const content = {}
@@ -251,7 +259,7 @@ export default function ChatWindow({
251
259
 
252
260
  // 流式输出消息,实时显示(token为流式输出内容,end为结束输出,整体输出一次)
253
261
  const handleMessageContent = (event, data) => {
254
- console.log("--- event, data",event, data)
262
+ // console.log(`--- event = ${event}, content_ns = ${content_ns}, content_id = ${content_id}, data = `, data)
255
263
 
256
264
  if (event == 'add_message' && data['sender'] == 'Machine') {
257
265
  getHistoryList();
@@ -269,12 +277,12 @@ export default function ChatWindow({
269
277
  // 如果刚才在调用工具,则追加信息
270
278
  if (content_id === 'WAIT'){
271
279
  content_id = id
272
- updateMessageItem({chunk, loadingMessage: loading_message})
280
+ updateMessageItem({chunk, loadingMessage: loading_message || ''})
273
281
  }
274
282
  // 新建信息
275
283
  else{
276
284
  content_id = id
277
- addMessageItem({chunk, id, name, loadingMessage:loading_message})
285
+ addMessageItem({chunk, id, name, loadingMessage: loading_message || ''})
278
286
  }
279
287
  }
280
288
  // 输出主体没有变化
@@ -291,20 +299,18 @@ export default function ChatWindow({
291
299
 
292
300
  // 如果 event_latest 是 token,此刻变成了 t_full_token,表示之前都在输出占位符,所以更新信息
293
301
  if (event_latest === 'token' && event === 't_full_token'){
294
- updateMessageItem({chunk, loadingMessage: loading_message})
302
+ updateMessageItem({chunk, loadingMessage: loading_message || ''})
295
303
  } else {
296
304
  addMessageItem({chunk, id, name, loadingMessage:loading_message})
297
305
  }
298
306
  }else{
299
- updateMessageItem({chunk, loadingMessage: loading_message})
307
+ updateMessageItem({chunk, loadingMessage: loading_message || ''})
300
308
  }
301
309
  }
302
310
 
303
311
  if (lastMessage.current) {
304
312
  lastMessage.current.scrollIntoView({ behavior: 'smooth' });
305
313
  }
306
-
307
-
308
314
  }
309
315
  else if (event == 't_token') {
310
316
  let { chunk, id, r_id, ns, name, loading_message } = data
@@ -314,9 +320,9 @@ export default function ChatWindow({
314
320
  content_ns = ns
315
321
  // 新建信息
316
322
  content_id = id
317
- addMessageItem({chunk, id, name, status:null, isThinkChunk:true, loadingMessage: loading_message})
323
+ addMessageItem({chunk, id, name, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
318
324
  }else {
319
- updateMessageItem({chunk, status:null, isThinkChunk:true, loadingMessage: loading_message})
325
+ updateMessageItem({chunk, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
320
326
  }
321
327
 
322
328
  if (lastMessage.current) {
@@ -325,14 +331,14 @@ export default function ChatWindow({
325
331
  }
326
332
  else if (event == 'status') {
327
333
  // 更新状态
328
- const {r_id, id, ns, name, status} = data
334
+ const {r_id, id, ns, name, status, loading_message} = data
329
335
 
330
336
  // ns变化表示切换了智能体,表示智能体一上来就调用工具
331
337
  if (content_ns !== ns){
332
338
  content_ns = ns
333
339
  // 表示智能体连续调用工具
334
340
  if (content_id === 'WAIT') {
335
- updateMessageItem({chunk:"", status, loadingMessage: loading_message})
341
+ updateMessageItem({chunk:"", status, loadingMessage: loading_message || ''})
336
342
  }else{
337
343
  // 这个时候还没有信息的id,所以 content_id 给特殊值
338
344
  content_id = "WAIT"
@@ -341,7 +347,7 @@ export default function ChatWindow({
341
347
  }
342
348
  // 当前智能体在调用工具
343
349
  else{
344
- updateMessageItem({chunk:"", status, loadingMessage: loading_message})
350
+ updateMessageItem({chunk:"", status, loadingMessage: loading_message || ''})
345
351
  }
346
352
 
347
353
  setAiStatus(data.status)
@@ -836,7 +842,7 @@ export default function ChatWindow({
836
842
  */
837
843
  useEffect(() => {
838
844
  if (lastMessage.current) lastMessage.current.scrollIntoView({ behavior: 'smooth' });
839
- }, [messages]);
845
+ }, [nowAIContentList]);
840
846
 
841
847
  /* Refocus the User input whenever a new response is returned from the LLM */
842
848
 
@@ -863,7 +869,7 @@ export default function ChatWindow({
863
869
  let current_r_id: string = null
864
870
  let current_sender: string = null
865
871
  chatHistory.forEach((data) => {
866
- const {sender, sender_name, text, id, category, r_id, error} = data;
872
+ const {sender, sender_name, text, id, category, r_id, error, reasoning_content} = data;
867
873
  // r_id 不一样表示切换了对话轮次,则新增一个 ChatMessageType
868
874
  if(current_r_id != r_id){
869
875
  current_r_id = r_id
@@ -894,6 +900,7 @@ export default function ChatWindow({
894
900
  id: id,
895
901
  name: sender_name,
896
902
  message: text,
903
+ thinkMessage: reasoning_content,
897
904
  // rawInfo: data,
898
905
  type: MessageType.text,
899
906
  });
@@ -945,7 +952,10 @@ export default function ChatWindow({
945
952
  return (
946
953
  <div className={'cl-tips-wrapper'}>
947
954
  <img className="drop-man-img" src={dropManUrl}/>
948
- <div className="drop-down-title"><strong>Hi,</strong><br/><strong>欢迎使用{window_title}!</strong><br/><div style={{fontSize:'14px'}}>您可以这样问我:</div></div>
955
+ <div className="drop-down-title">
956
+ <strong>Hi,</strong><br/><strong>{tipTitle || `欢迎使用${window_title}!`}</strong><br/>
957
+ <div style={{fontSize:'14px'}}>{tipTitle || `您可以这样问我:`}</div>
958
+ </div>
949
959
  <div className={'cl-drop-down-mobile'}>
950
960
  <div className="drop-down-list-mobile">
951
961
  {dropDownList.map(({backgroundImg, title}) => (
@@ -976,7 +986,7 @@ export default function ChatWindow({
976
986
  if (isEmpty(dropManUrl)){
977
987
  return (
978
988
  <div className='cl-drop-down'>
979
- <div className="drop-down-title">Hi,欢迎使用{window_title},您可以这样问我:</div>
989
+ <div className="drop-down-title">Hi{tipTitle || `欢迎使用${window_title}`},{tipContent || '您可以这样问我:'}</div>
980
990
  <div className="drop-down-list">
981
991
  {dropDownList.map(({backgroundImg, title}) => (
982
992
  <div className="drop-down-item-card" key={title}>
@@ -1010,7 +1020,7 @@ export default function ChatWindow({
1010
1020
  <div className={judgeDropClass()}>
1011
1021
  <img className="drop-man-img" src={dropManUrl}/>
1012
1022
  <div className='cl-drop-down'>
1013
- <div className="drop-down-title">Hi,欢迎使用{window_title},您可以这样问我:</div>
1023
+ <div className="drop-down-title">Hi{tipTitle || `欢迎使用${window_title}`},{tipContent || '您可以这样问我:'}</div>
1014
1024
  <div className="drop-down-list">
1015
1025
  {dropDownList.map(({backgroundImg, title}) => (
1016
1026
  <div
@@ -45,6 +45,8 @@ export default function ChatWidget({
45
45
  modalWidth,
46
46
  isMobile = false,
47
47
  isShowChatHeader = true,
48
+ tipTitle,
49
+ tipContent,
48
50
  }: {
49
51
  is_enable_call:boolean,
50
52
  tags: [];
@@ -85,6 +87,8 @@ export default function ChatWidget({
85
87
  modalWidth: number;
86
88
  isMobile: boolean;
87
89
  isShowChatHeader: boolean;
90
+ tipTitle: string,
91
+ tipContent: string,
88
92
  }) {
89
93
  const [open, setOpen] = useState(start_open);
90
94
  const [messages, setMessages] = useState<ChatMessageType[]>([]);
@@ -157,6 +161,8 @@ export default function ChatWidget({
157
161
  modalWidth={modalWidth}
158
162
  isMobile={isMobile}
159
163
  isShowChatHeader={isShowChatHeader}
164
+ tipTitle={tipTitle}
165
+ tipContent={tipContent}
160
166
  />
161
167
  </div>
162
168
  );
@@ -2459,5 +2459,20 @@ export const yt_style = `
2459
2459
  background: #1552FF;
2460
2460
  border-radius: 8px;
2461
2461
  }
2462
- `
2463
2462
 
2463
+ .ant-thought-chain-item-title{
2464
+ max-height: 32px !important;
2465
+ height: 32px !important;
2466
+ }
2467
+
2468
+ .ant-thought-chain-item-icon{
2469
+ margin-top: 6px !important;
2470
+ }
2471
+
2472
+ .ant-thought-chain-item-header::before {
2473
+ top: 6px !important;
2474
+ }
2475
+ .ant-thought-chain-item-content::before {
2476
+ height: 55px !important;
2477
+ }
2478
+ `
@@ -382,8 +382,6 @@ export class MobileChatPage extends React.Component {
382
382
 
383
383
  setWindowTitle = (title) => {
384
384
  if (!isEmpty(title)){
385
- document.title = 'AI校园智多星';
386
- window.document.title = 'AI校园智多星';
387
385
  }
388
386
  }
389
387
 
@@ -499,6 +497,8 @@ export class MobileChatPage extends React.Component {
499
497
  isLogin = false,
500
498
  isShowLogin = false,
501
499
  loginBtnClick,
500
+ tipTitle,
501
+ tipContent
502
502
  } = this.props;
503
503
  const { sceneInfo, currentFlow = {} } = this.state;
504
504
  const { flows = [], name: sceneName, character } = sceneInfo;
@@ -771,6 +771,8 @@ export class MobileChatPage extends React.Component {
771
771
  modalWidth={modalWidth}
772
772
  isMobile={true}
773
773
  isShowChatHeader={false}
774
+ tipTitle={tipTitle}
775
+ tipContent={tipContent}
774
776
  />
775
777
  </div>
776
778
  {