@zero-library/chat-agent 1.0.0 → 2.0.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/dist/index.esm.js CHANGED
@@ -1,13 +1,12 @@
1
- import { useRefState, useDebounce, isNumber, useSyncInput, shouldRender, RenderWrapper, downloadFile, FilePreview, isObject, isNullOrUnDef, isBoolean, UserAvatar, request as request$1, OK, getCurrentUser, deepMerge, copyText, RenderMarkdown, getToken, TOKEN_KEY, createValtioContext, FileIcon } from '@zero-library/common';
2
- import { message, Badge, Button, Flex, Spin, Splitter, Avatar, Space, Popover, List, Typography, Collapse, Tag, Card } from 'antd';
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';
2
+ import { message, Badge, Button, Flex, Spin, Splitter, Tag, Avatar, Empty, Space, Popover, List, Typography, Collapse, Drawer } from 'antd';
3
+ import dayjs from 'dayjs';
3
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import TextArea from 'antd/es/input/TextArea';
5
5
  import { forwardRef, useRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
6
- import { CloudUploadOutlined, PaperClipOutlined, PlusOutlined, DeleteOutlined, RedoOutlined, CommentOutlined, CloseOutlined, OpenAIOutlined, CopyOutlined, LikeOutlined, DislikeOutlined, EnterOutlined, CloseCircleOutlined, CaretRightOutlined } from '@ant-design/icons';
7
- import { useSnapshot, proxy } from 'valtio';
8
- import dayjs from 'dayjs';
6
+ import { CloudUploadOutlined, PaperClipOutlined, CloseOutlined, PlusOutlined, DeleteOutlined, RedoOutlined, CommentOutlined, OpenAIOutlined, CopyOutlined, LikeOutlined, DislikeOutlined, EnterOutlined, CloseCircleOutlined, PlayCircleOutlined, CaretRightOutlined } from '@ant-design/icons';
9
7
  import { Attachments, Sender, Suggestion, XProvider, Conversations, Welcome, Prompts, Bubble } from '@ant-design/x';
10
8
  import classNames2 from 'classnames';
9
+ import { useSnapshot, proxy } from 'valtio';
11
10
  import InfiniteScroll from 'react-infinite-scroll-component';
12
11
 
13
12
  var __defProp = Object.defineProperty;
@@ -19,6 +18,64 @@ var __export = (target, all) => {
19
18
  for (var name in all)
20
19
  __defProp(target, name, { get: all[name], enumerable: true });
21
20
  };
21
+ function transform(source, fieldMap) {
22
+ const result = {};
23
+ for (const [targetKey, mapping] of Object.entries(fieldMap)) {
24
+ const key = targetKey;
25
+ if (typeof mapping === "function") {
26
+ result[key] = mapping(source);
27
+ } else if (typeof mapping === "string" && source && mapping in source) {
28
+ result[key] = source[mapping];
29
+ } else {
30
+ result[key] = mapping;
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ function transforms(sources, fieldMap) {
36
+ return sources?.map((source) => transform(source, fieldMap)) || [];
37
+ }
38
+ function buildURLWithParams(url, params) {
39
+ const query = new URLSearchParams(
40
+ Object.entries(params || {}).flatMap(([key, val]) => Array.isArray(val) ? val.map((v) => [key, String(v)]) : [[key, String(val)]])
41
+ ).toString();
42
+ return query ? `${url}${url.includes("?") ? "&" : "?"}${query}` : url;
43
+ }
44
+ var copy, classifyTime, getBase64;
45
+ var init_utils = __esm({
46
+ "src/core/utils.ts"() {
47
+ copy = (value) => {
48
+ copyText(value).then(() => {
49
+ message.success("\u590D\u5236\u6210\u529F");
50
+ });
51
+ };
52
+ classifyTime = (timestamp) => {
53
+ const now = dayjs();
54
+ const target = dayjs(timestamp);
55
+ if (target.isSame(now, "day")) {
56
+ return "\u4ECA\u5929";
57
+ }
58
+ const diffInDays = now.diff(target, "day");
59
+ if (diffInDays < 7) {
60
+ return "\u6700\u8FD1 7 \u5929";
61
+ } else if (diffInDays < 30) {
62
+ return "\u6700\u8FD1 30 \u5929";
63
+ } else if (diffInDays < 180) {
64
+ return "\u6700\u8FD1\u534A\u5E74";
65
+ } else {
66
+ return "\u66F4\u65E9";
67
+ }
68
+ };
69
+ getBase64 = (file) => {
70
+ return new Promise((resolve, reject) => {
71
+ const reader = new FileReader();
72
+ reader.onload = () => resolve(reader.result);
73
+ reader.onerror = reject;
74
+ reader.readAsDataURL(file);
75
+ });
76
+ };
77
+ }
78
+ });
22
79
  var ChatProvider, useChatStore;
23
80
  var init_Context = __esm({
24
81
  "src/stores/Context.ts"() {
@@ -33,7 +90,11 @@ var init_styles_module = __esm({
33
90
  styles_module_default2 = {
34
91
  appCard: "styles_module_appCard",
35
92
  fileView: "styles_module_fileView",
36
- quoteList: "styles_module_quoteList"
93
+ fileEdit: "styles_module_fileEdit",
94
+ fileEditHeader: "styles_module_fileEditHeader",
95
+ fileEditContent: "styles_module_fileEditContent",
96
+ quoteList: "styles_module_quoteList",
97
+ mdEdit: "styles_module_mdEdit"
37
98
  };
38
99
  }
39
100
  });
@@ -83,6 +144,37 @@ var init_FileView = __esm({
83
144
  };
84
145
  }
85
146
  });
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
+ var DocDrawer_default;
156
+ var init_DocDrawer = __esm({
157
+ "src/ui/common/markdownAlert/components/DocDrawer.tsx"() {
158
+ init_file();
159
+ DocDrawer_default = ({ title, open, onClose, fileUrl }) => {
160
+ const [content, setContent] = useState("");
161
+ const [loading, setLoading] = useState(false);
162
+ const getContent = async () => {
163
+ try {
164
+ setLoading(true);
165
+ const res = await docQuery(fileUrl);
166
+ setContent(res.data?.content);
167
+ } finally {
168
+ setLoading(false);
169
+ }
170
+ };
171
+ useEffect(() => {
172
+ getContent();
173
+ }, [fileUrl]);
174
+ return /* @__PURE__ */ jsx(Drawer, { title, push: false, width: "100%", open, onClose, children: /* @__PURE__ */ jsx(Spin, { spinning: loading, children: content ? /* @__PURE__ */ jsx(RenderMarkdown, { content }) : /* @__PURE__ */ jsx(Empty, { className: "m-t-32" }) }) });
175
+ };
176
+ }
177
+ });
86
178
 
87
179
  // src/ui/common/markdownAlert/IndexQuote.tsx
88
180
  var IndexQuote_exports = {};
@@ -92,52 +184,58 @@ __export(IndexQuote_exports, {
92
184
  var IndexQuote_default;
93
185
  var init_IndexQuote = __esm({
94
186
  "src/ui/common/markdownAlert/IndexQuote.tsx"() {
187
+ init_DocDrawer();
95
188
  IndexQuote_default = ({ data, loading }) => {
189
+ const [open, setOpen] = useState(false);
96
190
  const onClick = () => {
97
- window.open(data.fileUrl, "_blank");
191
+ if (!data.fileUrl) return;
192
+ if (isExternal(data.fileUrl)) {
193
+ window.open(data.fileUrl, "_blank");
194
+ } else {
195
+ setOpen(true);
196
+ }
98
197
  };
99
- const Content = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 8, children: [
100
- /* @__PURE__ */ jsx(FileIcon, { suffix: data.suffix, fontSize: 16 }),
101
- /* @__PURE__ */ jsx("a", { onClick, children: data.fileName })
102
- ] }) });
103
- return /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", wrapperClassName: "inline-block index-quote", children: /* @__PURE__ */ jsx(Popover, { content: Content, title: data.title, children: /* @__PURE__ */ jsx(Tag, { bordered: false, color: "processing", className: "cursor-pointer", children: data.index }) }) });
198
+ const Content = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Flex, { align: "center", gap: 8, children: /* @__PURE__ */ jsx("a", { onClick, children: data.fileName }) }) });
199
+ const rootRef = useRef(null);
200
+ useEffect(() => {
201
+ const el = rootRef.current;
202
+ if (!el) return;
203
+ const previous = el.previousElementSibling;
204
+ if (!previous) return;
205
+ previous.appendChild(el);
206
+ }, []);
207
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: "inline-block m-l-8", children: [
208
+ /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsx(Popover, { content: Content, children: /* @__PURE__ */ jsx(Tag, { bordered: false, color: "processing", className: "cursor-pointer", children: data.index }) }) }),
209
+ open && /* @__PURE__ */ jsx(DocDrawer_default, { fileUrl: data.fileUrl, title: data.fileName, open, onClose: () => setOpen(false) })
210
+ ] });
104
211
  };
105
212
  }
106
213
  });
107
214
 
108
- // src/ui/common/markdownAlert/EditableMarkdownCard.tsx
109
- var EditableMarkdownCard_exports = {};
110
- __export(EditableMarkdownCard_exports, {
111
- default: () => EditableMarkdownCard_default
215
+ // src/ui/common/markdownAlert/MdEdit.tsx
216
+ var MdEdit_exports = {};
217
+ __export(MdEdit_exports, {
218
+ default: () => MdEdit_default
112
219
  });
113
- var EditableMarkdownCard_default;
114
- var init_EditableMarkdownCard = __esm({
115
- "src/ui/common/markdownAlert/EditableMarkdownCard.tsx"() {
116
- EditableMarkdownCard_default = ({ data, loading }) => {
117
- const [editing, setEditing] = useState(false);
118
- const [value, setValue] = useState(data.content || "");
119
- const wrapperRef = useRef(null);
120
- useEffect(() => {
121
- const handleClickOutside = (e) => {
122
- if (editing && wrapperRef.current && !wrapperRef.current.contains(e.target)) {
123
- setEditing(false);
124
- }
125
- };
126
- document.addEventListener("mousedown", handleClickOutside);
127
- return () => document.removeEventListener("mousedown", handleClickOutside);
128
- }, [editing]);
220
+ var MdEdit_default;
221
+ var init_MdEdit = __esm({
222
+ "src/ui/common/markdownAlert/MdEdit.tsx"() {
223
+ init_Context();
224
+ init_styles_module();
225
+ MdEdit_default = ({ data, loading }) => {
226
+ const chatStore = useChatStore();
227
+ const [value, setValue] = useState("");
228
+ const onOk = () => {
229
+ console.log("value", value);
230
+ chatStore.sendMessage("\u5F00\u59CB\u5199\u4F5C", [], { outline: value });
231
+ };
129
232
  useEffect(() => {
130
- if (value !== data.content) ;
131
- }, [value]);
132
- return /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsx(Card, { ref: wrapperRef, children: editing ? /* @__PURE__ */ jsx(
133
- TextArea,
134
- {
135
- autoSize: { minRows: 4, maxRows: 16 },
136
- value,
137
- onChange: (e) => setValue(e.target.value),
138
- placeholder: "\u8BF7\u8F93\u5165 Markdown \u5185\u5BB9..."
139
- }
140
- ) : /* @__PURE__ */ jsx("div", { onClick: () => setEditing(true), style: { cursor: "pointer", minHeight: 24 }, children: /* @__PURE__ */ jsx(RenderMarkdown, { content: value }) }) }) });
233
+ setValue(data.content);
234
+ }, [data.content]);
235
+ return /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxs("div", { className: styles_module_default2.mdEdit, children: [
236
+ /* @__PURE__ */ jsx(MarkdownEditor, { disabled: loading, value, onChange: setValue, showToolbar: false }),
237
+ !loading && /* @__PURE__ */ jsx(Flex, { justify: "end", className: "m-t-16", children: /* @__PURE__ */ jsx(Button, { color: "primary", variant: "outlined", onClick: onOk, children: "\u786E\u8BA4\u63D0\u7EB2\u601D\u8DEF\uFF0C\u5F00\u59CB\u5199\u4F5C" }) })
238
+ ] }) });
141
239
  };
142
240
  }
143
241
  });
@@ -150,17 +248,27 @@ __export(FileEdit_exports, {
150
248
  var FileEdit_default;
151
249
  var init_FileEdit = __esm({
152
250
  "src/ui/common/markdownAlert/FileEdit.tsx"() {
251
+ init_utils();
153
252
  init_Context();
154
253
  init_styles_module();
155
254
  FileEdit_default = ({ data, loading }) => {
156
255
  const chatStore = useChatStore();
157
- const onClick = () => {
158
- chatStore.setPreview(data, false);
256
+ const onPreview = () => {
257
+ chatStore.setPreview(data, true);
159
258
  };
160
- return /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxs(Flex, { gap: 8, align: "center", className: styles_module_default2.fileView, onClick, children: [
161
- /* @__PURE__ */ jsx(FileIcon, { suffix: data.suffix }),
162
- /* @__PURE__ */ jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
163
- ] }) });
259
+ return /* @__PURE__ */ jsxs(Flex, { vertical: true, className: styles_module_default2.fileEdit, children: [
260
+ /* @__PURE__ */ jsxs(Flex, { gap: 8, align: "center", justify: "space-between", className: styles_module_default2.fileEditHeader, children: [
261
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, align: "center", className: "flex-1", children: [
262
+ /* @__PURE__ */ jsx(FileIcon, { suffix: "md", fontSize: 18 }),
263
+ /* @__PURE__ */ jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
264
+ ] }),
265
+ /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxs(Flex, { children: [
266
+ /* @__PURE__ */ jsx(Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(PlayCircleOutlined, {}), onClick: onPreview, children: "\u9884\u89C8\u7F16\u8F91" }),
267
+ /* @__PURE__ */ jsx(Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsx(CopyOutlined, {}), onClick: () => copy(data.content), children: "\u590D\u5236" })
268
+ ] }) })
269
+ ] }),
270
+ /* @__PURE__ */ jsx(Flex, { gap: 8, align: "center", className: styles_module_default2.fileEditContent, children: /* @__PURE__ */ jsx(RenderMarkdown, { content: data.content }) })
271
+ ] });
164
272
  };
165
273
  }
166
274
  });
@@ -173,28 +281,39 @@ __export(QuoteList_exports, {
173
281
  var QuoteList_default;
174
282
  var init_QuoteList = __esm({
175
283
  "src/ui/common/markdownAlert/QuoteList.tsx"() {
284
+ init_DocDrawer();
176
285
  init_styles_module();
177
286
  QuoteList_default = ({ data, loading }) => {
178
- console.log("QuoteList data", data, loading);
287
+ const [open, setOpen] = useState(false);
288
+ const [selectItem, setSelectItem] = useState({});
179
289
  const onClick = (item) => {
180
- window.open(item.fileUrl, "_blank");
181
- };
182
- return /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsx(
183
- Collapse,
184
- {
185
- className: styles_module_default2.quoteList,
186
- bordered: false,
187
- ghost: true,
188
- expandIcon: ({ isActive }) => /* @__PURE__ */ jsx(CaretRightOutlined, { rotate: isActive ? 90 : 0 }),
189
- items: [
190
- {
191
- key: "1",
192
- label: "\u53C2\u8003\u8D44\u6599",
193
- children: /* @__PURE__ */ jsx(Flex, { vertical: true, gap: 4, children: data.list.map((item) => /* @__PURE__ */ jsx("p", { onClick: () => onClick(item), className: "cursor-pointer", children: item.displayName }, item.fileUrl)) })
194
- }
195
- ]
290
+ if (!item.fileUrl) return;
291
+ if (isExternal(item.fileUrl)) {
292
+ window.open(item.fileUrl, "_blank");
293
+ } else {
294
+ setSelectItem(item);
295
+ setOpen(true);
196
296
  }
197
- ) });
297
+ };
298
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
299
+ /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsx(
300
+ Collapse,
301
+ {
302
+ className: styles_module_default2.quoteList,
303
+ bordered: false,
304
+ ghost: true,
305
+ expandIcon: ({ isActive }) => /* @__PURE__ */ jsx(CaretRightOutlined, { rotate: isActive ? 90 : 0 }),
306
+ items: [
307
+ {
308
+ key: "1",
309
+ label: "\u53C2\u8003\u8D44\u6599",
310
+ children: /* @__PURE__ */ jsx(Flex, { vertical: true, gap: 4, children: data.list.map((item) => /* @__PURE__ */ jsx("p", { onClick: () => onClick(item), className: "cursor-pointer", children: item.title }, item.fileUrl)) })
311
+ }
312
+ ]
313
+ }
314
+ ) }),
315
+ open && /* @__PURE__ */ jsx(DocDrawer_default, { fileUrl: selectItem.fileUrl, title: selectItem.title, open, onClose: () => setOpen(false) })
316
+ ] });
198
317
  };
199
318
  }
200
319
  });
@@ -205,59 +324,12 @@ var ChatRoleMap = {
205
324
  1: "user",
206
325
  2: "assistant"
207
326
  };
208
- var copy = (value) => {
209
- copyText(value).then(() => {
210
- message.success("\u590D\u5236\u6210\u529F");
211
- });
212
- };
213
- var classifyTime = (timestamp) => {
214
- const now = dayjs();
215
- const target = dayjs(timestamp);
216
- if (target.isSame(now, "day")) {
217
- return "\u4ECA\u5929";
218
- }
219
- const diffInDays = now.diff(target, "day");
220
- if (diffInDays < 7) {
221
- return "\u6700\u8FD1 7 \u5929";
222
- } else if (diffInDays < 30) {
223
- return "\u6700\u8FD1 30 \u5929";
224
- } else if (diffInDays < 180) {
225
- return "\u6700\u8FD1\u534A\u5E74";
226
- } else {
227
- return "\u66F4\u65E9";
228
- }
229
- };
230
- function transform(source, fieldMap) {
231
- const result = {};
232
- for (const [targetKey, mapping] of Object.entries(fieldMap)) {
233
- const key = targetKey;
234
- if (typeof mapping === "function") {
235
- result[key] = mapping(source);
236
- } else if (typeof mapping === "string" && source && mapping in source) {
237
- result[key] = source[mapping];
238
- } else {
239
- result[key] = mapping;
240
- }
241
- }
242
- return result;
243
- }
244
- function transforms(sources, fieldMap) {
245
- return sources?.map((source) => transform(source, fieldMap)) || [];
246
- }
247
- function buildURLWithParams(url, params) {
248
- const query = new URLSearchParams(
249
- Object.entries(params || {}).flatMap(([key, val]) => Array.isArray(val) ? val.map((v) => [key, String(v)]) : [[key, String(val)]])
250
- ).toString();
251
- return query ? `${url}${url.includes("?") ? "&" : "?"}${query}` : url;
252
- }
253
- var getBase64 = (file) => {
254
- return new Promise((resolve, reject) => {
255
- const reader = new FileReader();
256
- reader.onload = () => resolve(reader.result);
257
- reader.onerror = reject;
258
- reader.readAsDataURL(file);
259
- });
260
- };
327
+
328
+ // src/stores/index.ts
329
+ init_utils();
330
+
331
+ // src/core/fetchRequest.ts
332
+ init_utils();
261
333
  function processChunk(chunk, onChunk) {
262
334
  if (onChunk) {
263
335
  onChunk(typeof chunk === "string" ? chunk : JSON.stringify(chunk));
@@ -364,7 +436,7 @@ var put = (url, data = {}, options = {}) => request(url, data, { ...options, met
364
436
  var del = (url, data = {}, options = {}) => request(url, data, { ...options, method: "DELETE" });
365
437
  var fetchRequest_default = { delete: del, get, post, put };
366
438
 
367
- // src/services/index.tsx
439
+ // src/services/index.ts
368
440
  var agentInfoQuery = (agentId) => {
369
441
  return request$1.get("/agent/detail", { agentId });
370
442
  };
@@ -389,7 +461,7 @@ var updateFeedback = (params) => {
389
461
  var uploadFile = (formData) => {
390
462
  return request$1.post("/agent/file", formData);
391
463
  };
392
- var sendMessage = (params) => {
464
+ var sendChatMessage = (params) => {
393
465
  return fetchRequest_default.post(
394
466
  "/agent/chat",
395
467
  { ...params, stream: true },
@@ -430,12 +502,15 @@ function createChatStore() {
430
502
  preview: {
431
503
  file: {},
432
504
  isEdit: false
505
+ // 未使用
506
+ // isShow: 0, // 0 不显示 1 显示 2 用户关闭
507
+ // isIntact: false // true 完整 false 不完整
433
508
  },
434
509
  userInfo: {},
435
510
  params: {}
436
511
  });
437
512
  const setPreview = (file = {}, isEdit = false) => {
438
- if (config.layout.preview) {
513
+ if (shouldRender(config.layout.preview)) {
439
514
  config.preview = {
440
515
  file,
441
516
  isEdit
@@ -443,6 +518,8 @@ function createChatStore() {
443
518
  } else {
444
519
  if (file?.fileUrl) {
445
520
  window.open(file.fileUrl, "_blank");
521
+ } else {
522
+ console.log("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u9884\u89C8");
446
523
  }
447
524
  }
448
525
  };
@@ -544,8 +621,15 @@ function createChatStore() {
544
621
  };
545
622
  const agent = proxy({
546
623
  active: {},
547
- loading: false
624
+ loading: false,
625
+ params: {}
548
626
  });
627
+ const setAgentParams = (params = {}) => {
628
+ agent.params = {
629
+ thinkMode: 2,
630
+ ...params
631
+ };
632
+ };
549
633
  const switchAgent = async ({ appKey, agentKey, isVerify = false }, conversationId) => {
550
634
  const agentId = `${appKey}:${agentKey}`;
551
635
  if (agent.active.id === agentId) return;
@@ -557,6 +641,7 @@ function createChatStore() {
557
641
  }
558
642
  const { data } = await agentInfoQuery(agentId);
559
643
  agent.active = data;
644
+ setAgentParams();
560
645
  config.hooks?.onAfterSwitchAgent?.(agentId);
561
646
  switchConversation({ key: conversationId });
562
647
  } finally {
@@ -689,16 +774,16 @@ function createChatStore() {
689
774
  }
690
775
  conversation.messages[chunk.conversationId].loading = false;
691
776
  };
692
- const onSendMessage = async (message4, files = []) => {
777
+ const sendMessage = async (message4, files = [], params) => {
693
778
  const conversationId = conversation.active.key;
694
779
  if (conversation.messages[conversationId].loading) return;
695
780
  let newMsgContent = "", newImgList;
781
+ const references = conversation.messages[conversationId].references;
696
782
  if (message4) {
697
783
  newMsgContent = message4;
698
784
  newImgList = files;
699
785
  } else {
700
- const references = conversation.messages[conversationId].references;
701
- if (references?.type === 1 && references.content.markdown) {
786
+ if (references?.type === 1 && references?.content?.markdown) {
702
787
  newMsgContent = references.content.markdown + "\n";
703
788
  }
704
789
  newMsgContent = newMsgContent + conversation.messages[conversationId].content;
@@ -723,6 +808,13 @@ function createChatStore() {
723
808
  status: "loading"
724
809
  };
725
810
  conversation.messages[conversationId].message.items.push(userMsg, placeholder);
811
+ const extraParams = {
812
+ ...config.params
813
+ };
814
+ if (!extraParams.params) {
815
+ extraParams.params = {};
816
+ }
817
+ Object.assign(extraParams.params, agent.params, message4 ? {} : references?.params, params);
726
818
  if (!message4) {
727
819
  setContent("");
728
820
  setFileList([]);
@@ -731,12 +823,12 @@ function createChatStore() {
731
823
  }
732
824
  removeQuestionList(conversationId);
733
825
  try {
734
- sendMessage({
826
+ sendChatMessage({
735
827
  agentId: agent.active.id,
736
828
  conversationId: conversationId.endsWith(DEFAULT_NEW_CONV_ID) ? void 0 : conversationId,
737
829
  message: userMsg.content,
738
830
  files: userMsg.files,
739
- ...config.params,
831
+ ...extraParams,
740
832
  onMessageEvent: (event) => {
741
833
  updatePlaceholderMessage(conversationId, placeholderId, event);
742
834
  }
@@ -747,7 +839,7 @@ function createChatStore() {
747
839
  conversation.messages[conversationId].loading = false;
748
840
  }
749
841
  };
750
- const onCancelReceive = () => {
842
+ const cancelReceive = () => {
751
843
  conversation.messages[conversation.active.key].loading = false;
752
844
  };
753
845
  return {
@@ -770,17 +862,19 @@ function createChatStore() {
770
862
  conversations,
771
863
  setInitMessage,
772
864
  agent,
865
+ setAgentParams,
773
866
  switchAgent,
774
867
  getConversations,
775
868
  getMessages,
776
869
  switchConversation,
777
870
  delConversation,
778
871
  removePlaceholder,
779
- updatePlaceholderMessage,
780
- onSendMessage,
781
- onCancelReceive
872
+ sendMessage,
873
+ cancelReceive
782
874
  };
783
875
  }
876
+
877
+ // src/ui/layouts/index.tsx
784
878
  init_Context();
785
879
 
786
880
  // src/ui/common/AgentHeader.tsx
@@ -796,6 +890,7 @@ var styles_module_default = {
796
890
  nsBody: "styles_module_nsBody",
797
891
  nsBodyWidth: "styles_module_nsBodyWidth",
798
892
  nsBubbleList: "styles_module_nsBubbleList",
893
+ nsAgentHeader: "styles_module_nsAgentHeader",
799
894
  nsChatTitle: "styles_module_nsChatTitle",
800
895
  nsChatHeaderPopover: "styles_module_nsChatHeaderPopover",
801
896
  chatWelcomeWrap: "styles_module_chatWelcomeWrap",
@@ -806,7 +901,8 @@ var styles_module_default = {
806
901
  senderListItem: "styles_module_senderListItem",
807
902
  senderListFooter: "styles_module_senderListFooter",
808
903
  nsChatUserName: "styles_module_nsChatUserName",
809
- nsSenderHeaderContent: "styles_module_nsSenderHeaderContent"
904
+ nsSenderReferenceHeaderTitle: "styles_module_nsSenderReferenceHeaderTitle",
905
+ nsSenderReferenceHeaderContent: "styles_module_nsSenderReferenceHeaderContent"
810
906
  };
811
907
  var ConversationList_default = () => {
812
908
  const chatStore = useChatStore();
@@ -818,7 +914,7 @@ var ConversationList_default = () => {
818
914
  chatStore.getConversations(agentState.active.id);
819
915
  }
820
916
  }, [agentState.active.id]);
821
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", { className: "height-full scroll-fade-in", id: "scrollableDiv", children: /* @__PURE__ */ jsx(
917
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", { className: "height-full scroll-fade-in", id: "scrollableDiv", children: conversationsState.list.items.length ? /* @__PURE__ */ jsx(
822
918
  InfiniteScroll,
823
919
  {
824
920
  dataLength: conversationsState.list.items.length,
@@ -855,14 +951,14 @@ var ConversationList_default = () => {
855
951
  }
856
952
  )
857
953
  }
858
- ) }) });
954
+ ) : /* @__PURE__ */ jsx(Empty, { description: "\u6682\u65E0\u4F1A\u8BDD\u8BB0\u5F55", image: Empty.PRESENTED_IMAGE_SIMPLE }) }) });
859
955
  };
860
956
  var AgentHeader_default = () => {
861
957
  const chatStore = useChatStore();
862
958
  const agentState = useSnapshot(chatStore.agent);
863
959
  const configState = useSnapshot(chatStore.config);
864
- const conversationsState = useSnapshot(chatStore.conversations);
865
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", className: "p-l-16 p-r-16 p-t-8 p-b-8", children: [
960
+ useSnapshot(chatStore.conversations);
961
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", className: styles_module_default.nsAgentHeader, children: [
866
962
  /* @__PURE__ */ jsxs(Flex, { gap: 4, align: "center", children: [
867
963
  /* @__PURE__ */ jsx(
868
964
  RenderWrapper,
@@ -888,7 +984,7 @@ var AgentHeader_default = () => {
888
984
  RenderWrapper,
889
985
  {
890
986
  control: configState.layout.headerConversationListBtn,
891
- DefaultComponent: conversationsState.list.items.length > 0 && /* @__PURE__ */ jsx(
987
+ DefaultComponent: /* @__PURE__ */ jsx(
892
988
  Popover,
893
989
  {
894
990
  getPopupContainer: (e) => e,
@@ -905,7 +1001,7 @@ var AgentHeader_default = () => {
905
1001
  RenderWrapper,
906
1002
  {
907
1003
  control: configState.layout.headerCloseBtn,
908
- DefaultComponent: /* @__PURE__ */ jsx(Button, { type: "text", size: "large", onClick: configState.hooks?.onClose, icon: /* @__PURE__ */ jsx(CloseOutlined, {}) })
1004
+ DefaultComponent: /* @__PURE__ */ jsx(Button, { type: "text", size: "large", onClick: configState.hooks?.onHeaderClose, icon: /* @__PURE__ */ jsx(CloseOutlined, {}) })
909
1005
  }
910
1006
  )
911
1007
  ] })
@@ -917,7 +1013,7 @@ var customComponents = {
917
1013
  appCard: () => Promise.resolve().then(() => (init_AppCard(), AppCard_exports)),
918
1014
  fileView: () => Promise.resolve().then(() => (init_FileView(), FileView_exports)),
919
1015
  indexQuote: () => Promise.resolve().then(() => (init_IndexQuote(), IndexQuote_exports)),
920
- editableMarkdownCard: () => Promise.resolve().then(() => (init_EditableMarkdownCard(), EditableMarkdownCard_exports)),
1016
+ mdEdit: () => Promise.resolve().then(() => (init_MdEdit(), MdEdit_exports)),
921
1017
  fileEdit: () => Promise.resolve().then(() => (init_FileEdit(), FileEdit_exports)),
922
1018
  quoteList: () => Promise.resolve().then(() => (init_QuoteList(), QuoteList_exports))
923
1019
  };
@@ -948,6 +1044,7 @@ var MessageRender_default = ({ message: message4, placement }) => {
948
1044
  };
949
1045
 
950
1046
  // src/ui/common/BubbleListItems.tsx
1047
+ init_utils();
951
1048
  init_Context();
952
1049
  function extractThinkContent(content) {
953
1050
  let main = content;
@@ -1169,6 +1266,9 @@ var BubbleListItems_default = ({ avatar = true }) => {
1169
1266
  conversationState.active.key
1170
1267
  );
1171
1268
  };
1269
+
1270
+ // src/components/Attachments.tsx
1271
+ init_utils();
1172
1272
  var Attachments_default = forwardRef(({ maxCount, accept, fileSize, fileSizeTip, fileList = [], onChange, extraParams }, ref) => {
1173
1273
  const fileListRef = useRef([]);
1174
1274
  const [attachedFiles, setAttachedFiles, getAttachedFiles] = useRefState([]);
@@ -1343,6 +1443,7 @@ var ChatSender_default = forwardRef(
1343
1443
  onHeaderOpenChange,
1344
1444
  onSend,
1345
1445
  onCancel,
1446
+ onFocus,
1346
1447
  extraHeader,
1347
1448
  extraFooter,
1348
1449
  extraFooterBelow,
@@ -1389,6 +1490,7 @@ var ChatSender_default = forwardRef(
1389
1490
  header: senderHeader,
1390
1491
  onSubmit,
1391
1492
  onChange: setInputValue,
1493
+ onFocus,
1392
1494
  autoSize: { minRows: 2, maxRows: 6 },
1393
1495
  onCancel,
1394
1496
  footer: ({ components }) => {
@@ -1427,12 +1529,13 @@ var ChatSender_default2 = () => {
1427
1529
  if (chatMessage?.loading) return;
1428
1530
  chatStore.setContent(con);
1429
1531
  setTimeout(() => {
1430
- chatStore.onSendMessage();
1532
+ chatStore.sendMessage();
1431
1533
  }, 10);
1432
1534
  };
1433
1535
  return /* @__PURE__ */ jsx(
1434
1536
  ChatSender_default,
1435
1537
  {
1538
+ placeholder: configState.layout.sender?.props?.placeholder,
1436
1539
  content: chatMessage.content,
1437
1540
  fileList: chatMessage.files,
1438
1541
  headerOpen: chatMessage.headerOpen,
@@ -1440,26 +1543,37 @@ var ChatSender_default2 = () => {
1440
1543
  onContentChange: chatStore.setContent,
1441
1544
  onFileListChange: chatStore.setFileList,
1442
1545
  onHeaderOpenChange: chatStore.setHeaderOpen,
1443
- onSend: () => chatStore.onSendMessage(),
1546
+ onSend: () => chatStore.sendMessage(),
1547
+ onFocus: chatStore.config.hooks?.onSenderFocus,
1444
1548
  fileUpload: {
1445
1549
  ...agentState.active?.parameters?.fileUpload,
1446
1550
  extraParams: { agentId: agentState.active.id }
1447
1551
  },
1448
1552
  extraFooter: /* @__PURE__ */ jsxs(Fragment, { children: [
1449
- /* @__PURE__ */ jsx(Button, { size: "small", color: "primary", variant: "filled", children: "\u6DF1\u5EA6\u601D\u8003" }),
1553
+ /* @__PURE__ */ jsx(
1554
+ Button,
1555
+ {
1556
+ size: "small",
1557
+ color: agentState.params.thinkMode === 1 ? "primary" : "default",
1558
+ variant: "filled",
1559
+ onClick: () => chatStore.setAgentParams({ thinkMode: agentState.params.thinkMode === 1 ? 2 : 1 }),
1560
+ children: "\u6DF1\u5EA6\u601D\u8003"
1561
+ }
1562
+ ),
1450
1563
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.senderExtraBtn })
1451
1564
  ] }),
1452
1565
  extraHeader: /* @__PURE__ */ jsx(
1453
1566
  Sender.Header,
1454
1567
  {
1455
- title: /* @__PURE__ */ jsxs(Space, { children: [
1568
+ title: /* @__PURE__ */ jsxs(Flex, { gap: 4, children: [
1456
1569
  /* @__PURE__ */ jsx(EnterOutlined, {}),
1457
- /* @__PURE__ */ jsx(Typography.Text, { type: "secondary", children: chatMessage?.references?.content?.name })
1570
+ /* @__PURE__ */ jsx(Typography.Text, { type: "secondary", ellipsis: true, children: chatMessage?.references?.content?.name })
1458
1571
  ] }),
1459
1572
  open: !!chatMessage?.references?.content?.name,
1460
1573
  onOpenChange: () => chatStore.setReferences(),
1461
1574
  classNames: {
1462
- content: shouldRender(configState.layout.referencesBtn) ? "" : styles_module_default.nsSenderHeaderContent
1575
+ header: styles_module_default.nsSenderReferenceHeaderTitle,
1576
+ content: shouldRender(configState.layout.referencesBtn) ? "" : styles_module_default.nsSenderReferenceHeaderContent
1463
1577
  },
1464
1578
  children: /* @__PURE__ */ jsx(
1465
1579
  RenderWrapper,
@@ -1520,7 +1634,7 @@ var SenderPromptsItems_default = () => {
1520
1634
  split: false,
1521
1635
  className: styles_module_default.senderList,
1522
1636
  dataSource: question.hotQuestionList,
1523
- renderItem: (item) => /* @__PURE__ */ jsx(List.Item, { onClick: () => chatStore.onSendMessage(item.question), className: styles_module_default.senderListItem, children: item.question }),
1637
+ renderItem: (item) => /* @__PURE__ */ jsx(List.Item, { onClick: () => chatStore.sendMessage(item.question), className: styles_module_default.senderListItem, children: item.question }),
1524
1638
  footer: /* @__PURE__ */ jsx(Flex, { justify: "end", className: styles_module_default.senderListFooter, children: "(\u60A8\u53EF\u70B9\u51FB\u4EE5\u4E0A\u95EE\u9898\u5F00\u542FAI\u4F53\u9A8C)" })
1525
1639
  }
1526
1640
  ),
@@ -1569,7 +1683,7 @@ var layouts_default = forwardRef(({ theme, params, hooks, layout, defaultAgent }
1569
1683
  useImperativeHandle(
1570
1684
  ref,
1571
1685
  () => ({
1572
- sendMessage: chatStore.onSendMessage,
1686
+ sendMessage: chatStore.sendMessage,
1573
1687
  switchAgent: chatStore.switchAgent,
1574
1688
  switchConversation: chatStore.switchConversation,
1575
1689
  setReferences: chatStore.setReferences,
@@ -1583,6 +1697,9 @@ var layouts_default = forwardRef(({ theme, params, hooks, layout, defaultAgent }
1583
1697
  const setSplitterSizes = (sizes) => {
1584
1698
  console.log(sizes);
1585
1699
  };
1700
+ const hasPreView = useMemo(() => {
1701
+ return shouldRender(configState.layout.preview) && (!!configState.preview.file.fileUrl || !!configState.preview.file.content);
1702
+ }, [configState.layout.preview, configState.preview.file]);
1586
1703
  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__ */ jsx("div", { className: "overflow-hidden height-full", children: /* @__PURE__ */ jsxs(Splitter, { onResize: setSplitterSizes, children: [
1587
1704
  shouldRender(configState.layout.conversationList) && /* @__PURE__ */ jsx(Splitter.Panel, { size: 360, collapsible: false, resizable: false, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: "height-full", children: [
1588
1705
  /* @__PURE__ */ jsx(
@@ -1600,33 +1717,54 @@ var layouts_default = forwardRef(({ theme, params, hooks, layout, defaultAgent }
1600
1717
  }
1601
1718
  ) })
1602
1719
  ] }) }),
1603
- configState.preview.file.fileUrl && shouldRender(configState.layout.preview) && /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, resizable: false, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: "height-full", children: [
1604
- /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default3.nsPreviewHeader, children: [
1605
- /* @__PURE__ */ jsx("div", { className: styles_module_default3.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1606
- /* @__PURE__ */ jsxs(Flex, { gap: 8, justify: "center", align: "center", children: [
1607
- /* @__PURE__ */ jsx(
1608
- Button,
1609
- {
1610
- color: "primary",
1611
- variant: "outlined",
1612
- onClick: () => downloadFile(configState.preview.file.fileUrl, configState.preview.file.fileName),
1613
- children: "\u4E0B\u8F7D"
1720
+ hasPreView && /* @__PURE__ */ jsxs(Splitter.Panel, { collapsible: false, resizable: false, children: [
1721
+ configState.preview.file.fileUrl && /* @__PURE__ */ jsxs(Flex, { vertical: true, className: "height-full", children: [
1722
+ /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default3.nsPreviewHeader, children: [
1723
+ /* @__PURE__ */ jsx("div", { className: styles_module_default3.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1724
+ /* @__PURE__ */ jsxs(Flex, { gap: 8, justify: "center", align: "center", children: [
1725
+ /* @__PURE__ */ jsx(
1726
+ Button,
1727
+ {
1728
+ color: "primary",
1729
+ variant: "outlined",
1730
+ onClick: () => downloadFile(configState.preview.file.fileUrl, configState.preview.file.fileName),
1731
+ children: "\u4E0B\u8F7D"
1732
+ }
1733
+ ),
1734
+ /* @__PURE__ */ jsx(Button, { onClick: () => chatStore.setPreview(), children: "\u5173\u95ED" })
1735
+ ] })
1736
+ ] }),
1737
+ /* @__PURE__ */ jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsx(
1738
+ FilePreview,
1739
+ {
1740
+ ...configState.preview.file,
1741
+ pdfParams: {
1742
+ isHasThumbnails: false
1614
1743
  }
1615
- ),
1616
- /* @__PURE__ */ jsx(Button, { onClick: () => chatStore.setPreview(), children: "\u5173\u95ED" })
1617
- ] })
1744
+ }
1745
+ ) })
1618
1746
  ] }),
1619
- /* @__PURE__ */ jsx("div", { className: "full-scroll", children: configState.preview.file.fileUrl && /* @__PURE__ */ jsx(
1620
- FilePreview,
1747
+ configState.preview.file.content && /* @__PURE__ */ jsx(
1748
+ MarkdownEditor,
1621
1749
  {
1622
- ...configState.preview.file,
1623
- pdfParams: {
1624
- isHasThumbnails: false
1625
- }
1750
+ value: configState.preview.file.content,
1751
+ onQuote: (text) => {
1752
+ chatStore.setReferences({
1753
+ type: 2,
1754
+ content: {
1755
+ name: text,
1756
+ markdown: text
1757
+ },
1758
+ params: {
1759
+ outline: text
1760
+ }
1761
+ });
1762
+ },
1763
+ extraNav: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tag, { bordered: false, color: "default", className: "cursor-pointer", onClick: () => chatStore.setPreview(), children: /* @__PURE__ */ jsx(CloseOutlined, {}) }) })
1626
1764
  }
1627
- ) })
1628
- ] }) }),
1629
- /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, resizable: false, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames2("height-full"), children: [
1765
+ )
1766
+ ] }),
1767
+ /* @__PURE__ */ jsx(Splitter.Panel, { collapsible: false, resizable: false, size: hasPreView ? 400 : void 0, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames2("height-full"), children: [
1630
1768
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.header, DefaultComponent: AgentHeader_default }),
1631
1769
  /* @__PURE__ */ jsx(Flex, { vertical: true, className: classNames2("full-scroll", styles_module_default.nsBody), children: /* @__PURE__ */ jsxs(Flex, { justify: "center", vertical: true, gap: 24, className: classNames2("height-full", styles_module_default.nsBodyWidth), children: [
1632
1770
  shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsx(