yt-chat-components 1.5.2 → 1.5.4

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.5.2",
3
+ "version": "1.5.4",
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,8 +111,8 @@
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
- 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"}'
115
- is-show-side-right=false
114
+ box-style='{"height":"100%","minWidth": "1380px","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"}'
115
+ is-show-side-right=true
116
116
  is-show-side-left=true
117
117
  dialog-index="999999999"
118
118
  agent-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/kai_yuan/byz/xinge.png"
@@ -122,7 +122,6 @@
122
122
  is-title-side-icon=true
123
123
  is-show-upload-button=false
124
124
  drop-man-url="https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/ai/ai_man01.png"
125
- banner-map='{"a":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/banner.png","b":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/banner.png","c":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/banner.png"}'
126
125
  asset-map='{"sendMessageUrl":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/sendMessage.png","stopMessageUrl":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/stopMessage.png","speakUrl":"https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/speak.png"}'
127
126
  />
128
127
  </body>
@@ -67,7 +67,7 @@ export class StreamAudioPlayer {
67
67
  this.pendingBufferSizeSec += durationSec;
68
68
 
69
69
  // 如果累计 ≥ 0.5s 才创建 buffer 并推入队列
70
- if (this.pendingBufferSizeSec >= 0.5) {
70
+ if (this.pendingBufferSizeSec >= 0.3) {
71
71
  const totalLength = this.pendingBuffer.reduce((sum, b) => sum + b.length, 0);
72
72
  const mergedChannel = new Float32Array(totalLength);
73
73
 
@@ -249,11 +249,11 @@ export async function getFlowInfo(baseUrl: string, flowId: string, api_key: stri
249
249
  return axios.get(`${baseUrl}/api/t1/flow/detail/${flowId}`,{headers});
250
250
  }
251
251
 
252
- export async function getKnowledgeInfo(baseUrl: string, flowId: string, api_key: string) {
252
+ export async function getQaInfo(baseUrl: string, flowId: string, api_key: string) {
253
253
  const headers = {
254
254
  'Content-Type': 'multipart/form-data',
255
255
  'x-api-key': api_key,
256
256
  timeout:600000
257
257
  };
258
- return axios.get(`${baseUrl}/api/t1/knowledge/detail/${flowId}`,{headers});
258
+ return axios.get(`${baseUrl}/api/t1/qa_doc/find_doc_by_flow_id/${flowId}`,{headers});
259
259
  }
@@ -153,6 +153,7 @@ export default function ChatWindow({
153
153
  { file: File; fileUrl: string; fileType: string; fileId: string }[]
154
154
  >([]);
155
155
  const scrollContainerRef = useRef(null);
156
+ const sessionIdRef = useRef(null);
156
157
  const [showLeftArrow, setShowLeftArrow] = useState(false); // 控制左侧箭头显示
157
158
  const [showRightArrow, setShowRightArrow] = useState(false); // 控制右侧箭头显示
158
159
  const isStream = true;//是否流式输出(手动开关)
@@ -189,7 +190,7 @@ export default function ChatWindow({
189
190
  if (delayMessageList.length > 0) {
190
191
  const data = delayMessageList.shift();
191
192
  const {r_id, form_config} = data;
192
- updateMessageItem({chunk:"\n```form\n" + JSON.stringify(form_config) + "\n```\n"})
193
+ updateMessageItem({updateSrc: "7", chunk:"\n```form\n" + JSON.stringify(form_config) + "\n```\n"})
193
194
 
194
195
  // ?????? done
195
196
  // addMessage({
@@ -206,8 +207,8 @@ export default function ChatWindow({
206
207
  }
207
208
  }
208
209
 
209
- const addMessageItem = ({chunk, id, name, icon = null, status = null, isThinkChunk = false, loadingMessage = null}) => {
210
- // console.log("--- addMessageItem", chunk, status, loadingMessage)
210
+ const addMessageItem = ({addSrc = null, chunk, id, name, icon = null, status = null, isThinkChunk = false, loadingMessage = null}) => {
211
+ // console.log("--- addMessageItem", addSrc, chunk, status, loadingMessage)
211
212
  setNowAIContentList((prevState) => {
212
213
  const content = {}
213
214
  if(isThinkChunk){
@@ -232,8 +233,8 @@ export default function ChatWindow({
232
233
  })
233
234
  }
234
235
 
235
- const updateMessageItem = ({chunk, status = null, isThinkChunk = false, loadingMessage = null}) => {
236
- // console.log("--- updateMessageItem", chunk, status, loadingMessage)
236
+ const updateMessageItem = ({updateSrc = null, chunk, status = null, isThinkChunk = false, loadingMessage = null}) => {
237
+ // console.log("--- updateMessageItem", updateSrc, chunk, status, loadingMessage)
237
238
  // chunk 和 status 都为空,则不更新
238
239
  if(isEmpty(chunk) && isEmpty(status)){
239
240
  return
@@ -286,12 +287,12 @@ export default function ChatWindow({
286
287
  // 如果刚才在调用工具,则追加信息
287
288
  if (content_id === 'WAIT'){
288
289
  content_id = id
289
- updateMessageItem({chunk, loadingMessage: loading_message || ''})
290
+ updateMessageItem({updateSrc: "1", chunk, loadingMessage: loading_message || ''})
290
291
  }
291
292
  // 新建信息
292
293
  else{
293
294
  content_id = id
294
- addMessageItem({chunk, id, name, icon, loadingMessage: loading_message || ''})
295
+ addMessageItem({addSrc: "1", chunk, id, name, icon, loadingMessage: loading_message || ''})
295
296
  }
296
297
  }
297
298
  // 输出主体没有变化
@@ -303,18 +304,18 @@ export default function ChatWindow({
303
304
  }
304
305
 
305
306
  // id切换表示一句话说完了, 新增信息
306
- // if (content_id !== id){
307
- // content_id = id
308
- //
309
- // // 如果 event_latest 是 token,此刻变成了 t_full_token,表示之前都在输出占位符,所以更新信息
310
- // if (event_latest === 'token' && event === 't_full_token'){
311
- // updateMessageItem({chunk, loadingMessage: loading_message || ''})
312
- // } else {
313
- // addMessageItem({chunk, id, name, icon, loadingMessage:loading_message})
314
- // }
315
- // }else{
316
- updateMessageItem({chunk, loadingMessage: loading_message || ''})
317
- // }
307
+ if (content_id !== id){
308
+ content_id = id
309
+
310
+ // 如果 event_latest 是 token,此刻变成了 t_full_token,表示之前都在输出占位符,所以更新信息
311
+ if (event_latest === 'token' && event === 't_full_token'){
312
+ updateMessageItem({updateSrc: "2", chunk, loadingMessage: loading_message || ''})
313
+ } else {
314
+ addMessageItem({addSrc: "2", chunk, id, name, icon, loadingMessage:loading_message})
315
+ }
316
+ }else{
317
+ updateMessageItem({updateSrc: "3", chunk, loadingMessage: loading_message || ''})
318
+ }
318
319
  }
319
320
 
320
321
  if (lastMessage.current) {
@@ -322,16 +323,16 @@ export default function ChatWindow({
322
323
  }
323
324
  }
324
325
  else if (event == 't_token') {
325
- let { chunk, id, r_id, ns, name, loading_message } = data
326
+ let { chunk, id, r_id, ns, name, icon, loading_message } = data
326
327
 
327
328
  // ns切换表示切换了智能体
328
329
  if (content_ns !== ns){
329
330
  content_ns = ns
330
331
  // 新建信息
331
332
  content_id = id
332
- addMessageItem({chunk, id, name, icon, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
333
+ addMessageItem({addSrc: "3", chunk, id, name, icon, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
333
334
  }else {
334
- updateMessageItem({chunk, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
335
+ updateMessageItem({updateSrc: "4", chunk, status:null, isThinkChunk:true, loadingMessage: loading_message || ''})
335
336
  }
336
337
 
337
338
  if (lastMessage.current) {
@@ -340,23 +341,23 @@ export default function ChatWindow({
340
341
  }
341
342
  else if (event == 'status') {
342
343
  // 更新状态
343
- const {r_id, id, ns, name, status, loading_message} = data
344
+ const {r_id, id, ns, name, icon, status, loading_message} = data
344
345
 
345
346
  // ns变化表示切换了智能体,表示智能体一上来就调用工具
346
347
  if (content_ns !== ns){
347
348
  content_ns = ns
348
349
  // 表示智能体连续调用工具
349
350
  if (content_id === 'WAIT') {
350
- updateMessageItem({chunk:"", status, loadingMessage: loading_message || ''})
351
+ updateMessageItem({updateSrc: "5", chunk:"", status, loadingMessage: loading_message || ''})
351
352
  }else{
352
353
  // 这个时候还没有信息的id,所以 content_id 给特殊值
353
354
  content_id = "WAIT"
354
- addMessageItem({chunk:"", id: "WAIT", name, icon, status})
355
+ addMessageItem({addSrc: "4", chunk:"", id: "WAIT", name, icon, status})
355
356
  }
356
357
  }
357
358
  // 当前智能体在调用工具
358
359
  else{
359
- updateMessageItem({chunk:"", status, loadingMessage: loading_message || ''})
360
+ updateMessageItem({updateSrc: "6", chunk:"", status, loadingMessage: loading_message || ''})
360
361
  }
361
362
 
362
363
  setAiStatus(data.status)
@@ -529,7 +530,7 @@ export default function ChatWindow({
529
530
 
530
531
  let userInfoClone = {...userInfo};
531
532
  if(isEmpty(userInfoClone.code)) {
532
- userInfoClone.code = sessionId;
533
+ userInfoClone.code = sessionIdRef.current;
533
534
  }
534
535
  const code = userInfoClone['code'] ? userInfoClone['code'] : ""
535
536
  const name = userInfoClone['name'] ? userInfoClone['name'] : ""
@@ -573,7 +574,7 @@ export default function ChatWindow({
573
574
  message,
574
575
  input_type,
575
576
  output_type,
576
- sessionId,
577
+ sessionIdRef.current,
577
578
  output_component,
578
579
  tweaks,
579
580
  api_key,
@@ -598,13 +599,13 @@ export default function ChatWindow({
598
599
  isSend: false
599
600
  });
600
601
  }else if (e.name !== 'AbortError') {
601
- messageTip.error('网络请求错误,请重试');
602
+ messageTip.error('当前网络繁忙,请稍后重试');
602
603
  // ?????? done
603
604
  addMessage({
604
605
  messageItemList: [{
605
606
  id:new Date().getTime() + '',
606
607
  name: "AI",
607
- message: "网络请求错误,请重试",
608
+ message: "当前网络繁忙,请稍后重试",
608
609
  type: MessageType.text,
609
610
  }],
610
611
  isSend: false
@@ -895,9 +896,9 @@ export default function ChatWindow({
895
896
  try {
896
897
  let userInfoClone = userInfo;
897
898
  if(isEmpty(userInfoClone.code)) {
898
- userInfoClone.code = sessionId;
899
+ userInfoClone.code = sessionIdRef.current;
899
900
  }
900
- const res = await getChatHistory(hostUrl, flowId, sessionId, userInfoClone['code']);
901
+ const res = await getChatHistory(hostUrl, flowId, sessionIdRef.current, userInfoClone['code']);
901
902
  const chatHistory = res.data?.length ? res.data : [];
902
903
 
903
904
  // 这里是多轮对话全量的信息,应该逐条处理成最终结果
@@ -957,6 +958,7 @@ export default function ChatWindow({
957
958
  * 当获取历史记录时(sessindId变化时),清空消息,并添加历史记录
958
959
  */
959
960
  useEffect(() => {
961
+ sessionIdRef.current = sessionId;
960
962
  fetchChatHistory().then();
961
963
 
962
964
  return () => {
@@ -999,7 +1001,7 @@ export default function ChatWindow({
999
1001
  * 对话是否处于活跃状态
1000
1002
  * */
1001
1003
  const isActiveMessage = useCallback(() => {
1002
- return !!receivingMessageRef.current;
1004
+ return receivingMessageRef.current;
1003
1005
  }, []);
1004
1006
 
1005
1007
  const renderTipsInfo = () => {
@@ -100,7 +100,6 @@ export default function ChatWidget({
100
100
  }) {
101
101
  const [open, setOpen] = useState(start_open);
102
102
  const [messages, setMessages] = useState<ChatMessageType[]>([]);
103
- const sessionId = session_id;
104
103
 
105
104
  function updateLastMessage(message: ChatMessageType) {
106
105
  setMessages((prev) => {
@@ -157,7 +156,7 @@ export default function ChatWidget({
157
156
  messages={messages}
158
157
  triggerRef={triggerRef}
159
158
  position={chat_position}
160
- sessionId={sessionId}
159
+ sessionId={session_id}
161
160
  additional_headers={additional_headers}
162
161
  setDropDownList={setDropDownList}
163
162
  dropDownList={dropDownList}
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import ChatWidget from '../chatWidget/index';
3
3
  import aiAvatarPng from '../../assets/aicenter/aiavatar.png';
4
- import { getFlowInfo, getHistoryList, getKnowledgeInfo } from '../chatWidget/chatWindow/controllers/index';
4
+ import { getFlowInfo, getHistoryList, getQaInfo } from '../chatWidget/chatWindow/controllers/index';
5
5
  import './index.module.css'
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
  import historyListEmptyPng from '../../assets/aicenter/history-list-empty.png';
@@ -69,19 +69,19 @@ const style = `
69
69
  }
70
70
  .p_toolDialog .p_sign{
71
71
  width: calc(100vw - 140px);
72
+ min-width:1380px;
72
73
  margin: 0 auto;
73
- min-width: 1200px;
74
74
  }
75
75
 
76
76
  .dialog_box{
77
77
  margin: 1.5rem auto 0;
78
78
  width: calc(100vw - 140px);
79
79
  height: calc(100vh - 192px);
80
+ min-width:1380px;
80
81
  background: #fff;
81
82
  border-radius: 15px;
82
83
  display: flex;
83
84
  flex-direction: column;
84
- min-width: 1200px;
85
85
  }
86
86
  .p_toolDialog .p_toolLeft {
87
87
  display: flex;
@@ -222,7 +222,8 @@ const style = `
222
222
 
223
223
  .p_toolDialog .p_toolRight {
224
224
  flex: 1;
225
- background: #f5f5f5;h
225
+ background: #f5f5f5;
226
+ min-width:780px;
226
227
  }
227
228
 
228
229
  .p_toolRightToRight {
@@ -376,17 +377,17 @@ export class ToolDialogV2 extends React.Component {
376
377
  const res = await getFlowInfo(this.props.hostUrl, this.props.appId, api_key);
377
378
  if(res.status === 200 && typeof res.data !== "string") {
378
379
  // 查询知识库相关信息用作预置问题
379
- // getKnowledgeInfo(this.props.hostUrl, this.props.appId, api_key).then(res => {
380
- // if (res.status === 200 && typeof res.data !== "string") {
381
- // if (!isEmpty(knowledgeInfo)) {
382
- // this.setState({ knowledgeInfo: res.data })
383
- // } else if (!isEmpty(this.props.knowledgeInfo)) {
384
- // this.setState({ knowledgeInfo: this.props.knowledgeInfo })
385
- // }
386
- // }
387
- // }).catch(e => {
388
- // console.log(e);
389
- // });
380
+ getQaInfo(this.props.hostUrl, this.props.appId, api_key).then(res => {
381
+ if (res.status === 200 && typeof res.data !== "string") {
382
+ if ( !isEmpty(res.data) && !isEmpty(res.data.media) && !isEmpty(res.data.question)) {
383
+ this.setState({ knowledgeInfo: res.data })
384
+ } else if ( !isEmpty(this.props.knowledgeInfo)) {
385
+ this.setState({ knowledgeInfo: this.props.knowledgeInfo })
386
+ }
387
+ }
388
+ }).catch(e => {
389
+ console.log(e);
390
+ });
390
391
  this.setState({ currentFlow: res.data });
391
392
  }
392
393
  return res.data;
@@ -474,7 +475,7 @@ export class ToolDialogV2 extends React.Component {
474
475
  modalWidth,
475
476
  isShowReadIcon = false,
476
477
  signUrl,
477
- knowledgeInfo,
478
+ isShowVoiceButton,
478
479
  } = this.props;
479
480
  const { currentFlow = {} } = this.state;
480
481
  return (
@@ -562,6 +563,7 @@ export class ToolDialogV2 extends React.Component {
562
563
  dropDownList={this.state.dropDownList}
563
564
  baseConfig={{ isTitleSideIcon, logoWidth, agentUrl, ...assetMap }}
564
565
  isShowUploadButton={isShowUploadButton}
566
+ isShowVoiceButton={isShowVoiceButton}
565
567
  dropManUrl={currentFlow.character}
566
568
  modalWidth={modalWidth}
567
569
  isShowReadIcon={isShowReadIcon}
@@ -572,32 +574,34 @@ export class ToolDialogV2 extends React.Component {
572
574
  />
573
575
  </MethodContext.Provider>
574
576
  </div>
575
- <div className={'p_toolRightToRight'}>
576
- <Carousel autoplay={{ dotDuration: true }} autoplaySpeed={4000} className={'p_carousel'}>
577
- {
578
- (this.state.knowledgeInfo?.media||[]).map(item => {
579
- if (item.a_type==='image') {
580
- return <div key={item.a}>
581
- <Image
582
- preview={{
583
- mask: <div><EyeOutlined style={{marginRight:'4px'}}/>预览</div>
584
- }}
585
- style={contentStyle} src={item.a}
586
- />
587
- </div>
588
- }else if(item.a_type==='video'){
589
- return <div key={item.a}>
590
- <video style={contentStyle} src={item.a} controls={true}/>
591
- </div>
592
- }
593
- })
594
- }
595
- </Carousel>
596
- <div style={{ height: '1px', background: '#E5E5E5',marginTop: '25px' }}/>
597
- <div className={'p_hot'}>
598
- <img src={'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/hot.png'}/>
599
- <span>热点问题</span>
600
- </div>
577
+ {
578
+ isShowSideRight && <div className={'p_toolRightToRight'}>
579
+ <Carousel autoplay={{ dotDuration: true }} autoplaySpeed={4000} className={'p_carousel'}>
580
+ {
581
+ (this.state.knowledgeInfo?.media || []).map(item => {
582
+ if (item.a_type === 'image') {
583
+ return <div key={item.a}>
584
+ <Image
585
+ preview={{
586
+ mask: <div><EyeOutlined style={{ marginRight: '4px' }}/>预览</div>
587
+ }}
588
+ style={contentStyle} src={item.a}
589
+ />
590
+ </div>
591
+ } else if (item.a_type === 'video') {
592
+ return <div key={item.a}>
593
+ <video style={contentStyle} src={item.a} controls={true}/>
594
+ </div>
595
+ }
596
+ })
597
+ }
598
+ </Carousel>
599
+ <div style={{ height: '1px', background: '#E5E5E5', marginTop: '25px' }}/>
600
+ <div className={'p_hot'}>
601
+ <img
602
+ src={'https://trans-from-yuntu-resourse.oss-cn-beijing.aliyuncs.com/smartSchool/appCreator/school/bcyz/user/ai/hot.png'}/>
603
+ <span>热点问题</span>
604
+ </div>
601
605
  <TabSelector
602
606
  isSimple={true}
603
607
  handleRowClick={(word) => {
@@ -605,10 +609,11 @@ export class ToolDialogV2 extends React.Component {
605
609
  }}
606
610
  dataList={this.state.knowledgeInfo?.question || []}
607
611
  />
608
- </div>
612
+ </div>
613
+ }
609
614
  </div>
610
615
  </div>
611
- <div className={'p_footer'}><span style={{fontSize: 16}}>技术支持:北京云图科技有限公司</span></div>
616
+ <div className={'p_footer'}><span style={{ fontSize: 16 }}>技术支持:北京云图科技有限公司</span></div>
612
617
  </div>
613
618
  </div>
614
619
  );
@@ -13,8 +13,8 @@
13
13
 
14
14
  .toolDialogSign {
15
15
  width: calc(100vw - 140px);
16
+ min-width:1380px;
16
17
  margin: 0 auto;
17
- min-width: 1200px;
18
18
  }
19
19
 
20
20
  .dialogBox {
@@ -25,7 +25,7 @@
25
25
  border-radius: 15px;
26
26
  display: flex;
27
27
  flex-direction: column;
28
- min-width: 1200px;
28
+ min-width:1380px;
29
29
  }
30
30
 
31
31
  .toolLeft {
@@ -154,6 +154,7 @@
154
154
  .toolRight {
155
155
  flex: 1;
156
156
  background: #f5f5f5;
157
+ min-width:780px;
157
158
  }
158
159
 
159
160
  .toolRightToRight {