@zero-library/chat-agent 2.1.19 → 2.2.0

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/dist/index.esm.js CHANGED
@@ -1,13 +1,12 @@
1
- import { useRefState, useDebounce, useSyncInput, RenderWrapper, shouldRender, isFunction, useDeepEffect, useWebSocket, getWebSocketUrl, getToken, isLocalhost, downloadFile, FilePreview, MarkdownEditor, useCreateValtioContext, isNumber, getFileSuffixName, isObject, isNullOrUnDef, isBoolean, UserAvatar, deepCopy, transforms, transform, getCurrentUser, deepMerge, createRequest, RenderMarkdown, copyText, FileIcon, isExternal } from '@zero-library/common';
1
+ import { createSecureManager, createTokenManager, useRefState, useDebounce, useSyncInput, RenderWrapper, shouldRender, isFunction, useDeepEffect, useWebSocket, downloadFile, FilePreview, MarkdownEditor, isNumber, getFileSuffixName, isObject, isNullOrUnDef, isBoolean, UserAvatar, copyText, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, RenderMarkdown, transform, emit, buildUrlParams, getWebSocketUrl, useCreateValtioContext, FileIcon, isExternal } from '@zero-library/common';
2
2
  import { App, Badge, Button, Flex, Typography, Spin, Splitter, Tag, Popover, List, Avatar, Space, message, Empty, Modal, Row, Col, Collapse, Drawer } from 'antd';
3
- import dayjs from 'dayjs';
4
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
4
  import { forwardRef, useRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
6
5
  import { useSnapshot, proxy } from 'valtio';
7
6
  import { CloudUploadOutlined, PaperClipOutlined, EnterOutlined, UserSwitchOutlined, CloseOutlined, PlusOutlined, CommentOutlined, OpenAIOutlined, CopyOutlined, LikeOutlined, DislikeOutlined, DeleteOutlined, RedoOutlined, PlayCircleOutlined, CaretRightOutlined } from '@ant-design/icons';
8
- import { Attachments, Sender, Suggestion, XProvider, Welcome, Prompts, Bubble, Conversations } from '@ant-design/x';
9
- export * from '@ant-design/x';
10
- import classNames8 from 'classnames';
7
+ import { Attachments, Sender, Suggestion, XProvider, Prompts, Bubble, Conversations, Welcome } from '@ant-design/x';
8
+ import classNames9 from 'classnames';
9
+ import dayjs from 'dayjs';
11
10
  import InfiniteScroll from 'react-infinite-scroll-component';
12
11
 
13
12
  var __defProp = Object.defineProperty;
@@ -19,36 +18,6 @@ var __export = (target, all) => {
19
18
  for (var name in all)
20
19
  __defProp(target, name, { get: all[name], enumerable: true });
21
20
  };
22
- var classifyTime, replaceThinkTags, copy;
23
- var init_utils = __esm({
24
- "src/core/utils.ts"() {
25
- classifyTime = (timestamp) => {
26
- const now = dayjs();
27
- const target = dayjs(timestamp);
28
- if (target.isSame(now, "day")) {
29
- return "\u4ECA\u5929";
30
- }
31
- const diffInDays = now.diff(target, "day");
32
- if (diffInDays < 7) {
33
- return "\u6700\u8FD1 7 \u5929";
34
- } else if (diffInDays < 30) {
35
- return "\u6700\u8FD1 30 \u5929";
36
- } else if (diffInDays < 180) {
37
- return "\u6700\u8FD1\u534A\u5E74";
38
- } else {
39
- return "\u66F4\u65E9";
40
- }
41
- };
42
- replaceThinkTags = (str) => {
43
- return str.replace(/<think>/g, ":::alert type=think data={content:'").replace(/<\/think>/g, "'} ::: ");
44
- };
45
- copy = (value) => {
46
- copyText(value).then(() => {
47
- message.success("\u590D\u5236\u6210\u529F");
48
- });
49
- };
50
- }
51
- });
52
21
  var ChatProvider, useChatStore;
53
22
  var init_Context = __esm({
54
23
  "src/stores/Context.ts"() {
@@ -207,7 +176,6 @@ __export(FileEdit_exports, {
207
176
  var FileEdit_default;
208
177
  var init_FileEdit = __esm({
209
178
  "src/ui/common/markdownAlert/FileEdit.tsx"() {
210
- init_utils();
211
179
  init_Context();
212
180
  init_styles_module();
213
181
  FileEdit_default = ({ data, loading }) => {
@@ -223,7 +191,7 @@ var init_FileEdit = __esm({
223
191
  ] }),
224
192
  /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxs(Flex, { children: [
225
193
  /* @__PURE__ */ jsx(Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(PlayCircleOutlined, {}), onClick: onPreview, children: "\u9884\u89C8\u7F16\u8F91" }),
226
- /* @__PURE__ */ jsx(Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(CopyOutlined, {}), onClick: () => copy(data.content), children: "\u590D\u5236" })
194
+ /* @__PURE__ */ jsx(Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(CopyOutlined, {}), onClick: () => copyText(data.content), children: "\u590D\u5236" })
227
195
  ] }) })
228
196
  ] }),
229
197
  /* @__PURE__ */ jsx(Flex, { gap: 8, align: "center", className: styles_module_default.fileEditContent, children: /* @__PURE__ */ jsx(RenderMarkdown, { content: data.content }) })
@@ -306,9 +274,41 @@ var init_Think = __esm({
306
274
  };
307
275
  }
308
276
  });
309
-
310
- // src/stores/index.ts
311
- init_utils();
277
+ var userInfoManager = createSecureManager({
278
+ key: "NS-USER",
279
+ aesKey: "((#II))"
280
+ });
281
+ var TOKEN_KEY = "NS-TOKEN";
282
+ var tokenManager = createTokenManager({
283
+ key: TOKEN_KEY
284
+ });
285
+ var redirectUrl = () => {
286
+ const path = localStorage.getItem("SIGNPATH");
287
+ emit("jumpLink", { url: `/uc${path || "/sign-in"}` });
288
+ };
289
+ var classifyTime = (timestamp) => {
290
+ const now = dayjs();
291
+ const target = dayjs(timestamp);
292
+ if (target.isSame(now, "day")) {
293
+ return "\u4ECA\u5929";
294
+ }
295
+ const diffInDays = now.diff(target, "day");
296
+ if (diffInDays < 7) {
297
+ return "\u6700\u8FD1 7 \u5929";
298
+ } else if (diffInDays < 30) {
299
+ return "\u6700\u8FD1 30 \u5929";
300
+ } else if (diffInDays < 180) {
301
+ return "\u6700\u8FD1\u534A\u5E74";
302
+ } else {
303
+ return "\u66F4\u65E9";
304
+ }
305
+ };
306
+ var replaceThinkTags = (str) => {
307
+ return str.replace(/<think>/g, ":::alert type=think data={content:'").replace(/<\/think>/g, "'} :::");
308
+ };
309
+ var getChatSocketUrl = (baseURL, params) => {
310
+ return buildUrlParams(params, getWebSocketUrl(`${baseURL}/lolr/conversation/ws/subscribe`), "comma");
311
+ };
312
312
 
313
313
  // src/services/index.ts
314
314
  var createChatService = (request) => {
@@ -428,8 +428,6 @@ var defaultExpertLayout = {
428
428
  globalHeader: false,
429
429
  chatHeader: {
430
430
  props: {
431
- title: true,
432
- closeBtn: false,
433
431
  newConversationBtn: false,
434
432
  agentCharacter: false,
435
433
  conversationListBtn: false
@@ -440,10 +438,14 @@ var defaultExpertLayout = {
440
438
  function createChatStore() {
441
439
  const config = proxy({
442
440
  services: {
443
- websocketBaseUrls: []
441
+ /** WebSocket地址 */
442
+ websocketUrls: ["", ""],
443
+ /** HTTP请求实例 */
444
+ request: {}
444
445
  },
445
446
  hooks: {},
446
447
  layout: {},
448
+ /** 文件预览状态 */
447
449
  preview: {
448
450
  file: {},
449
451
  isEdit: false
@@ -451,16 +453,42 @@ function createChatStore() {
451
453
  // isShow: 0, // 0 不显示 1 显示 2 用户关闭
452
454
  // isIntact: false // true 完整 false 不完整
453
455
  },
456
+ /** 当前用户信息 */
454
457
  userInfo: {},
458
+ /** 聊天参数配置 */
455
459
  params: {}
456
460
  });
457
- const setServices = ({ baseUrl = "/api" } = {}) => {
458
- config.services.baseUrl = baseUrl;
459
- if (!config.services.websocketBaseUrls?.includes(baseUrl)) {
460
- config.services.websocketBaseUrls = [...config.services.websocketBaseUrls, baseUrl];
461
+ const setServices = ({ http, websocket } = {}) => {
462
+ const httpConfig = { baseURL: "/api", headers: { [TOKEN_KEY]: tokenManager.get() }, ...http?.config };
463
+ const request = createRequest(httpConfig);
464
+ if (config.hooks?.onRequestInterceptor) {
465
+ request.instance.interceptors.request.use(...config.hooks.onRequestInterceptor);
466
+ }
467
+ request.instance.interceptors.response.use(void 0, (err) => {
468
+ if (err?.response?.status === HttpStatus.UNAUTHORIZED) {
469
+ if (config.hooks.onRedirectLogin) {
470
+ config.hooks.onRedirectLogin();
471
+ } else {
472
+ redirectUrl();
473
+ }
474
+ }
475
+ return Promise.reject(err);
476
+ });
477
+ if (config.hooks?.onResponseInterceptor) {
478
+ request.instance.interceptors.response.use(...config.hooks.onResponseInterceptor);
479
+ }
480
+ config.services.request = { ...createChatService(request), ...createFileService(request), ...http?.request };
481
+ config.services.websocketUrls = ["", ""];
482
+ if (isArray(websocket?.baseURLs)) {
483
+ websocket.baseURLs.forEach((baseURL, index) => {
484
+ if (isString(baseURL)) {
485
+ config.services.websocketUrls[index] = getChatSocketUrl(baseURL, websocket?.params || httpConfig.headers);
486
+ }
487
+ });
488
+ } else {
489
+ const url = getChatSocketUrl(httpConfig.baseURL, websocket?.params || httpConfig.headers);
490
+ config.services.websocketUrls = [url, ""];
461
491
  }
462
- const request = createRequest(baseUrl);
463
- config.services.request = { ...createChatService(request), ...createFileService(request) };
464
492
  };
465
493
  const setPreview = (file = {}, isEdit = false) => {
466
494
  if (shouldRender(config.layout.preview)) {
@@ -487,20 +515,16 @@ function createChatStore() {
487
515
  config.hooks = hooks;
488
516
  };
489
517
  const setUserInfo = (userInfo) => {
490
- config.userInfo = transform(userInfo || getCurrentUser() || {}, {
491
- id: (userInfo2) => {
492
- return String(userInfo2["id"]);
493
- },
494
- name: "name",
495
- iconUrl: "avatar",
496
- description: "name"
497
- });
518
+ config.userInfo = userInfo || userInfoManager.get() || {};
519
+ config.userInfo.id = String(config.userInfo.id || "");
498
520
  };
499
521
  const receiver = proxy({
522
+ /** 当前激活的接收者信息(智能体或专家) */
500
523
  active: {},
524
+ /** 接收者加载状态 */
501
525
  loading: false,
526
+ /** 接收者透传参数,后期可能扩展不透传参数 */
502
527
  params: {}
503
- // 透传参数,后期可能扩展不透传参数
504
528
  });
505
529
  const setReceiverParams = (params) => {
506
530
  if (isObject(params)) {
@@ -559,10 +583,15 @@ function createChatStore() {
559
583
  setReceiverParams();
560
584
  };
561
585
  const character = proxy({
586
+ /** 性格列表 */
562
587
  list: [],
588
+ /** 当前激活的性格 */
563
589
  active: {},
590
+ /** 性格选择面板是否打开 */
564
591
  open: false,
592
+ /** 加载性格列表的状态 */
565
593
  loading: false,
594
+ /** 切换性格时的加载状态 */
566
595
  switchLoading: false
567
596
  });
568
597
  const getCharacters = async (agentId) => {
@@ -597,16 +626,20 @@ function createChatStore() {
597
626
  }
598
627
  };
599
628
  const conversations = proxy({
629
+ /** 会话列表数据 */
600
630
  list: {
601
631
  items: [],
632
+ /** 分页查询参数 */
602
633
  params: {
603
634
  pageNum: 1,
604
635
  pageSize: 1e3
605
636
  }
606
637
  },
638
+ /** 当前会话索引,创建会话时更新,促使页面更新会话列表 */
607
639
  updateIndex: 0,
608
- // 当前会话索引, 创建会话时更新,促使页面更新会话列表
640
+ /** 获取会话列表的加载状态 */
609
641
  loading: false,
642
+ /** 删除会话的加载状态 */
610
643
  delLoading: false
611
644
  });
612
645
  const getConversations = async (targetId, targetType) => {
@@ -652,14 +685,18 @@ function createChatStore() {
652
685
  }
653
686
  };
654
687
  const conversation = proxy({
655
- // 每个会话单独存储
688
+ /** 当前激活的会话信息 */
656
689
  active: {
657
690
  id: "",
691
+ /** 会话成员对象,包含用户、智能体、专家等 */
658
692
  member: {}
659
693
  },
694
+ /** 每个会话的消息存储,以会话ID为键 */
660
695
  messages: {},
696
+ /** 消息反馈状态 */
661
697
  feedback: {
662
698
  // open: false,
699
+ /** 反馈操作加载状态 */
663
700
  loading: false
664
701
  // recordId: '',
665
702
  // target: undefined as number | undefined
@@ -707,14 +744,18 @@ function createChatStore() {
707
744
  };
708
745
  const setInitMessage = async (conversationId) => {
709
746
  conversation.messages[conversationId] = {
747
+ /** 输入框内容 */
710
748
  content: "",
749
+ /** 上传文件列表 */
711
750
  files: [],
712
- // 上传文件内容
751
+ /** 头部展开状态 */
713
752
  headerOpen: false,
753
+ /** 消息发送/接收加载状态 */
714
754
  loading: false,
755
+ /** 消息列表 */
715
756
  message: [],
757
+ /** 推荐问题列表 */
716
758
  questionList: []
717
- // 推荐问题
718
759
  };
719
760
  };
720
761
  const resolveConversationId = async (receiverId, strategy = 2) => {
@@ -819,13 +860,13 @@ function createChatStore() {
819
860
  if (other) return other;
820
861
  return void 0;
821
862
  };
822
- const sendMessage = async (message3, files = [], params) => {
863
+ const sendMessage = async (message2, files = [], params) => {
823
864
  const conversationId = conversation.active.id;
824
865
  if (conversation.messages[conversationId].loading) return;
825
866
  let msgContent = "", msgFiles;
826
867
  const references = conversation.messages[conversationId].references;
827
- if (message3) {
828
- msgContent = message3;
868
+ if (message2) {
869
+ msgContent = message2;
829
870
  msgFiles = files;
830
871
  } else {
831
872
  if (references?.type === 1 && references?.content?.markdown) {
@@ -853,9 +894,9 @@ function createChatStore() {
853
894
  stream: true
854
895
  };
855
896
  const extraParams = deepCopy(config.params.params || {});
856
- Object.assign(extraParams, receiver.params, message3 ? {} : references?.params, params);
897
+ Object.assign(extraParams, receiver.params, message2 ? {} : references?.params, params);
857
898
  sendParams.params = JSON.stringify(extraParams);
858
- if (!message3) {
899
+ if (!message2) {
859
900
  setContent("");
860
901
  setFileList([]);
861
902
  setReferences();
@@ -901,15 +942,15 @@ function createChatStore() {
901
942
  const messages = conversation.messages[msg.conversationId].message;
902
943
  const idx = findMsgIndex(msg.conversationId, msg.id);
903
944
  if (idx === -1) return;
904
- const message3 = messages[idx];
945
+ const message2 = messages[idx];
905
946
  conversation.messages[msg.conversationId].loading = true;
906
- if (message3?.type === "STEP_STARTED" || message3?.type === "TEXT_MESSAGE_START") {
947
+ if (message2?.type === "STEP_STARTED" || message2?.type === "TEXT_MESSAGE_START") {
907
948
  messages[idx] = msg;
908
949
  return;
909
950
  }
910
951
  messages[idx] = {
911
- ...message3,
912
- msgContent: message3.msgContent + (msg.msgContent || "")
952
+ ...message2,
953
+ msgContent: message2.msgContent + (msg.msgContent || "")
913
954
  };
914
955
  };
915
956
  const endCallback = (msg) => {
@@ -927,9 +968,13 @@ function createChatStore() {
927
968
  messages[idx] = { ...msg, type: void 0 };
928
969
  conversation.messages[msg.conversationId].loading = false;
929
970
  };
930
- const acceptMessage = (newMessage) => {
971
+ const acceptMessage = async (newMessage) => {
931
972
  const conversationId = newMessage.data.conversationId;
932
973
  if (!conversation.messages[conversationId]?.message) return;
974
+ const canProceed = await config.hooks?.onBeforeAcceptMessage?.(newMessage.data);
975
+ if (canProceed === false) {
976
+ throw new Error("\u64CD\u4F5C\u88AB\u963B\u6B62");
977
+ }
933
978
  switch (newMessage.data.type) {
934
979
  case "TEXT_MESSAGE_START":
935
980
  startCallback(newMessage.data);
@@ -947,37 +992,68 @@ function createChatStore() {
947
992
  errCallback(newMessage.data);
948
993
  break;
949
994
  }
995
+ config.hooks?.onAfterAcceptMessage?.(newMessage.data);
950
996
  };
951
997
  return {
998
+ /** 全局配置对象 */
952
999
  config,
1000
+ /** 设置服务配置 */
953
1001
  setServices,
1002
+ /** 设置文件预览 */
954
1003
  setPreview,
1004
+ /** 设置布局配置 */
955
1005
  setLayout,
1006
+ /** 设置生命周期钩子 */
956
1007
  setHooks,
1008
+ /** 设置聊天参数 */
957
1009
  setParams,
1010
+ /** 设置用户信息 */
958
1011
  setUserInfo,
1012
+ /** 智能体性格状态 */
959
1013
  character,
1014
+ /** 获取性格列表 */
960
1015
  getCharacters,
1016
+ /** 打开性格选择面板 */
961
1017
  openCharacterList,
1018
+ /** 关闭性格选择面板 */
962
1019
  closeCharacterList,
1020
+ /** 切换性格 */
963
1021
  switchCharacter,
1022
+ /** 接收者状态 */
964
1023
  receiver,
1024
+ /** 设置接收者参数 */
965
1025
  setReceiverParams,
1026
+ /** 历史会话状态 */
966
1027
  conversations,
1028
+ /** 获取会话列表 */
967
1029
  getConversations,
1030
+ /** 删除会话 */
968
1031
  delConversation,
1032
+ /** 当前会话状态 */
969
1033
  conversation,
1034
+ /** 设置说话人类型 */
970
1035
  setSpeakHuman,
1036
+ /** 设置引用消息 */
971
1037
  setReferences,
1038
+ /** 设置消息内容 */
972
1039
  setContent,
1040
+ /** 设置文件列表 */
973
1041
  setFileList,
1042
+ /** 设置头部展开状态 */
974
1043
  setHeaderOpen,
1044
+ /** 消息反馈操作 */
975
1045
  feedback,
1046
+ /** 切换智能体会话 */
976
1047
  switchAgentConversation,
1048
+ /** 创建新会话 */
977
1049
  createConversation,
1050
+ /** 切换会话 */
978
1051
  switchConversation,
1052
+ /** 发送消息 */
979
1053
  sendMessage,
1054
+ /** 取消接收 */
980
1055
  cancelReceive,
1056
+ /** 接收消息 */
981
1057
  acceptMessage
982
1058
  };
983
1059
  }
@@ -985,9 +1061,6 @@ function createChatStore() {
985
1061
  // src/ui/layouts/index.tsx
986
1062
  init_Context();
987
1063
 
988
- // src/components/MessageRender.tsx
989
- init_utils();
990
-
991
1064
  // src/ui/common/markdownAlert/index.ts
992
1065
  var customComponents = {
993
1066
  appCard: () => Promise.resolve().then(() => (init_AppCard(), AppCard_exports)),
@@ -1006,17 +1079,17 @@ var styles_module_default2 = {
1006
1079
  chatSender: "styles_module_chatSender",
1007
1080
  chatQuoteMsg: "styles_module_chatQuoteMsg"
1008
1081
  };
1009
- var MessageRender_default = ({ message: message3, placement }) => {
1010
- return /* @__PURE__ */ jsx(Flex, { vertical: true, children: !(message3.msgContent || message3.msgFiles.length) ? /* @__PURE__ */ jsx(Typography, { children: /* @__PURE__ */ jsx(Spin, { size: "small" }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1011
- message3.msgContent && /* @__PURE__ */ jsx(
1082
+ var MessageRender_default = ({ message: message2, placement }) => {
1083
+ return /* @__PURE__ */ jsx(Flex, { vertical: true, children: !(message2.msgContent || message2.msgFiles.length) ? /* @__PURE__ */ jsx(Typography, { children: /* @__PURE__ */ jsx(Spin, { size: "small" }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1084
+ message2.msgContent && /* @__PURE__ */ jsx(
1012
1085
  Bubble,
1013
1086
  {
1014
1087
  placement,
1015
- className: classNames8({ [styles_module_default2.loadingMessage]: message3.type }),
1016
- content: /* @__PURE__ */ jsx(RenderMarkdown, { content: replaceThinkTags(message3.msgContent), customComponents })
1088
+ className: classNames9({ [styles_module_default2.loadingMessage]: message2.type }),
1089
+ content: /* @__PURE__ */ jsx(RenderMarkdown, { content: replaceThinkTags(message2.msgContent), customComponents })
1017
1090
  }
1018
1091
  ),
1019
- message3.msgFiles?.map((file) => /* @__PURE__ */ jsx(
1092
+ message2.msgFiles?.map((file) => /* @__PURE__ */ jsx(
1020
1093
  Bubble,
1021
1094
  {
1022
1095
  className: "m-t-8",
@@ -1036,19 +1109,19 @@ var MessageRender_default = ({ message: message3, placement }) => {
1036
1109
  },
1037
1110
  file.content
1038
1111
  )),
1039
- message3.quoteMsg?.id && /* @__PURE__ */ jsx(
1112
+ message2.quoteMsg?.id && /* @__PURE__ */ jsx(
1040
1113
  Bubble,
1041
1114
  {
1042
- className: classNames8(styles_module_default2.chatQuoteMsg),
1115
+ className: classNames9(styles_module_default2.chatQuoteMsg),
1043
1116
  placement,
1044
1117
  content: /* @__PURE__ */ jsxs(Flex, { vertical: true, gap: 8, children: [
1045
- message3.quoteMsg.msgContent && /* @__PURE__ */ jsxs(Flex, { children: [
1118
+ message2.quoteMsg.msgContent && /* @__PURE__ */ jsxs(Flex, { children: [
1046
1119
  /* @__PURE__ */ jsx("span", { children: "\u3010\u5F15\u7528\u6D88\u606F\u3011\uFF1A" }),
1047
- /* @__PURE__ */ jsx(Flex, { flex: 1, className: "text-ellipsis", children: message3.quoteMsg.msgContent })
1120
+ /* @__PURE__ */ jsx(Flex, { flex: 1, className: "text-ellipsis", children: message2.quoteMsg.msgContent })
1048
1121
  ] }),
1049
- message3.quoteMsg?.msgFiles && message3.quoteMsg.msgFiles.length > 0 && /* @__PURE__ */ jsxs(Flex, { children: [
1122
+ message2.quoteMsg?.msgFiles && message2.quoteMsg.msgFiles.length > 0 && /* @__PURE__ */ jsxs(Flex, { children: [
1050
1123
  /* @__PURE__ */ jsx("span", { children: "\u3010\u5F15\u7528\u6587\u4EF6\u3011\uFF1A" }),
1051
- /* @__PURE__ */ jsx(Flex, { gap: 8, wrap: true, flex: 1, children: message3.quoteMsg.msgFiles.map((file) => /* @__PURE__ */ jsx(
1124
+ /* @__PURE__ */ jsx(Flex, { gap: 8, wrap: true, flex: 1, children: message2.quoteMsg.msgFiles.map((file) => /* @__PURE__ */ jsx(
1052
1125
  Attachments.FileCard,
1053
1126
  {
1054
1127
  item: {
@@ -1074,7 +1147,6 @@ var MEMBER_TYPE = {
1074
1147
  };
1075
1148
 
1076
1149
  // src/ui/common/BubbleListItems.tsx
1077
- init_utils();
1078
1150
  init_Context();
1079
1151
 
1080
1152
  // src/ui/common/styles.module.less
@@ -1102,7 +1174,55 @@ var styles_module_default3 = {
1102
1174
  nsAvatarListItemIconActive: "styles_module_nsAvatarListItemIconActive",
1103
1175
  nsAvatarListItemName: "styles_module_nsAvatarListItemName"
1104
1176
  };
1105
- var BubbleListItems_default = ({ firstMessage = false, avatar = { user: false, agent: true, other: true } }) => {
1177
+
1178
+ // src/ui/common/WelcomeItem.tsx
1179
+ init_Context();
1180
+ var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
1181
+ const chatStore = useChatStore();
1182
+ const receiverState = useSnapshot(chatStore.receiver);
1183
+ return /* @__PURE__ */ jsxs(Space, { direction: "vertical", size: 16, className: styles_module_default3.chatWelcomeWrap, children: [
1184
+ /* @__PURE__ */ jsx(
1185
+ Welcome,
1186
+ {
1187
+ className: classNames9(styles_module_default3.chatWelcome, "p-t-32"),
1188
+ variant: "borderless",
1189
+ icon: /* @__PURE__ */ jsx(RenderWrapper, { control: icon, DefaultComponent: /* @__PURE__ */ jsx(Avatar, { shape: "square", size: 58, src: receiverState.active.logo }) }),
1190
+ title: /* @__PURE__ */ jsx(RenderWrapper, { control: title, DefaultComponent: `\u4F60\u597D\uFF0C\u6211\u662F${receiverState.active.name || ""}` }),
1191
+ description: /* @__PURE__ */ jsx(
1192
+ RenderWrapper,
1193
+ {
1194
+ control: description,
1195
+ DefaultComponent: /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: receiverState.active.description || "" } })
1196
+ }
1197
+ )
1198
+ }
1199
+ ),
1200
+ receiverState.active.config?.recommendQuestions?.length > 0 && /* @__PURE__ */ jsx(
1201
+ RenderWrapper,
1202
+ {
1203
+ control: prompts,
1204
+ DefaultComponent: /* @__PURE__ */ jsx(
1205
+ Prompts,
1206
+ {
1207
+ className: "m-t-16",
1208
+ wrap: true,
1209
+ items: [
1210
+ {
1211
+ key: "1",
1212
+ label: "\u{1F914} \u63A8\u8350\u95EE\u9898:",
1213
+ children: receiverState.active.config.recommendQuestions.map(({ question }) => ({
1214
+ key: question,
1215
+ description: /* @__PURE__ */ jsx("span", { onClick: () => chatStore.sendMessage(question), className: classNames9(styles_module_default3.chatWelcomePrompts, "text-ellipsis"), children: question })
1216
+ }))
1217
+ }
1218
+ ]
1219
+ }
1220
+ )
1221
+ }
1222
+ )
1223
+ ] });
1224
+ };
1225
+ var BubbleListItems_default = ({ firstMessage = false, welcomeMessage = true, avatar = { user: false, agent: true, other: true } }) => {
1106
1226
  const chatStore = useChatStore();
1107
1227
  const receiverState = useSnapshot(chatStore.receiver);
1108
1228
  const conversationState = useSnapshot(chatStore.conversation);
@@ -1142,44 +1262,16 @@ var BubbleListItems_default = ({ firstMessage = false, avatar = { user: false, a
1142
1262
  () => conversationState.messages[conversationState.active.id] || {},
1143
1263
  [conversationState.messages[conversationState.active.id]]
1144
1264
  );
1145
- const placeholderNode = useMemo(
1146
- () => [
1265
+ const welcomeMessageRecord = useMemo(() => {
1266
+ const isExist = shouldRender(welcomeMessage);
1267
+ return isExist ? [
1147
1268
  {
1148
1269
  key: "placeholder",
1149
- content: /* @__PURE__ */ jsxs(Space, { direction: "vertical", size: 16, className: styles_module_default3.chatWelcomeWrap, children: [
1150
- /* @__PURE__ */ jsx(
1151
- Welcome,
1152
- {
1153
- className: classNames8(styles_module_default3.chatWelcome, "p-t-32"),
1154
- variant: "borderless",
1155
- icon: /* @__PURE__ */ jsx(Avatar, { shape: "square", size: 58, src: receiverState.active.logo }),
1156
- title: `\u4F60\u597D\uFF0C\u6211\u662F${receiverState.active.name || ""}`,
1157
- description: /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: receiverState.active.description || "" } })
1158
- }
1159
- ),
1160
- receiverState.active.config?.recommendQuestions?.length > 0 && /* @__PURE__ */ jsx(
1161
- Prompts,
1162
- {
1163
- className: "m-t-16",
1164
- wrap: true,
1165
- items: [
1166
- {
1167
- key: "1",
1168
- label: "\u{1F914} \u63A8\u8350\u95EE\u9898:",
1169
- children: receiverState.active.config.recommendQuestions.map(({ question }) => ({
1170
- key: question,
1171
- description: /* @__PURE__ */ jsx("span", { onClick: () => chatStore.sendMessage(question), className: classNames8(styles_module_default3.chatWelcomePrompts, "text-ellipsis"), children: question })
1172
- }))
1173
- }
1174
- ]
1175
- }
1176
- )
1177
- ] }),
1270
+ content: /* @__PURE__ */ jsx(RenderWrapper, { control: welcomeMessage, DefaultComponent: /* @__PURE__ */ jsx(WelcomeItem_default, {}) }),
1178
1271
  variant: "borderless"
1179
1272
  }
1180
- ],
1181
- [receiverState.active]
1182
- );
1273
+ ] : [];
1274
+ }, [receiverState.active, welcomeMessage]);
1183
1275
  const questionList = useMemo(
1184
1276
  () => chatMessage?.questionList?.length ? [
1185
1277
  {
@@ -1207,36 +1299,36 @@ var BubbleListItems_default = ({ firstMessage = false, avatar = { user: false, a
1207
1299
  [chatMessage?.questionList]
1208
1300
  );
1209
1301
  const chatRecords = useMemo(() => {
1210
- return (chatMessage?.message || []).map((message3, index) => {
1211
- const role = conversationRoles[MEMBER_TYPE[message3.sender.type]] || {};
1302
+ return (chatMessage?.message || []).map((message2, index) => {
1303
+ const role = conversationRoles[MEMBER_TYPE[message2.sender.type]] || {};
1212
1304
  return {
1213
- key: message3.id,
1305
+ key: message2.id,
1214
1306
  placement: role.placement,
1215
1307
  variant: "borderless",
1216
1308
  avatar: role.avatar,
1217
- content: /* @__PURE__ */ jsx(MessageRender_default, { message: message3, placement: role.placement }),
1309
+ content: /* @__PURE__ */ jsx(MessageRender_default, { message: message2, placement: role.placement }),
1218
1310
  footer: role.user === "agent" && /* @__PURE__ */ jsxs(Flex, { children: [
1219
- /* @__PURE__ */ jsx(Button, { onClick: () => copy(message3.msgContent), color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(CopyOutlined, {}) }),
1311
+ /* @__PURE__ */ jsx(Button, { onClick: () => copyText(message2.msgContent), color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(CopyOutlined, {}) }),
1220
1312
  /* @__PURE__ */ jsx(
1221
1313
  Button,
1222
1314
  {
1223
- color: message3.msgFeedback === 1 ? "primary" : "default",
1224
- disabled: !!message3.type,
1315
+ color: message2.msgFeedback === 1 ? "primary" : "default",
1316
+ disabled: !!message2.type,
1225
1317
  size: "small",
1226
1318
  variant: "text",
1227
1319
  icon: /* @__PURE__ */ jsx(LikeOutlined, {}),
1228
- onClick: () => chatStore.feedback(conversationState.active.id, message3.id, 1, index)
1320
+ onClick: () => chatStore.feedback(conversationState.active.id, message2.id, 1, index)
1229
1321
  }
1230
1322
  ),
1231
1323
  /* @__PURE__ */ jsx(
1232
1324
  Button,
1233
1325
  {
1234
- color: message3.msgFeedback === 2 ? "primary" : "default",
1235
- disabled: !!message3.type,
1326
+ color: message2.msgFeedback === 2 ? "primary" : "default",
1327
+ disabled: !!message2.type,
1236
1328
  size: "small",
1237
1329
  variant: "text",
1238
1330
  icon: /* @__PURE__ */ jsx(DislikeOutlined, {}),
1239
- onClick: () => chatStore.feedback(conversationState.active.id, message3.id, 2, index)
1331
+ onClick: () => chatStore.feedback(conversationState.active.id, message2.id, 2, index)
1240
1332
  }
1241
1333
  )
1242
1334
  ] })
@@ -1259,23 +1351,19 @@ var BubbleListItems_default = ({ firstMessage = false, avatar = { user: false, a
1259
1351
  }, [firstMessage]);
1260
1352
  const bubbleListItems = useMemo(() => {
1261
1353
  const list = [];
1262
- if (firstMessageRecord.length > 0) {
1263
- list.push(...firstMessageRecord);
1264
- }
1265
- if (chatRecords.length > 0) {
1266
- list.push(...chatRecords, ...questionList);
1267
- }
1354
+ list.push(...firstMessageRecord);
1355
+ list.push(...chatRecords, ...questionList);
1268
1356
  if (list.length) {
1269
1357
  return list;
1270
1358
  }
1271
- return [...placeholderNode];
1272
- }, [chatRecords, questionList, placeholderNode, firstMessageRecord]);
1359
+ return [...welcomeMessageRecord];
1360
+ }, [chatRecords, questionList, welcomeMessageRecord, firstMessageRecord]);
1273
1361
  const listRef = useRef(null);
1274
1362
  const autoScrollRef = useRef(true);
1275
1363
  const handleScroll = (el) => {
1276
1364
  const target = el.target;
1277
1365
  const distanceToBottom = target.scrollHeight - target.scrollTop - target.clientHeight;
1278
- autoScrollRef.current = distanceToBottom < 100;
1366
+ autoScrollRef.current = distanceToBottom < 150;
1279
1367
  };
1280
1368
  useEffect(() => {
1281
1369
  autoScrollRef.current = true;
@@ -1300,7 +1388,7 @@ var BubbleListItems_default = ({ firstMessage = false, avatar = { user: false, a
1300
1388
  autoScroll: false,
1301
1389
  ref: listRef,
1302
1390
  items: bubbleListItems,
1303
- className: classNames8(styles_module_default3.nsBubbleList, "height-full", "scroll-fade-in", "zero-chat-bubbles"),
1391
+ className: classNames9(styles_module_default3.nsBubbleList, "height-full", "scroll-fade-in", "zero-chat-bubbles"),
1304
1392
  onScroll: handleScroll
1305
1393
  },
1306
1394
  conversationState.active.id
@@ -1335,7 +1423,7 @@ var CharacterList_default = () => {
1335
1423
  /* @__PURE__ */ jsx(
1336
1424
  Avatar,
1337
1425
  {
1338
- className: classNames8(styles_module_default3.nsAvatarListItemIcon, "cursor-pointer", {
1426
+ className: classNames9(styles_module_default3.nsAvatarListItemIcon, "cursor-pointer", {
1339
1427
  [styles_module_default3.nsAvatarListItemIconActive]: activeCharacter.id === item.id
1340
1428
  }),
1341
1429
  size: 50,
@@ -1422,6 +1510,7 @@ var ConversationList_default = () => {
1422
1510
  };
1423
1511
  var ChatHeader_default = ({
1424
1512
  title = true,
1513
+ avatar = true,
1425
1514
  closeBtn = false,
1426
1515
  newConversationBtn = true,
1427
1516
  agentCharacter = true,
@@ -1430,18 +1519,10 @@ var ChatHeader_default = ({
1430
1519
  const chatStore = useChatStore();
1431
1520
  const receiverState = useSnapshot(chatStore.receiver);
1432
1521
  const configState = useSnapshot(chatStore.config);
1433
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", className: classNames8(styles_module_default3.nsChatHeader, "zero-chat-header"), children: [
1522
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", className: classNames9(styles_module_default3.nsChatHeader, "zero-chat-header"), children: [
1434
1523
  /* @__PURE__ */ jsxs(Flex, { gap: 4, align: "center", children: [
1435
- /* @__PURE__ */ jsx(
1436
- RenderWrapper,
1437
- {
1438
- control: title,
1439
- DefaultComponent: /* @__PURE__ */ jsxs(Fragment, { children: [
1440
- /* @__PURE__ */ jsx(Avatar, { size: 22, src: receiverState.active.logo, alt: receiverState.active.name }),
1441
- /* @__PURE__ */ jsx("div", { className: styles_module_default3.nsChatTitle, children: receiverState.active.name })
1442
- ] })
1443
- }
1444
- ),
1524
+ /* @__PURE__ */ jsx(RenderWrapper, { control: avatar, DefaultComponent: /* @__PURE__ */ jsx(Avatar, { size: 22, src: receiverState.active.logo, alt: receiverState.active.name }) }),
1525
+ /* @__PURE__ */ jsx(RenderWrapper, { control: title, DefaultComponent: /* @__PURE__ */ jsx("div", { className: styles_module_default3.nsChatTitle, children: receiverState.active.name }) }),
1445
1526
  " "
1446
1527
  ] }),
1447
1528
  /* @__PURE__ */ jsxs(Space, { size: 2, children: [
@@ -1481,7 +1562,7 @@ var ChatHeader_default = ({
1481
1562
  ] }) });
1482
1563
  };
1483
1564
  var Attachments_default = forwardRef(({ fileUpload, fileUploadConfig = [], fileList = [], onChange, extraParams }, ref) => {
1484
- const { message: message3 } = App.useApp();
1565
+ const { message: message2 } = App.useApp();
1485
1566
  const fileListRef = useRef([]);
1486
1567
  const [attachedFiles, setAttachedFiles, getAttachedFiles] = useRefState([]);
1487
1568
  useEffect(() => {
@@ -1509,7 +1590,7 @@ var Attachments_default = forwardRef(({ fileUpload, fileUploadConfig = [], fileL
1509
1590
  onChange(files);
1510
1591
  }, [attachedFiles]);
1511
1592
  const onErrorTip = useDebounce((errorMsg) => {
1512
- message3.error(errorMsg);
1593
+ message2.error(errorMsg);
1513
1594
  }, 300);
1514
1595
  const findConfigByFile = (file) => {
1515
1596
  return fileUploadConfig.find((cfg) => cfg.allowedFileTypes?.includes(getFileSuffixName(file.name).toLocaleUpperCase()));
@@ -1740,7 +1821,7 @@ var SenderPromptsItems_default = () => {
1740
1821
  title: /* @__PURE__ */ jsx(
1741
1822
  "div",
1742
1823
  {
1743
- className: classNames8(styles_module_default3.nsSenderListTitle, "text-ellipsis"),
1824
+ className: classNames9(styles_module_default3.nsSenderListTitle, "text-ellipsis"),
1744
1825
  children: `${receiverState.active.name}\u5F00\u59CB\u5173\u6CE8${question.name}\u5185\u5BB9\uFF01`
1745
1826
  }
1746
1827
  ),
@@ -1869,7 +1950,7 @@ var ConversationListHeader_default = () => {
1869
1950
  type: "primary",
1870
1951
  shape: "round",
1871
1952
  onClick: () => chatStore.createConversation(),
1872
- className: classNames8("m-t-16"),
1953
+ className: classNames9("m-t-16"),
1873
1954
  icon: /* @__PURE__ */ jsx(PlusOutlined, {}),
1874
1955
  children: "\u65B0\u5EFA\u4F1A\u8BDD"
1875
1956
  }
@@ -1877,7 +1958,7 @@ var ConversationListHeader_default = () => {
1877
1958
  ] });
1878
1959
  };
1879
1960
  var ConversationListPanel_default = ({ header }) => {
1880
- return /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames8("height-full", "zero-chat-conversations", styles_module_default3.nsConversationListPanel), children: [
1961
+ return /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames9("height-full", "zero-chat-conversations", styles_module_default3.nsConversationListPanel), children: [
1881
1962
  /* @__PURE__ */ jsx(RenderWrapper, { control: header, DefaultComponent: ConversationListHeader_default }),
1882
1963
  /* @__PURE__ */ jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsx(ConversationList_default, {}) })
1883
1964
  ] });
@@ -1896,6 +1977,18 @@ var styles_module_default4 = {
1896
1977
  var layouts_default = forwardRef(({ theme, params, userInfo, hooks, layout, config, services }, ref) => {
1897
1978
  const chatStore = useMemo(() => createChatStore(), []);
1898
1979
  const senderRef = useRef();
1980
+ useEffect(() => {
1981
+ chatStore.setHooks(hooks);
1982
+ }, [hooks]);
1983
+ useEffect(() => {
1984
+ chatStore.setUserInfo(userInfo);
1985
+ }, [userInfo]);
1986
+ useEffect(() => {
1987
+ chatStore.setLayout(layout, config?.receiverType);
1988
+ }, [layout, config?.receiverType]);
1989
+ useEffect(() => {
1990
+ chatStore.setParams(params);
1991
+ }, [params]);
1899
1992
  useDeepEffect(() => {
1900
1993
  chatStore.setServices(services);
1901
1994
  }, [services]);
@@ -1908,18 +2001,6 @@ var layouts_default = forwardRef(({ theme, params, userInfo, hooks, layout, conf
1908
2001
  chatStore.switchAgentConversation(config.receiverId, config.conversationStrategy);
1909
2002
  }
1910
2003
  }, [config]);
1911
- useEffect(() => {
1912
- chatStore.setUserInfo(userInfo);
1913
- }, [userInfo]);
1914
- useEffect(() => {
1915
- chatStore.setLayout(layout, config?.receiverType);
1916
- }, [layout, config?.receiverType]);
1917
- useEffect(() => {
1918
- chatStore.setParams(params);
1919
- }, [params]);
1920
- useEffect(() => {
1921
- chatStore.setHooks(hooks);
1922
- }, [hooks]);
1923
2004
  const receiverState = useSnapshot(chatStore.receiver);
1924
2005
  const configState = useSnapshot(chatStore.config);
1925
2006
  useImperativeHandle(
@@ -1955,19 +2036,13 @@ var layouts_default = forwardRef(({ theme, params, userInfo, hooks, layout, conf
1955
2036
  }
1956
2037
  }, [hasPreView]);
1957
2038
  useWebSocket({
1958
- url: configState.services.websocketBaseUrls?.[0] && getWebSocketUrl(
1959
- `${configState.services.websocketBaseUrls?.[0]}/lolr/conversation/ws/subscribe?NS-TOKEN=${getToken()}`,
1960
- isLocalhost() ? "192.168.3.102" : ""
1961
- ),
2039
+ url: configState.services.websocketUrls?.[0],
1962
2040
  onMessage: chatStore.acceptMessage,
1963
2041
  clientHeartbeat: false,
1964
2042
  reconnectInterval: 1e4
1965
2043
  });
1966
2044
  useWebSocket({
1967
- url: configState.services.websocketBaseUrls?.[1] && getWebSocketUrl(
1968
- `${configState.services.websocketBaseUrls?.[1]}/lolr/conversation/ws/subscribe?NS-TOKEN=${getToken()}`,
1969
- isLocalhost() ? "192.168.3.102" : ""
1970
- ),
2045
+ url: configState.services.websocketUrls?.[1],
1971
2046
  onMessage: chatStore.acceptMessage,
1972
2047
  clientHeartbeat: false,
1973
2048
  reconnectInterval: 1e4
@@ -1975,7 +2050,7 @@ var layouts_default = forwardRef(({ theme, params, userInfo, hooks, layout, conf
1975
2050
  useEffect(() => {
1976
2051
  configState.hooks?.onBeforeInit?.();
1977
2052
  }, []);
1978
- return /* @__PURE__ */ jsx(XProvider, { theme: { cssVar: true, ...theme }, children: /* @__PURE__ */ jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsx(Spin, { spinning: receiverState.loading, wrapperClassName: "full-spin", children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames8(styles_module_default4.nsChatLayout, "zero-chat-layout", "height-full"), children: [
2053
+ return /* @__PURE__ */ jsx(XProvider, { theme: { cssVar: true, ...theme }, children: /* @__PURE__ */ jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsx(Spin, { spinning: receiverState.loading, wrapperClassName: "full-spin", children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames9(styles_module_default4.nsChatLayout, "zero-chat-layout", "height-full"), children: [
1979
2054
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: ChatHeader_default }),
1980
2055
  /* @__PURE__ */ jsxs(Flex, { className: "full-scroll", children: [
1981
2056
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.leftPanel }),
@@ -2029,15 +2104,15 @@ var layouts_default = forwardRef(({ theme, params, userInfo, hooks, layout, conf
2029
2104
  }
2030
2105
  )
2031
2106
  ] }) }),
2032
- /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, max: 800, min: 400, size: sizes[1], children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames8("height-full"), children: [
2107
+ /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, max: 800, min: 400, size: sizes[1], children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames9("height-full"), children: [
2033
2108
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: ChatHeader_default }),
2034
- /* @__PURE__ */ jsx(Flex, { vertical: true, className: classNames8("full-scroll"), children: /* @__PURE__ */ jsxs(
2109
+ /* @__PURE__ */ jsx(Flex, { vertical: true, className: classNames9("full-scroll"), children: /* @__PURE__ */ jsxs(
2035
2110
  Flex,
2036
2111
  {
2037
2112
  justify: "center",
2038
2113
  vertical: true,
2039
2114
  gap: 24,
2040
- className: classNames8("height-full", styles_module_default4.nsChatBody, "zero-chat-body", styles_module_default4.nsBodyWidth),
2115
+ className: classNames9("height-full", styles_module_default4.nsChatBody, "zero-chat-body", styles_module_default4.nsBodyWidth),
2041
2116
  children: [
2042
2117
  shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.messageList, DefaultComponent: BubbleListItems_default }) }),
2043
2118
  /* @__PURE__ */ jsxs(Flex, { vertical: true, gap: 8, children: [