@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.cjs.js CHANGED
@@ -2,19 +2,17 @@
2
2
 
3
3
  var common = require('@zero-library/common');
4
4
  var antd = require('antd');
5
+ var dayjs = require('dayjs');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
- var TextArea = require('antd/es/input/TextArea');
7
7
  var react = require('react');
8
8
  var icons = require('@ant-design/icons');
9
- var valtio = require('valtio');
10
- var dayjs = require('dayjs');
11
9
  var x = require('@ant-design/x');
12
10
  var classNames2 = require('classnames');
11
+ var valtio = require('valtio');
13
12
  var InfiniteScroll = require('react-infinite-scroll-component');
14
13
 
15
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
15
 
17
- var TextArea__default = /*#__PURE__*/_interopDefault(TextArea);
18
16
  var dayjs__default = /*#__PURE__*/_interopDefault(dayjs);
19
17
  var classNames2__default = /*#__PURE__*/_interopDefault(classNames2);
20
18
  var InfiniteScroll__default = /*#__PURE__*/_interopDefault(InfiniteScroll);
@@ -28,6 +26,64 @@ var __export = (target, all) => {
28
26
  for (var name in all)
29
27
  __defProp(target, name, { get: all[name], enumerable: true });
30
28
  };
29
+ function transform(source, fieldMap) {
30
+ const result = {};
31
+ for (const [targetKey, mapping] of Object.entries(fieldMap)) {
32
+ const key = targetKey;
33
+ if (typeof mapping === "function") {
34
+ result[key] = mapping(source);
35
+ } else if (typeof mapping === "string" && source && mapping in source) {
36
+ result[key] = source[mapping];
37
+ } else {
38
+ result[key] = mapping;
39
+ }
40
+ }
41
+ return result;
42
+ }
43
+ function transforms(sources, fieldMap) {
44
+ return sources?.map((source) => transform(source, fieldMap)) || [];
45
+ }
46
+ function buildURLWithParams(url, params) {
47
+ const query = new URLSearchParams(
48
+ Object.entries(params || {}).flatMap(([key, val]) => Array.isArray(val) ? val.map((v) => [key, String(v)]) : [[key, String(val)]])
49
+ ).toString();
50
+ return query ? `${url}${url.includes("?") ? "&" : "?"}${query}` : url;
51
+ }
52
+ var copy, classifyTime, getBase64;
53
+ var init_utils = __esm({
54
+ "src/core/utils.ts"() {
55
+ copy = (value) => {
56
+ common.copyText(value).then(() => {
57
+ antd.message.success("\u590D\u5236\u6210\u529F");
58
+ });
59
+ };
60
+ classifyTime = (timestamp) => {
61
+ const now = dayjs__default.default();
62
+ const target = dayjs__default.default(timestamp);
63
+ if (target.isSame(now, "day")) {
64
+ return "\u4ECA\u5929";
65
+ }
66
+ const diffInDays = now.diff(target, "day");
67
+ if (diffInDays < 7) {
68
+ return "\u6700\u8FD1 7 \u5929";
69
+ } else if (diffInDays < 30) {
70
+ return "\u6700\u8FD1 30 \u5929";
71
+ } else if (diffInDays < 180) {
72
+ return "\u6700\u8FD1\u534A\u5E74";
73
+ } else {
74
+ return "\u66F4\u65E9";
75
+ }
76
+ };
77
+ getBase64 = (file) => {
78
+ return new Promise((resolve, reject) => {
79
+ const reader = new FileReader();
80
+ reader.onload = () => resolve(reader.result);
81
+ reader.onerror = reject;
82
+ reader.readAsDataURL(file);
83
+ });
84
+ };
85
+ }
86
+ });
31
87
  var ChatProvider, useChatStore;
32
88
  var init_Context = __esm({
33
89
  "src/stores/Context.ts"() {
@@ -42,7 +98,11 @@ var init_styles_module = __esm({
42
98
  styles_module_default2 = {
43
99
  appCard: "styles_module_appCard",
44
100
  fileView: "styles_module_fileView",
45
- quoteList: "styles_module_quoteList"
101
+ fileEdit: "styles_module_fileEdit",
102
+ fileEditHeader: "styles_module_fileEditHeader",
103
+ fileEditContent: "styles_module_fileEditContent",
104
+ quoteList: "styles_module_quoteList",
105
+ mdEdit: "styles_module_mdEdit"
46
106
  };
47
107
  }
48
108
  });
@@ -92,6 +152,37 @@ var init_FileView = __esm({
92
152
  };
93
153
  }
94
154
  });
155
+ var docQuery;
156
+ var init_file = __esm({
157
+ "src/services/file.ts"() {
158
+ docQuery = (paramsStr) => {
159
+ return common.request.get(`/uc/doc?${paramsStr}`);
160
+ };
161
+ }
162
+ });
163
+ var DocDrawer_default;
164
+ var init_DocDrawer = __esm({
165
+ "src/ui/common/markdownAlert/components/DocDrawer.tsx"() {
166
+ init_file();
167
+ DocDrawer_default = ({ title, open, onClose, fileUrl }) => {
168
+ const [content, setContent] = react.useState("");
169
+ const [loading, setLoading] = react.useState(false);
170
+ const getContent = async () => {
171
+ try {
172
+ setLoading(true);
173
+ const res = await docQuery(fileUrl);
174
+ setContent(res.data?.content);
175
+ } finally {
176
+ setLoading(false);
177
+ }
178
+ };
179
+ react.useEffect(() => {
180
+ getContent();
181
+ }, [fileUrl]);
182
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Drawer, { title, push: false, width: "100%", open, onClose, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, children: content ? /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content }) : /* @__PURE__ */ jsxRuntime.jsx(antd.Empty, { className: "m-t-32" }) }) });
183
+ };
184
+ }
185
+ });
95
186
 
96
187
  // src/ui/common/markdownAlert/IndexQuote.tsx
97
188
  var IndexQuote_exports = {};
@@ -101,52 +192,58 @@ __export(IndexQuote_exports, {
101
192
  var IndexQuote_default;
102
193
  var init_IndexQuote = __esm({
103
194
  "src/ui/common/markdownAlert/IndexQuote.tsx"() {
195
+ init_DocDrawer();
104
196
  IndexQuote_default = ({ data, loading }) => {
197
+ const [open, setOpen] = react.useState(false);
105
198
  const onClick = () => {
106
- window.open(data.fileUrl, "_blank");
199
+ if (!data.fileUrl) return;
200
+ if (common.isExternal(data.fileUrl)) {
201
+ window.open(data.fileUrl, "_blank");
202
+ } else {
203
+ setOpen(true);
204
+ }
107
205
  };
108
- const Content = /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { align: "center", gap: 8, children: [
109
- /* @__PURE__ */ jsxRuntime.jsx(common.FileIcon, { suffix: data.suffix, fontSize: 16 }),
110
- /* @__PURE__ */ jsxRuntime.jsx("a", { onClick, children: data.fileName })
111
- ] }) });
112
- return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", wrapperClassName: "inline-block index-quote", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Popover, { content: Content, title: data.title, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Tag, { bordered: false, color: "processing", className: "cursor-pointer", children: data.index }) }) });
206
+ const Content = /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { align: "center", gap: 8, children: /* @__PURE__ */ jsxRuntime.jsx("a", { onClick, children: data.fileName }) }) });
207
+ const rootRef = react.useRef(null);
208
+ react.useEffect(() => {
209
+ const el = rootRef.current;
210
+ if (!el) return;
211
+ const previous = el.previousElementSibling;
212
+ if (!previous) return;
213
+ previous.appendChild(el);
214
+ }, []);
215
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: "inline-block m-l-8", children: [
216
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Popover, { content: Content, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Tag, { bordered: false, color: "processing", className: "cursor-pointer", children: data.index }) }) }),
217
+ open && /* @__PURE__ */ jsxRuntime.jsx(DocDrawer_default, { fileUrl: data.fileUrl, title: data.fileName, open, onClose: () => setOpen(false) })
218
+ ] });
113
219
  };
114
220
  }
115
221
  });
116
222
 
117
- // src/ui/common/markdownAlert/EditableMarkdownCard.tsx
118
- var EditableMarkdownCard_exports = {};
119
- __export(EditableMarkdownCard_exports, {
120
- default: () => EditableMarkdownCard_default
223
+ // src/ui/common/markdownAlert/MdEdit.tsx
224
+ var MdEdit_exports = {};
225
+ __export(MdEdit_exports, {
226
+ default: () => MdEdit_default
121
227
  });
122
- var EditableMarkdownCard_default;
123
- var init_EditableMarkdownCard = __esm({
124
- "src/ui/common/markdownAlert/EditableMarkdownCard.tsx"() {
125
- EditableMarkdownCard_default = ({ data, loading }) => {
126
- const [editing, setEditing] = react.useState(false);
127
- const [value, setValue] = react.useState(data.content || "");
128
- const wrapperRef = react.useRef(null);
129
- react.useEffect(() => {
130
- const handleClickOutside = (e) => {
131
- if (editing && wrapperRef.current && !wrapperRef.current.contains(e.target)) {
132
- setEditing(false);
133
- }
134
- };
135
- document.addEventListener("mousedown", handleClickOutside);
136
- return () => document.removeEventListener("mousedown", handleClickOutside);
137
- }, [editing]);
228
+ var MdEdit_default;
229
+ var init_MdEdit = __esm({
230
+ "src/ui/common/markdownAlert/MdEdit.tsx"() {
231
+ init_Context();
232
+ init_styles_module();
233
+ MdEdit_default = ({ data, loading }) => {
234
+ const chatStore = useChatStore();
235
+ const [value, setValue] = react.useState("");
236
+ const onOk = () => {
237
+ console.log("value", value);
238
+ chatStore.sendMessage("\u5F00\u59CB\u5199\u4F5C", [], { outline: value });
239
+ };
138
240
  react.useEffect(() => {
139
- if (value !== data.content) ;
140
- }, [value]);
141
- return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Card, { ref: wrapperRef, children: editing ? /* @__PURE__ */ jsxRuntime.jsx(
142
- TextArea__default.default,
143
- {
144
- autoSize: { minRows: 4, maxRows: 16 },
145
- value,
146
- onChange: (e) => setValue(e.target.value),
147
- placeholder: "\u8BF7\u8F93\u5165 Markdown \u5185\u5BB9..."
148
- }
149
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: () => setEditing(true), style: { cursor: "pointer", minHeight: 24 }, children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: value }) }) }) });
241
+ setValue(data.content);
242
+ }, [data.content]);
243
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default2.mdEdit, children: [
244
+ /* @__PURE__ */ jsxRuntime.jsx(common.MarkdownEditor, { disabled: loading, value, onChange: setValue, showToolbar: false }),
245
+ !loading && /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "end", className: "m-t-16", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "primary", variant: "outlined", onClick: onOk, children: "\u786E\u8BA4\u63D0\u7EB2\u601D\u8DEF\uFF0C\u5F00\u59CB\u5199\u4F5C" }) })
246
+ ] }) });
150
247
  };
151
248
  }
152
249
  });
@@ -159,17 +256,27 @@ __export(FileEdit_exports, {
159
256
  var FileEdit_default;
160
257
  var init_FileEdit = __esm({
161
258
  "src/ui/common/markdownAlert/FileEdit.tsx"() {
259
+ init_utils();
162
260
  init_Context();
163
261
  init_styles_module();
164
262
  FileEdit_default = ({ data, loading }) => {
165
263
  const chatStore = useChatStore();
166
- const onClick = () => {
167
- chatStore.setPreview(data, false);
264
+ const onPreview = () => {
265
+ chatStore.setPreview(data, true);
168
266
  };
169
- return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", className: styles_module_default2.fileView, onClick, children: [
170
- /* @__PURE__ */ jsxRuntime.jsx(common.FileIcon, { suffix: data.suffix }),
171
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
172
- ] }) });
267
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: styles_module_default2.fileEdit, children: [
268
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", justify: "space-between", className: styles_module_default2.fileEditHeader, children: [
269
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", className: "flex-1", children: [
270
+ /* @__PURE__ */ jsxRuntime.jsx(common.FileIcon, { suffix: "md", fontSize: 18 }),
271
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
272
+ ] }),
273
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { children: [
274
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlayCircleOutlined, {}), onClick: onPreview, children: "\u9884\u89C8\u7F16\u8F91" }),
275
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CopyOutlined, {}), onClick: () => copy(data.content), children: "\u590D\u5236" })
276
+ ] }) })
277
+ ] }),
278
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { gap: 8, align: "center", className: styles_module_default2.fileEditContent, children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: data.content }) })
279
+ ] });
173
280
  };
174
281
  }
175
282
  });
@@ -182,28 +289,39 @@ __export(QuoteList_exports, {
182
289
  var QuoteList_default;
183
290
  var init_QuoteList = __esm({
184
291
  "src/ui/common/markdownAlert/QuoteList.tsx"() {
292
+ init_DocDrawer();
185
293
  init_styles_module();
186
294
  QuoteList_default = ({ data, loading }) => {
187
- console.log("QuoteList data", data, loading);
295
+ const [open, setOpen] = react.useState(false);
296
+ const [selectItem, setSelectItem] = react.useState({});
188
297
  const onClick = (item) => {
189
- window.open(item.fileUrl, "_blank");
190
- };
191
- return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(
192
- antd.Collapse,
193
- {
194
- className: styles_module_default2.quoteList,
195
- bordered: false,
196
- ghost: true,
197
- expandIcon: ({ isActive }) => /* @__PURE__ */ jsxRuntime.jsx(icons.CaretRightOutlined, { rotate: isActive ? 90 : 0 }),
198
- items: [
199
- {
200
- key: "1",
201
- label: "\u53C2\u8003\u8D44\u6599",
202
- children: /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, gap: 4, children: data.list.map((item) => /* @__PURE__ */ jsxRuntime.jsx("p", { onClick: () => onClick(item), className: "cursor-pointer", children: item.displayName }, item.fileUrl)) })
203
- }
204
- ]
298
+ if (!item.fileUrl) return;
299
+ if (common.isExternal(item.fileUrl)) {
300
+ window.open(item.fileUrl, "_blank");
301
+ } else {
302
+ setSelectItem(item);
303
+ setOpen(true);
205
304
  }
206
- ) });
305
+ };
306
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
307
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(
308
+ antd.Collapse,
309
+ {
310
+ className: styles_module_default2.quoteList,
311
+ bordered: false,
312
+ ghost: true,
313
+ expandIcon: ({ isActive }) => /* @__PURE__ */ jsxRuntime.jsx(icons.CaretRightOutlined, { rotate: isActive ? 90 : 0 }),
314
+ items: [
315
+ {
316
+ key: "1",
317
+ label: "\u53C2\u8003\u8D44\u6599",
318
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, gap: 4, children: data.list.map((item) => /* @__PURE__ */ jsxRuntime.jsx("p", { onClick: () => onClick(item), className: "cursor-pointer", children: item.title }, item.fileUrl)) })
319
+ }
320
+ ]
321
+ }
322
+ ) }),
323
+ open && /* @__PURE__ */ jsxRuntime.jsx(DocDrawer_default, { fileUrl: selectItem.fileUrl, title: selectItem.title, open, onClose: () => setOpen(false) })
324
+ ] });
207
325
  };
208
326
  }
209
327
  });
@@ -214,59 +332,12 @@ var ChatRoleMap = {
214
332
  1: "user",
215
333
  2: "assistant"
216
334
  };
217
- var copy = (value) => {
218
- common.copyText(value).then(() => {
219
- antd.message.success("\u590D\u5236\u6210\u529F");
220
- });
221
- };
222
- var classifyTime = (timestamp) => {
223
- const now = dayjs__default.default();
224
- const target = dayjs__default.default(timestamp);
225
- if (target.isSame(now, "day")) {
226
- return "\u4ECA\u5929";
227
- }
228
- const diffInDays = now.diff(target, "day");
229
- if (diffInDays < 7) {
230
- return "\u6700\u8FD1 7 \u5929";
231
- } else if (diffInDays < 30) {
232
- return "\u6700\u8FD1 30 \u5929";
233
- } else if (diffInDays < 180) {
234
- return "\u6700\u8FD1\u534A\u5E74";
235
- } else {
236
- return "\u66F4\u65E9";
237
- }
238
- };
239
- function transform(source, fieldMap) {
240
- const result = {};
241
- for (const [targetKey, mapping] of Object.entries(fieldMap)) {
242
- const key = targetKey;
243
- if (typeof mapping === "function") {
244
- result[key] = mapping(source);
245
- } else if (typeof mapping === "string" && source && mapping in source) {
246
- result[key] = source[mapping];
247
- } else {
248
- result[key] = mapping;
249
- }
250
- }
251
- return result;
252
- }
253
- function transforms(sources, fieldMap) {
254
- return sources?.map((source) => transform(source, fieldMap)) || [];
255
- }
256
- function buildURLWithParams(url, params) {
257
- const query = new URLSearchParams(
258
- Object.entries(params || {}).flatMap(([key, val]) => Array.isArray(val) ? val.map((v) => [key, String(v)]) : [[key, String(val)]])
259
- ).toString();
260
- return query ? `${url}${url.includes("?") ? "&" : "?"}${query}` : url;
261
- }
262
- var getBase64 = (file) => {
263
- return new Promise((resolve, reject) => {
264
- const reader = new FileReader();
265
- reader.onload = () => resolve(reader.result);
266
- reader.onerror = reject;
267
- reader.readAsDataURL(file);
268
- });
269
- };
335
+
336
+ // src/stores/index.ts
337
+ init_utils();
338
+
339
+ // src/core/fetchRequest.ts
340
+ init_utils();
270
341
  function processChunk(chunk, onChunk) {
271
342
  if (onChunk) {
272
343
  onChunk(typeof chunk === "string" ? chunk : JSON.stringify(chunk));
@@ -373,7 +444,7 @@ var put = (url, data = {}, options = {}) => request(url, data, { ...options, met
373
444
  var del = (url, data = {}, options = {}) => request(url, data, { ...options, method: "DELETE" });
374
445
  var fetchRequest_default = { delete: del, get, post, put };
375
446
 
376
- // src/services/index.tsx
447
+ // src/services/index.ts
377
448
  var agentInfoQuery = (agentId) => {
378
449
  return common.request.get("/agent/detail", { agentId });
379
450
  };
@@ -398,7 +469,7 @@ var updateFeedback = (params) => {
398
469
  var uploadFile = (formData) => {
399
470
  return common.request.post("/agent/file", formData);
400
471
  };
401
- var sendMessage = (params) => {
472
+ var sendChatMessage = (params) => {
402
473
  return fetchRequest_default.post(
403
474
  "/agent/chat",
404
475
  { ...params, stream: true },
@@ -439,12 +510,15 @@ function createChatStore() {
439
510
  preview: {
440
511
  file: {},
441
512
  isEdit: false
513
+ // 未使用
514
+ // isShow: 0, // 0 不显示 1 显示 2 用户关闭
515
+ // isIntact: false // true 完整 false 不完整
442
516
  },
443
517
  userInfo: {},
444
518
  params: {}
445
519
  });
446
520
  const setPreview = (file = {}, isEdit = false) => {
447
- if (config.layout.preview) {
521
+ if (common.shouldRender(config.layout.preview)) {
448
522
  config.preview = {
449
523
  file,
450
524
  isEdit
@@ -452,6 +526,8 @@ function createChatStore() {
452
526
  } else {
453
527
  if (file?.fileUrl) {
454
528
  window.open(file.fileUrl, "_blank");
529
+ } else {
530
+ console.log("\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301\u9884\u89C8");
455
531
  }
456
532
  }
457
533
  };
@@ -553,8 +629,15 @@ function createChatStore() {
553
629
  };
554
630
  const agent = valtio.proxy({
555
631
  active: {},
556
- loading: false
632
+ loading: false,
633
+ params: {}
557
634
  });
635
+ const setAgentParams = (params = {}) => {
636
+ agent.params = {
637
+ thinkMode: 2,
638
+ ...params
639
+ };
640
+ };
558
641
  const switchAgent = async ({ appKey, agentKey, isVerify = false }, conversationId) => {
559
642
  const agentId = `${appKey}:${agentKey}`;
560
643
  if (agent.active.id === agentId) return;
@@ -566,6 +649,7 @@ function createChatStore() {
566
649
  }
567
650
  const { data } = await agentInfoQuery(agentId);
568
651
  agent.active = data;
652
+ setAgentParams();
569
653
  config.hooks?.onAfterSwitchAgent?.(agentId);
570
654
  switchConversation({ key: conversationId });
571
655
  } finally {
@@ -698,16 +782,16 @@ function createChatStore() {
698
782
  }
699
783
  conversation.messages[chunk.conversationId].loading = false;
700
784
  };
701
- const onSendMessage = async (message4, files = []) => {
785
+ const sendMessage = async (message4, files = [], params) => {
702
786
  const conversationId = conversation.active.key;
703
787
  if (conversation.messages[conversationId].loading) return;
704
788
  let newMsgContent = "", newImgList;
789
+ const references = conversation.messages[conversationId].references;
705
790
  if (message4) {
706
791
  newMsgContent = message4;
707
792
  newImgList = files;
708
793
  } else {
709
- const references = conversation.messages[conversationId].references;
710
- if (references?.type === 1 && references.content.markdown) {
794
+ if (references?.type === 1 && references?.content?.markdown) {
711
795
  newMsgContent = references.content.markdown + "\n";
712
796
  }
713
797
  newMsgContent = newMsgContent + conversation.messages[conversationId].content;
@@ -732,6 +816,13 @@ function createChatStore() {
732
816
  status: "loading"
733
817
  };
734
818
  conversation.messages[conversationId].message.items.push(userMsg, placeholder);
819
+ const extraParams = {
820
+ ...config.params
821
+ };
822
+ if (!extraParams.params) {
823
+ extraParams.params = {};
824
+ }
825
+ Object.assign(extraParams.params, agent.params, message4 ? {} : references?.params, params);
735
826
  if (!message4) {
736
827
  setContent("");
737
828
  setFileList([]);
@@ -740,12 +831,12 @@ function createChatStore() {
740
831
  }
741
832
  removeQuestionList(conversationId);
742
833
  try {
743
- sendMessage({
834
+ sendChatMessage({
744
835
  agentId: agent.active.id,
745
836
  conversationId: conversationId.endsWith(DEFAULT_NEW_CONV_ID) ? void 0 : conversationId,
746
837
  message: userMsg.content,
747
838
  files: userMsg.files,
748
- ...config.params,
839
+ ...extraParams,
749
840
  onMessageEvent: (event) => {
750
841
  updatePlaceholderMessage(conversationId, placeholderId, event);
751
842
  }
@@ -756,7 +847,7 @@ function createChatStore() {
756
847
  conversation.messages[conversationId].loading = false;
757
848
  }
758
849
  };
759
- const onCancelReceive = () => {
850
+ const cancelReceive = () => {
760
851
  conversation.messages[conversation.active.key].loading = false;
761
852
  };
762
853
  return {
@@ -779,17 +870,19 @@ function createChatStore() {
779
870
  conversations,
780
871
  setInitMessage,
781
872
  agent,
873
+ setAgentParams,
782
874
  switchAgent,
783
875
  getConversations,
784
876
  getMessages,
785
877
  switchConversation,
786
878
  delConversation,
787
879
  removePlaceholder,
788
- updatePlaceholderMessage,
789
- onSendMessage,
790
- onCancelReceive
880
+ sendMessage,
881
+ cancelReceive
791
882
  };
792
883
  }
884
+
885
+ // src/ui/layouts/index.tsx
793
886
  init_Context();
794
887
 
795
888
  // src/ui/common/AgentHeader.tsx
@@ -805,6 +898,7 @@ var styles_module_default = {
805
898
  nsBody: "styles_module_nsBody",
806
899
  nsBodyWidth: "styles_module_nsBodyWidth",
807
900
  nsBubbleList: "styles_module_nsBubbleList",
901
+ nsAgentHeader: "styles_module_nsAgentHeader",
808
902
  nsChatTitle: "styles_module_nsChatTitle",
809
903
  nsChatHeaderPopover: "styles_module_nsChatHeaderPopover",
810
904
  chatWelcomeWrap: "styles_module_chatWelcomeWrap",
@@ -815,7 +909,8 @@ var styles_module_default = {
815
909
  senderListItem: "styles_module_senderListItem",
816
910
  senderListFooter: "styles_module_senderListFooter",
817
911
  nsChatUserName: "styles_module_nsChatUserName",
818
- nsSenderHeaderContent: "styles_module_nsSenderHeaderContent"
912
+ nsSenderReferenceHeaderTitle: "styles_module_nsSenderReferenceHeaderTitle",
913
+ nsSenderReferenceHeaderContent: "styles_module_nsSenderReferenceHeaderContent"
819
914
  };
820
915
  var ConversationList_default = () => {
821
916
  const chatStore = useChatStore();
@@ -827,7 +922,7 @@ var ConversationList_default = () => {
827
922
  chatStore.getConversations(agentState.active.id);
828
923
  }
829
924
  }, [agentState.active.id]);
830
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full scroll-fade-in", id: "scrollableDiv", children: /* @__PURE__ */ jsxRuntime.jsx(
925
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full scroll-fade-in", id: "scrollableDiv", children: conversationsState.list.items.length ? /* @__PURE__ */ jsxRuntime.jsx(
831
926
  InfiniteScroll__default.default,
832
927
  {
833
928
  dataLength: conversationsState.list.items.length,
@@ -864,14 +959,14 @@ var ConversationList_default = () => {
864
959
  }
865
960
  )
866
961
  }
867
- ) }) });
962
+ ) : /* @__PURE__ */ jsxRuntime.jsx(antd.Empty, { description: "\u6682\u65E0\u4F1A\u8BDD\u8BB0\u5F55", image: antd.Empty.PRESENTED_IMAGE_SIMPLE }) }) });
868
963
  };
869
964
  var AgentHeader_default = () => {
870
965
  const chatStore = useChatStore();
871
966
  const agentState = valtio.useSnapshot(chatStore.agent);
872
967
  const configState = valtio.useSnapshot(chatStore.config);
873
- const conversationsState = valtio.useSnapshot(chatStore.conversations);
874
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", className: "p-l-16 p-r-16 p-t-8 p-b-8", children: [
968
+ valtio.useSnapshot(chatStore.conversations);
969
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", className: styles_module_default.nsAgentHeader, children: [
875
970
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", children: [
876
971
  /* @__PURE__ */ jsxRuntime.jsx(
877
972
  common.RenderWrapper,
@@ -897,7 +992,7 @@ var AgentHeader_default = () => {
897
992
  common.RenderWrapper,
898
993
  {
899
994
  control: configState.layout.headerConversationListBtn,
900
- DefaultComponent: conversationsState.list.items.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
995
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(
901
996
  antd.Popover,
902
997
  {
903
998
  getPopupContainer: (e) => e,
@@ -914,7 +1009,7 @@ var AgentHeader_default = () => {
914
1009
  common.RenderWrapper,
915
1010
  {
916
1011
  control: configState.layout.headerCloseBtn,
917
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", onClick: configState.hooks?.onClose, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloseOutlined, {}) })
1012
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", onClick: configState.hooks?.onHeaderClose, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloseOutlined, {}) })
918
1013
  }
919
1014
  )
920
1015
  ] })
@@ -926,7 +1021,7 @@ var customComponents = {
926
1021
  appCard: () => Promise.resolve().then(() => (init_AppCard(), AppCard_exports)),
927
1022
  fileView: () => Promise.resolve().then(() => (init_FileView(), FileView_exports)),
928
1023
  indexQuote: () => Promise.resolve().then(() => (init_IndexQuote(), IndexQuote_exports)),
929
- editableMarkdownCard: () => Promise.resolve().then(() => (init_EditableMarkdownCard(), EditableMarkdownCard_exports)),
1024
+ mdEdit: () => Promise.resolve().then(() => (init_MdEdit(), MdEdit_exports)),
930
1025
  fileEdit: () => Promise.resolve().then(() => (init_FileEdit(), FileEdit_exports)),
931
1026
  quoteList: () => Promise.resolve().then(() => (init_QuoteList(), QuoteList_exports))
932
1027
  };
@@ -957,6 +1052,7 @@ var MessageRender_default = ({ message: message4, placement }) => {
957
1052
  };
958
1053
 
959
1054
  // src/ui/common/BubbleListItems.tsx
1055
+ init_utils();
960
1056
  init_Context();
961
1057
  function extractThinkContent(content) {
962
1058
  let main = content;
@@ -1178,6 +1274,9 @@ var BubbleListItems_default = ({ avatar = true }) => {
1178
1274
  conversationState.active.key
1179
1275
  );
1180
1276
  };
1277
+
1278
+ // src/components/Attachments.tsx
1279
+ init_utils();
1181
1280
  var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSizeTip, fileList = [], onChange, extraParams }, ref) => {
1182
1281
  const fileListRef = react.useRef([]);
1183
1282
  const [attachedFiles, setAttachedFiles, getAttachedFiles] = common.useRefState([]);
@@ -1352,6 +1451,7 @@ var ChatSender_default = react.forwardRef(
1352
1451
  onHeaderOpenChange,
1353
1452
  onSend,
1354
1453
  onCancel,
1454
+ onFocus,
1355
1455
  extraHeader,
1356
1456
  extraFooter,
1357
1457
  extraFooterBelow,
@@ -1398,6 +1498,7 @@ var ChatSender_default = react.forwardRef(
1398
1498
  header: senderHeader,
1399
1499
  onSubmit,
1400
1500
  onChange: setInputValue,
1501
+ onFocus,
1401
1502
  autoSize: { minRows: 2, maxRows: 6 },
1402
1503
  onCancel,
1403
1504
  footer: ({ components }) => {
@@ -1436,12 +1537,13 @@ var ChatSender_default2 = () => {
1436
1537
  if (chatMessage?.loading) return;
1437
1538
  chatStore.setContent(con);
1438
1539
  setTimeout(() => {
1439
- chatStore.onSendMessage();
1540
+ chatStore.sendMessage();
1440
1541
  }, 10);
1441
1542
  };
1442
1543
  return /* @__PURE__ */ jsxRuntime.jsx(
1443
1544
  ChatSender_default,
1444
1545
  {
1546
+ placeholder: configState.layout.sender?.props?.placeholder,
1445
1547
  content: chatMessage.content,
1446
1548
  fileList: chatMessage.files,
1447
1549
  headerOpen: chatMessage.headerOpen,
@@ -1449,26 +1551,37 @@ var ChatSender_default2 = () => {
1449
1551
  onContentChange: chatStore.setContent,
1450
1552
  onFileListChange: chatStore.setFileList,
1451
1553
  onHeaderOpenChange: chatStore.setHeaderOpen,
1452
- onSend: () => chatStore.onSendMessage(),
1554
+ onSend: () => chatStore.sendMessage(),
1555
+ onFocus: chatStore.config.hooks?.onSenderFocus,
1453
1556
  fileUpload: {
1454
1557
  ...agentState.active?.parameters?.fileUpload,
1455
1558
  extraParams: { agentId: agentState.active.id }
1456
1559
  },
1457
1560
  extraFooter: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1458
- /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { size: "small", color: "primary", variant: "filled", children: "\u6DF1\u5EA6\u601D\u8003" }),
1561
+ /* @__PURE__ */ jsxRuntime.jsx(
1562
+ antd.Button,
1563
+ {
1564
+ size: "small",
1565
+ color: agentState.params.thinkMode === 1 ? "primary" : "default",
1566
+ variant: "filled",
1567
+ onClick: () => chatStore.setAgentParams({ thinkMode: agentState.params.thinkMode === 1 ? 2 : 1 }),
1568
+ children: "\u6DF1\u5EA6\u601D\u8003"
1569
+ }
1570
+ ),
1459
1571
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.senderExtraBtn })
1460
1572
  ] }),
1461
1573
  extraHeader: /* @__PURE__ */ jsxRuntime.jsx(
1462
1574
  x.Sender.Header,
1463
1575
  {
1464
- title: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { children: [
1576
+ title: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, children: [
1465
1577
  /* @__PURE__ */ jsxRuntime.jsx(icons.EnterOutlined, {}),
1466
- /* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { type: "secondary", children: chatMessage?.references?.content?.name })
1578
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { type: "secondary", ellipsis: true, children: chatMessage?.references?.content?.name })
1467
1579
  ] }),
1468
1580
  open: !!chatMessage?.references?.content?.name,
1469
1581
  onOpenChange: () => chatStore.setReferences(),
1470
1582
  classNames: {
1471
- content: common.shouldRender(configState.layout.referencesBtn) ? "" : styles_module_default.nsSenderHeaderContent
1583
+ header: styles_module_default.nsSenderReferenceHeaderTitle,
1584
+ content: common.shouldRender(configState.layout.referencesBtn) ? "" : styles_module_default.nsSenderReferenceHeaderContent
1472
1585
  },
1473
1586
  children: /* @__PURE__ */ jsxRuntime.jsx(
1474
1587
  common.RenderWrapper,
@@ -1529,7 +1642,7 @@ var SenderPromptsItems_default = () => {
1529
1642
  split: false,
1530
1643
  className: styles_module_default.senderList,
1531
1644
  dataSource: question.hotQuestionList,
1532
- renderItem: (item) => /* @__PURE__ */ jsxRuntime.jsx(antd.List.Item, { onClick: () => chatStore.onSendMessage(item.question), className: styles_module_default.senderListItem, children: item.question }),
1645
+ renderItem: (item) => /* @__PURE__ */ jsxRuntime.jsx(antd.List.Item, { onClick: () => chatStore.sendMessage(item.question), className: styles_module_default.senderListItem, children: item.question }),
1533
1646
  footer: /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "end", className: styles_module_default.senderListFooter, children: "(\u60A8\u53EF\u70B9\u51FB\u4EE5\u4E0A\u95EE\u9898\u5F00\u542FAI\u4F53\u9A8C)" })
1534
1647
  }
1535
1648
  ),
@@ -1578,7 +1691,7 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1578
1691
  react.useImperativeHandle(
1579
1692
  ref,
1580
1693
  () => ({
1581
- sendMessage: chatStore.onSendMessage,
1694
+ sendMessage: chatStore.sendMessage,
1582
1695
  switchAgent: chatStore.switchAgent,
1583
1696
  switchConversation: chatStore.switchConversation,
1584
1697
  setReferences: chatStore.setReferences,
@@ -1592,6 +1705,9 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1592
1705
  const setSplitterSizes = (sizes) => {
1593
1706
  console.log(sizes);
1594
1707
  };
1708
+ const hasPreView = react.useMemo(() => {
1709
+ return common.shouldRender(configState.layout.preview) && (!!configState.preview.file.fileUrl || !!configState.preview.file.content);
1710
+ }, [configState.layout.preview, configState.preview.file]);
1595
1711
  return /* @__PURE__ */ jsxRuntime.jsx(x.XProvider, { theme: { cssVar: true, ...theme }, children: /* @__PURE__ */ jsxRuntime.jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: agentState.loading, wrapperClassName: "full-spin", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden height-full", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Splitter, { onResize: setSplitterSizes, children: [
1596
1712
  common.shouldRender(configState.layout.conversationList) && /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { size: 360, collapsible: false, resizable: false, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: "height-full", children: [
1597
1713
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1609,33 +1725,54 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1609
1725
  }
1610
1726
  ) })
1611
1727
  ] }) }),
1612
- configState.preview.file.fileUrl && common.shouldRender(configState.layout.preview) && /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, resizable: false, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: "height-full", children: [
1613
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default3.nsPreviewHeader, children: [
1614
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default3.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1615
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "center", align: "center", children: [
1616
- /* @__PURE__ */ jsxRuntime.jsx(
1617
- antd.Button,
1618
- {
1619
- color: "primary",
1620
- variant: "outlined",
1621
- onClick: () => common.downloadFile(configState.preview.file.fileUrl, configState.preview.file.fileName),
1622
- children: "\u4E0B\u8F7D"
1728
+ hasPreView && /* @__PURE__ */ jsxRuntime.jsxs(antd.Splitter.Panel, { collapsible: false, resizable: false, children: [
1729
+ configState.preview.file.fileUrl && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: "height-full", children: [
1730
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default3.nsPreviewHeader, children: [
1731
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default3.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1732
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "center", align: "center", children: [
1733
+ /* @__PURE__ */ jsxRuntime.jsx(
1734
+ antd.Button,
1735
+ {
1736
+ color: "primary",
1737
+ variant: "outlined",
1738
+ onClick: () => common.downloadFile(configState.preview.file.fileUrl, configState.preview.file.fileName),
1739
+ children: "\u4E0B\u8F7D"
1740
+ }
1741
+ ),
1742
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => chatStore.setPreview(), children: "\u5173\u95ED" })
1743
+ ] })
1744
+ ] }),
1745
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(
1746
+ common.FilePreview,
1747
+ {
1748
+ ...configState.preview.file,
1749
+ pdfParams: {
1750
+ isHasThumbnails: false
1623
1751
  }
1624
- ),
1625
- /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => chatStore.setPreview(), children: "\u5173\u95ED" })
1626
- ] })
1752
+ }
1753
+ ) })
1627
1754
  ] }),
1628
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: configState.preview.file.fileUrl && /* @__PURE__ */ jsxRuntime.jsx(
1629
- common.FilePreview,
1755
+ configState.preview.file.content && /* @__PURE__ */ jsxRuntime.jsx(
1756
+ common.MarkdownEditor,
1630
1757
  {
1631
- ...configState.preview.file,
1632
- pdfParams: {
1633
- isHasThumbnails: false
1634
- }
1758
+ value: configState.preview.file.content,
1759
+ onQuote: (text) => {
1760
+ chatStore.setReferences({
1761
+ type: 2,
1762
+ content: {
1763
+ name: text,
1764
+ markdown: text
1765
+ },
1766
+ params: {
1767
+ outline: text
1768
+ }
1769
+ });
1770
+ },
1771
+ extraNav: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Tag, { bordered: false, color: "default", className: "cursor-pointer", onClick: () => chatStore.setPreview(), children: /* @__PURE__ */ jsxRuntime.jsx(icons.CloseOutlined, {}) }) })
1635
1772
  }
1636
- ) })
1637
- ] }) }),
1638
- /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, resizable: false, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames2__default.default("height-full"), children: [
1773
+ )
1774
+ ] }),
1775
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, resizable: false, size: hasPreView ? 400 : void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames2__default.default("height-full"), children: [
1639
1776
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.header, DefaultComponent: AgentHeader_default }),
1640
1777
  /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, className: classNames2__default.default("full-scroll", styles_module_default.nsBody), children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "center", vertical: true, gap: 24, className: classNames2__default.default("height-full", styles_module_default.nsBodyWidth), children: [
1641
1778
  common.shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(