yt-chat-components 1.4.9 → 1.5.1

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.4.9",
3
+ "version": "1.5.1",
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",
package/public/index.html CHANGED
@@ -111,7 +111,6 @@
111
111
  host-url="https://ai-api.yuntu.cn"
112
112
  sign-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/logo.png"
113
113
  app-id="5f48c683-38d8-430e-8479-17730a605821"
114
- user-info='{"id": "123", "name": "John Doe", "code":"1606451129" }'
115
114
  box-style='{"height":"100%","background":"url(https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/system/portal_bg_blue.png) center top / 100% 100% no-repeat"}'
116
115
  is-show-side-right=false
117
116
  is-show-side-left=true
@@ -37,7 +37,10 @@ for (let i = 1; i <= 68; i++) {
37
37
  }
38
38
 
39
39
  // 根据name生成固定的颜色索引
40
- const getAvatarByName = (name: string) => {
40
+ const getAvatar = (name: string, icon: string) => {
41
+ if(icon){
42
+ return <Avatar shape="square" src={icon} style={{marginRight: 8}}/>
43
+ }
41
44
  const total = name.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
42
45
  const index = total % avatarImages.length;
43
46
  const img = avatarImages[index];
@@ -315,6 +318,35 @@ export default function ChatMessage({
315
318
  return renderLoading(MessageType.url, 50);
316
319
  }
317
320
  }
321
+ else if (className && className.includes('language-image')) {
322
+ try {
323
+ // 解析代码块内容为 JSON 配置
324
+ const data = JSON.parse(children.toString().trim().replace(/\\n/g, '').replace('\n', ''));
325
+ const {url} = data;
326
+ // 渲染组件
327
+ return <Image
328
+ height={'auto'}
329
+ width={'100%'}
330
+ src={url}
331
+ alt={''}
332
+ fallback="data:image/png;base64,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"
333
+ />
334
+ } catch (error) {
335
+ return renderLoading(MessageType.url, 50);
336
+ }
337
+ }
338
+ else if (className && className.includes('language-video')) {
339
+ try {
340
+ // 解析代码块内容为 JSON 配置
341
+ const data = JSON.parse(children.toString().trim().replace(/\\n/g, '').replace('\n', ''));
342
+ const {url} = data;
343
+
344
+ // 渲染组件
345
+ return <video src={url} autoPlay={true} controls={false}/>
346
+ } catch (error) {
347
+ return renderLoading(MessageType.url, 50);
348
+ }
349
+ }
318
350
  // 默认渲染其他代码块
319
351
  return <code className={className} {...props}>{children}</code>;
320
352
  },
@@ -357,7 +389,7 @@ export default function ChatMessage({
357
389
 
358
390
  const renderBotTextMessage = () => {
359
391
  const items = messageItemList.map((item, index) => {
360
- const {id, thinkMessage, message, loadingMessage, type, name, toolCallInfo, rawInfo} = item;
392
+ const {id, thinkMessage, message, loadingMessage, type, name, icon, toolCallInfo, rawInfo} = item||{};
361
393
  const isLatestItem = index === messageItemList.length - 1;
362
394
  let status = 'success'
363
395
  // 只有在接收信息的时候有 pending 状态,最后的信息才为 pending
@@ -367,7 +399,7 @@ export default function ChatMessage({
367
399
 
368
400
  const resultItem: CustomThoughtChainItem = {
369
401
  title: <div style={{display:"flex", flexDirection: 'row', alignItems: 'center'}}>
370
- {getAvatarByName(name)}
402
+ {getAvatar(name, icon)}
371
403
  <span>{name}</span>
372
404
  </div>,
373
405
  description: toolCallInfo,
@@ -1,8 +1,9 @@
1
1
  .w_send_file_box {
2
- height: 23px;
2
+ height: 100%;
3
+ align-items: end;
4
+ padding-bottom: 16px;
3
5
  display: flex;
4
6
  background: transparent;
5
- align-items: center;
6
7
  justify-content: center;
7
8
  border-radius: 24px;
8
9
  font-size: 12px;
@@ -178,10 +179,11 @@
178
179
  */
179
180
 
180
181
  .w_send_voice_box {
181
- height: 23px;
182
+ height: 100%;
183
+ align-items: end;
184
+ padding-bottom: 16px;
182
185
  display: flex;
183
186
  background: transparent;
184
- align-items: center;
185
187
  justify-content: center;
186
188
  border-radius: 24px;
187
189
  font-size: 12px;
@@ -164,7 +164,7 @@ export default function ChatWindow({
164
164
  let content_ns: string = null
165
165
  let event_latest: string = null
166
166
  const nowAIContentListRef = useRef(nowAIContentList);
167
- const {registerChatMethods} = React.useContext(MethodContext);
167
+ const {registerChatMethods} = React.useContext(MethodContext) || {};
168
168
  let voiceChunks = []; // 临时存储录制的语音片段
169
169
  // 滚动事件处理,选择文件时,文件内容超出显示框时,显示左右箭头
170
170
  const handleScroll = () => {
@@ -206,7 +206,7 @@ export default function ChatWindow({
206
206
  }
207
207
  }
208
208
 
209
- const addMessageItem = ({chunk, id, name, status = null, isThinkChunk = false, loadingMessage = null}) => {
209
+ const addMessageItem = ({chunk, id, name, icon = null, status = null, isThinkChunk = false, loadingMessage = null}) => {
210
210
  // console.log("--- addMessageItem", chunk, status, loadingMessage)
211
211
  setNowAIContentList((prevState) => {
212
212
  const content = {}
@@ -221,6 +221,7 @@ export default function ChatWindow({
221
221
  const messageItem : MessageItem = {
222
222
  id,
223
223
  name,
224
+ icon,
224
225
  type: MessageType.text,
225
226
  toolCallInfo: status,
226
227
  loadingMessage,
@@ -251,6 +252,7 @@ export default function ChatWindow({
251
252
  const newMessageItem: MessageItem = {
252
253
  id: latestMessageItem.id === 'WAIT' ? content_id : latestMessageItem.id,
253
254
  name: latestMessageItem.name,
255
+ icon: latestMessageItem.icon,
254
256
  type: latestMessageItem.type,
255
257
  toolCallInfo: status,
256
258
  loadingMessage,
@@ -273,7 +275,7 @@ export default function ChatWindow({
273
275
  getHistoryList();
274
276
  }
275
277
  else if (event == 'token' || event == 't_full_token') {
276
- let { chunk, id, r_id, ns, name, loading_message } = data
278
+ let { chunk, id, r_id, ns, name, icon, loading_message } = data
277
279
  if (chunk.includes('```') && !chunk.startsWith('\n')) {
278
280
  // 确保 ``` 前有换行
279
281
  chunk = '\n' + chunk;
@@ -290,7 +292,7 @@ export default function ChatWindow({
290
292
  // 新建信息
291
293
  else{
292
294
  content_id = id
293
- addMessageItem({chunk, id, name, loadingMessage: loading_message || ''})
295
+ addMessageItem({chunk, id, name, icon, loadingMessage: loading_message || ''})
294
296
  }
295
297
  }
296
298
  // 输出主体没有变化
@@ -309,7 +311,7 @@ export default function ChatWindow({
309
311
  // if (event_latest === 'token' && event === 't_full_token'){
310
312
  // updateMessageItem({chunk, loadingMessage: loading_message || ''})
311
313
  // } else {
312
- // addMessageItem({chunk, id, name, loadingMessage:loading_message})
314
+ // addMessageItem({chunk, id, name, icon, loadingMessage:loading_message})
313
315
  // }
314
316
  // }else{
315
317
  updateMessageItem({chunk, loadingMessage: loading_message || ''})
@@ -328,7 +330,7 @@ export default function ChatWindow({
328
330
  content_ns = ns
329
331
  // 新建信息
330
332
  content_id = id
331
- addMessageItem({chunk, id, name, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
333
+ addMessageItem({chunk, id, name, icon, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
332
334
  }else {
333
335
  updateMessageItem({chunk, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
334
336
  }
@@ -350,7 +352,7 @@ export default function ChatWindow({
350
352
  }else{
351
353
  // 这个时候还没有信息的id,所以 content_id 给特殊值
352
354
  content_id = "WAIT"
353
- addMessageItem({chunk:"", id: "WAIT", name, status})
355
+ addMessageItem({chunk:"", id: "WAIT", name, icon, status})
354
356
  }
355
357
  }
356
358
  // 当前智能体在调用工具
@@ -957,7 +959,6 @@ export default function ChatWindow({
957
959
  }, [sessionId]);
958
960
 
959
961
  useEffect(() => {
960
- console.log("registerChatMethods",registerChatMethods)
961
962
  if (registerChatMethods) {
962
963
  registerChatMethods({
963
964
  isActiveMessage,
@@ -1252,10 +1253,11 @@ export default function ChatWindow({
1252
1253
  <button
1253
1254
  style={{
1254
1255
  ...(receivingMessage ? {cursor: 'pointer'} : {}),
1255
- padding: '0 13px',
1256
+ height:'100%',
1257
+ padding: '0 13px 16px',
1256
1258
  background: 'transparent',
1257
1259
  display: 'flex',
1258
- alignItems: 'center',
1260
+ alignItems: 'end',
1259
1261
  justifyContent: 'center'
1260
1262
  }}
1261
1263
  onClick={() => {
@@ -8,6 +8,7 @@ export enum MessageType {
8
8
  export type MessageItem = {
9
9
  id:string,
10
10
  name: string;
11
+ icon: string;
11
12
  thinkMessage: string;
12
13
  message: string;
13
14
  loadingMessage?: string;
@@ -2204,10 +2204,11 @@ export const yt_style = `
2204
2204
  }
2205
2205
 
2206
2206
  .w_send_file_box {
2207
- height: 23px;
2207
+ height: 100%;
2208
+ align-items: end;
2209
+ padding-bottom: 16px;
2208
2210
  display: flex;
2209
2211
  background: transparent;
2210
- align-items: center;
2211
2212
  justify-content: center;
2212
2213
  border-radius: 24px;
2213
2214
  font-size: 12px;
@@ -2441,10 +2442,11 @@ export const yt_style = `
2441
2442
  }
2442
2443
 
2443
2444
  .w_send_voice_box {
2444
- height: 23px;
2445
+ height: 100%;
2446
+ align-items: end;
2447
+ padding-bottom: 16px;
2445
2448
  display: flex;
2446
2449
  background: transparent;
2447
- align-items: center;
2448
2450
  justify-content: center;
2449
2451
  border-radius: 24px;
2450
2452
  font-size: 12px;
@@ -299,7 +299,7 @@ const api_key = 'sk-mniUFDpcWwvNF3iFzssXa6etN-S_Y4AApyHYcBU44L0';
299
299
  export const MethodContext = React.createContext();
300
300
 
301
301
  export class ToolDialogV2 extends React.Component {
302
-
302
+ sessionUserInfo = {};
303
303
  state = {
304
304
  historyList: [], // 历史对话列表
305
305
  sessionId: uuidv4(), // 当前激活的对话对应的sessionId
@@ -307,17 +307,26 @@ export class ToolDialogV2 extends React.Component {
307
307
  currentFlow: {},
308
308
  };
309
309
 
310
+ componentWillMount() {
311
+ const { userInfo = {} } = this.props;
312
+ const { sessionId } = this.state;
313
+ if (isEmpty(userInfo.code)) {
314
+ const code = sessionId.replaceAll("-", "").slice(2);
315
+ this.sessionUserInfo.code = code;
316
+ this.sessionUserInfo.id = code;
317
+ this.sessionUserInfo.name = code;
318
+ }else{
319
+ this.sessionUserInfo = userInfo;
320
+ }
321
+ }
322
+
310
323
  async componentDidMount() {
311
- this.getHistoryList({},true);
324
+ this.getHistoryList(true);
312
325
  }
313
326
 
314
327
  getCurrentFlowHistory=(flowId)=>{
315
- let { userInfo = {} } = this.props;
316
328
  const { sessionId } = this.state;
317
- if(isEmpty(userInfo.code)) {
318
- userInfo.code = sessionId;
319
- }
320
- const operationId = userInfo['code'] || '';
329
+ const operationId = this.sessionUserInfo['code'] || '';
321
330
  getHistoryList(this.props.hostUrl, flowId, operationId).then((res) => {
322
331
  if(res.status === 200 && typeof res.data !== "string" && typeof res.data !== "string"){
323
332
  this.setState({ historyList: res.data });
@@ -464,7 +473,7 @@ export class ToolDialogV2 extends React.Component {
464
473
  <div className="p_historyDialog">
465
474
  <div className="p_historyTitle">
466
475
  <div className="p_dialogTitle">对话列表</div>
467
- <HistoryOutlined style={{color:'#A4A4A4'}}/>
476
+ <Tooltip title={isEmpty(userInfo)?'当前历史记录将会在页面刷新后清除':'历史对话记录'}><HistoryOutlined style={{color:'#A4A4A4'}}/></Tooltip>
468
477
  </div>
469
478
  {this.state.historyList.length > 0 ? (
470
479
  <div className="p_historyList">
@@ -508,7 +517,7 @@ export class ToolDialogV2 extends React.Component {
508
517
  host_url={hostUrl}
509
518
  api_key={api_key}
510
519
  session_id={this.state.sessionId}
511
- userInfo={userInfo}
520
+ userInfo={this.sessionUserInfo}
512
521
  getHistoryList={this.getHistoryList}
513
522
  setDropDownList={(list) => this.setState({ dropDownList: list })}
514
523
  dropDownList={this.state.dropDownList}