@zero-library/chat-agent 2.0.7 → 2.0.8

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.d.mts CHANGED
@@ -56,18 +56,18 @@ interface ChatParams {
56
56
  params?: ObjectType<any>;
57
57
  }
58
58
  interface ChatLayoutHeader {
59
- title: RenderControl<void, void>;
60
- closeBtn: boolean;
61
- newConversationBtn: RenderControl<void, void>;
62
- conversationListBtn: boolean;
59
+ title?: RenderControl<void, void>;
60
+ closeBtn?: boolean;
61
+ newConversationBtn?: RenderControl<void, void>;
62
+ conversationListBtn?: boolean;
63
63
  }
64
64
  interface ChatLayoutConversationList {
65
- header: RenderControl<void, void>;
65
+ header?: RenderControl<void, void>;
66
66
  }
67
67
  interface ChatLayoutSender {
68
68
  placeholder?: string;
69
- extraBtn: RenderControl<void, void>;
70
- referencesBtn: RenderControl<void, void>;
69
+ extraBtn?: RenderControl<void, void>;
70
+ referencesBtn?: RenderControl<void, void>;
71
71
  }
72
72
  interface ChatLayout {
73
73
  leftPanel?: RenderControl<void, void>;
package/dist/index.d.ts CHANGED
@@ -56,18 +56,18 @@ interface ChatParams {
56
56
  params?: ObjectType<any>;
57
57
  }
58
58
  interface ChatLayoutHeader {
59
- title: RenderControl<void, void>;
60
- closeBtn: boolean;
61
- newConversationBtn: RenderControl<void, void>;
62
- conversationListBtn: boolean;
59
+ title?: RenderControl<void, void>;
60
+ closeBtn?: boolean;
61
+ newConversationBtn?: RenderControl<void, void>;
62
+ conversationListBtn?: boolean;
63
63
  }
64
64
  interface ChatLayoutConversationList {
65
- header: RenderControl<void, void>;
65
+ header?: RenderControl<void, void>;
66
66
  }
67
67
  interface ChatLayoutSender {
68
68
  placeholder?: string;
69
- extraBtn: RenderControl<void, void>;
70
- referencesBtn: RenderControl<void, void>;
69
+ extraBtn?: RenderControl<void, void>;
70
+ referencesBtn?: RenderControl<void, void>;
71
71
  }
72
72
  interface ChatLayout {
73
73
  leftPanel?: RenderControl<void, void>;
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useRefState, useDebounce, isNumber, useSyncInput, shouldRender, RenderWrapper, downloadFile, FilePreview, MarkdownEditor, createValtioContext, isObject, isNullOrUnDef, isBoolean, UserAvatar, request as request$1, getCurrentUser, deepMerge, RenderMarkdown, OK, getToken, TOKEN_KEY, copyText, FileIcon, isExternal } from '@zero-library/common';
1
+ import { useRefState, useDebounce, isNumber, useSyncInput, shouldRender, RenderWrapper, downloadFile, FilePreview, MarkdownEditor, createValtioContext, isObject, isNullOrUnDef, isBoolean, UserAvatar, request, getCurrentUser, deepMerge, RenderMarkdown, OK, getToken, TOKEN_KEY, copyText, FileIcon, isExternal } from '@zero-library/common';
2
2
  import { message, Badge, Button, Flex, Spin, Splitter, Tag, Avatar, Space, Popover, List, Typography, Empty, Collapse, Drawer } from 'antd';
3
3
  import dayjs from 'dayjs';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -18,6 +18,19 @@ var __export = (target, all) => {
18
18
  for (var name in all)
19
19
  __defProp(target, name, { get: all[name], enumerable: true });
20
20
  };
21
+ var docQuery, fileCreate;
22
+ var init_file = __esm({
23
+ "src/services/file.ts"() {
24
+ docQuery = (paramsStr) => {
25
+ return request.get(`/uc/doc?${paramsStr}`);
26
+ };
27
+ fileCreate = async (fileContent, fileName, targetFormat = "docx") => {
28
+ const blob = await request.post(`/uc/doc/convert`, { fileContent, fileName, targetFormat }, { responseType: "blob" });
29
+ const url = URL.createObjectURL(blob);
30
+ downloadFile(url, fileName);
31
+ };
32
+ }
33
+ });
21
34
  function transform(source, fieldMap) {
22
35
  const result = {};
23
36
  for (const [targetKey, mapping] of Object.entries(fieldMap)) {
@@ -144,14 +157,6 @@ var init_FileView = __esm({
144
157
  };
145
158
  }
146
159
  });
147
- var docQuery;
148
- var init_file = __esm({
149
- "src/services/file.ts"() {
150
- docQuery = (paramsStr) => {
151
- return request$1.get(`/uc/doc?${paramsStr}`);
152
- };
153
- }
154
- });
155
160
  var DocDrawer_default;
156
161
  var init_DocDrawer = __esm({
157
162
  "src/ui/common/markdownAlert/components/DocDrawer.tsx"() {
@@ -309,6 +314,9 @@ var init_QuoteList = __esm({
309
314
  }
310
315
  });
311
316
 
317
+ // src/ui/layouts/index.tsx
318
+ init_file();
319
+
312
320
  // src/core/constants.ts
313
321
  var DEFAULT_NEW_CONV_ID = "newConvId";
314
322
  var ChatRoleMap = {
@@ -384,7 +392,7 @@ async function handleStreamResponse(response, options) {
384
392
  buffer = parseBuffer(buffer, onChunk);
385
393
  }
386
394
  }
387
- async function request(url, data = {}, options = {}) {
395
+ async function request2(url, data = {}, options = {}) {
388
396
  const { stream = false, method = "POST", headers = {}, signal } = options;
389
397
  const controller = new AbortController();
390
398
  signal?.addEventListener("abort", () => controller.abort());
@@ -421,36 +429,36 @@ async function request(url, data = {}, options = {}) {
421
429
  }
422
430
  return r;
423
431
  }
424
- var get = (url, params = {}, options = {}) => request(url, params, { ...options, method: "GET" });
425
- var post = (url, data = {}, options = {}) => request(url, data, { ...options, method: "POST" });
426
- var put = (url, data = {}, options = {}) => request(url, data, { ...options, method: "PUT" });
427
- var del = (url, data = {}, options = {}) => request(url, data, { ...options, method: "DELETE" });
432
+ var get = (url, params = {}, options = {}) => request2(url, params, { ...options, method: "GET" });
433
+ var post = (url, data = {}, options = {}) => request2(url, data, { ...options, method: "POST" });
434
+ var put = (url, data = {}, options = {}) => request2(url, data, { ...options, method: "PUT" });
435
+ var del = (url, data = {}, options = {}) => request2(url, data, { ...options, method: "DELETE" });
428
436
  var fetchRequest_default = { delete: del, get, post, put };
429
437
 
430
438
  // src/services/index.ts
431
439
  var agentInfoQuery = (agentId) => {
432
- return request$1.get("/agent/detail", { agentId });
440
+ return request.get("/agent/detail", { agentId });
433
441
  };
434
442
  var agentsQuery = () => {
435
- return request$1.get("/agent");
443
+ return request.get("/agent");
436
444
  };
437
445
  var conversationsQuery = (params) => {
438
- return request$1.get("/agent/conversation", params);
446
+ return request.get("/agent/conversation", params);
439
447
  };
440
448
  var deleteConversation = (params) => {
441
- return request$1.delete("/agent/conversation", params);
449
+ return request.delete("/agent/conversation", params);
442
450
  };
443
451
  var chatMessagesQuery = (params) => {
444
- return request$1.get("/agent/message", params);
452
+ return request.get("/agent/message", params);
445
453
  };
446
454
  var chatMessageSuggestedQuery = (agentId, messageId) => {
447
- return request$1.get("/agent/message/suggested", { agentId, messageId });
455
+ return request.get("/agent/message/suggested", { agentId, messageId });
448
456
  };
449
457
  var updateFeedback = (params) => {
450
- return request$1.put("/agent/message/feedback", params);
458
+ return request.put("/agent/message/feedback", params);
451
459
  };
452
460
  var uploadFile = (formData) => {
453
- return request$1.post("/agent/file", formData);
461
+ return request.post("/agent/file", formData);
454
462
  };
455
463
  var sendChatMessage = (params) => {
456
464
  return fetchRequest_default.post(
@@ -943,7 +951,6 @@ var ConversationList_default = () => {
943
951
  ) : /* @__PURE__ */ jsx(Empty, { description: "\u6682\u65E0\u4F1A\u8BDD\u8BB0\u5F55", image: Empty.PRESENTED_IMAGE_SIMPLE }) }) });
944
952
  };
945
953
  var AgentHeader_default = ({ title = true, closeBtn = false, newConversationBtn = true, conversationListBtn = true }) => {
946
- console.log("AgentHeader", title, closeBtn, newConversationBtn, conversationListBtn);
947
954
  const chatStore = useChatStore();
948
955
  const agentState = useSnapshot(chatStore.agent);
949
956
  const configState = useSnapshot(chatStore.config);
@@ -1240,17 +1247,37 @@ var BubbleListItems_default = ({ avatar = true }) => {
1240
1247
  return [...placeholderNode];
1241
1248
  }, [chatRecords, questionList, placeholderNode]);
1242
1249
  const listRef = useRef(null);
1250
+ const autoScrollRef = useRef(true);
1251
+ const handleScroll = (el) => {
1252
+ const target = el.target;
1253
+ const distanceToBottom = target.scrollHeight - target.scrollTop - target.clientHeight;
1254
+ autoScrollRef.current = distanceToBottom < 100;
1255
+ };
1243
1256
  useEffect(() => {
1244
- if (bubbleListItems.length && (listRef.current?.nativeElement.scrollHeight ?? 0) - ((listRef.current?.nativeElement.scrollTop ?? 0) + (listRef.current?.nativeElement.clientHeight ?? 0)) < 100) {
1245
- listRef.current?.scrollTo({ key: bubbleListItems[bubbleListItems.length - 1].key, block: "end" });
1257
+ autoScrollRef.current = true;
1258
+ }, [bubbleListItems.length]);
1259
+ useEffect(() => {
1260
+ const el = listRef.current?.nativeElement;
1261
+ if (!el || !bubbleListItems.length) return;
1262
+ if (autoScrollRef.current) {
1263
+ setTimeout(() => {
1264
+ if (autoScrollRef.current) {
1265
+ listRef.current?.scrollTo({
1266
+ key: bubbleListItems[bubbleListItems.length - 1].key,
1267
+ block: "end"
1268
+ });
1269
+ }
1270
+ }, 100);
1246
1271
  }
1247
1272
  }, [bubbleListItems]);
1248
1273
  return /* @__PURE__ */ jsx(
1249
1274
  Bubble.List,
1250
1275
  {
1276
+ autoScroll: false,
1251
1277
  ref: listRef,
1252
1278
  items: bubbleListItems,
1253
- className: classNames6(styles_module_default.nsBubbleList, "height-full", "scroll-fade-in")
1279
+ className: classNames6(styles_module_default.nsBubbleList, "height-full", "scroll-fade-in"),
1280
+ onScroll: handleScroll
1254
1281
  },
1255
1282
  conversationState.active.key
1256
1283
  );
@@ -1690,19 +1717,27 @@ var layouts_default = forwardRef(({ theme, params, hooks, layout, defaultAgent }
1690
1717
  }),
1691
1718
  []
1692
1719
  );
1693
- const setSplitterSizes = (sizes) => {
1694
- console.log(sizes);
1695
- };
1696
1720
  const hasPreView = useMemo(() => {
1697
1721
  return shouldRender(configState.layout.preview) && (!!configState.preview.file.fileUrl || !!configState.preview.file.content);
1698
1722
  }, [configState.layout.preview, configState.preview.file]);
1723
+ const [sizes, setSizes] = useState([0, "100%"]);
1724
+ const setSplitterSizes = (sizes2) => {
1725
+ setSizes(sizes2);
1726
+ };
1727
+ useEffect(() => {
1728
+ if (hasPreView) {
1729
+ setSplitterSizes(["70%", "30%"]);
1730
+ } else {
1731
+ setSplitterSizes([0, "100%"]);
1732
+ }
1733
+ }, [hasPreView]);
1699
1734
  return /* @__PURE__ */ jsx(XProvider, { theme: { cssVar: true, ...theme }, children: /* @__PURE__ */ jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsx(Spin, { spinning: agentState.loading, wrapperClassName: "full-spin", children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames6(styles_module_default3.nsChatLayout, "height-full"), children: [
1700
1735
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: AgentHeader_default }),
1701
1736
  /* @__PURE__ */ jsxs(Flex, { className: "full-scroll", children: [
1702
1737
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.leftPanel, DefaultComponent: /* @__PURE__ */ jsx(Fragment, {}) }),
1703
1738
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.conversationList, DefaultComponent: ConversationListPanel_default }),
1704
- /* @__PURE__ */ jsxs(Splitter, { onResize: setSplitterSizes, children: [
1705
- hasPreView && /* @__PURE__ */ jsxs(Splitter.Panel, { collapsible: false, resizable: false, children: [
1739
+ /* @__PURE__ */ jsxs(Splitter, { className: "flex-1", onResize: setSplitterSizes, children: [
1740
+ /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, min: 600, size: sizes[0], children: hasPreView && /* @__PURE__ */ jsxs(Fragment, { children: [
1706
1741
  configState.preview.file.fileUrl && /* @__PURE__ */ jsxs(Flex, { vertical: true, className: "height-full", children: [
1707
1742
  /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default3.nsPreviewHeader, children: [
1708
1743
  /* @__PURE__ */ jsx("div", { className: styles_module_default3.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
@@ -1745,11 +1780,12 @@ var layouts_default = forwardRef(({ theme, params, hooks, layout, defaultAgent }
1745
1780
  }
1746
1781
  });
1747
1782
  },
1783
+ onDownloadFile: (content, type) => fileCreate(content, configState.preview.file.fileName, type),
1748
1784
  extraNav: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tag, { bordered: false, color: "default", className: "cursor-pointer", onClick: () => chatStore.setPreview(), children: /* @__PURE__ */ jsx(CloseOutlined, {}) }) })
1749
1785
  }
1750
1786
  )
1751
- ] }),
1752
- /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, resizable: true, size: hasPreView ? 400 : void 0, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames6("height-full"), children: [
1787
+ ] }) }),
1788
+ /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, max: 800, min: 400, size: sizes[1], children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames6("height-full"), children: [
1753
1789
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: AgentHeader_default }),
1754
1790
  /* @__PURE__ */ jsx(Flex, { vertical: true, className: classNames6("full-scroll"), children: /* @__PURE__ */ jsxs(Flex, { justify: "center", vertical: true, gap: 24, className: classNames6("height-full p-t-8 p-b-8", styles_module_default.nsBodyWidth), children: [
1755
1791
  shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsx(