@zero-library/chat-agent 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1676 @@
1
+ 'use strict';
2
+
3
+ var common = require('@zero-library/common');
4
+ var antd = require('antd');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var TextArea = require('antd/es/input/TextArea');
7
+ var react = require('react');
8
+ var icons = require('@ant-design/icons');
9
+ var valtio = require('valtio');
10
+ var dayjs = require('dayjs');
11
+ var x = require('@ant-design/x');
12
+ var classNames2 = require('classnames');
13
+ var InfiniteScroll = require('react-infinite-scroll-component');
14
+
15
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
+
17
+ var TextArea__default = /*#__PURE__*/_interopDefault(TextArea);
18
+ var dayjs__default = /*#__PURE__*/_interopDefault(dayjs);
19
+ var classNames2__default = /*#__PURE__*/_interopDefault(classNames2);
20
+ var InfiniteScroll__default = /*#__PURE__*/_interopDefault(InfiniteScroll);
21
+
22
+ var __defProp = Object.defineProperty;
23
+ var __getOwnPropNames = Object.getOwnPropertyNames;
24
+ var __esm = (fn, res) => function __init() {
25
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
26
+ };
27
+ var __export = (target, all) => {
28
+ for (var name in all)
29
+ __defProp(target, name, { get: all[name], enumerable: true });
30
+ };
31
+ var ChatProvider, useChatStore;
32
+ var init_Context = __esm({
33
+ "src/stores/Context.ts"() {
34
+ ({ ValtioProvider: ChatProvider, useValtioStore: useChatStore } = common.createValtioContext());
35
+ }
36
+ });
37
+
38
+ // src/ui/common/markdownAlert/styles.module.less
39
+ var styles_module_default2;
40
+ var init_styles_module = __esm({
41
+ "src/ui/common/markdownAlert/styles.module.less"() {
42
+ styles_module_default2 = {
43
+ appCard: "styles_module_appCard",
44
+ fileView: "styles_module_fileView",
45
+ quoteList: "styles_module_quoteList"
46
+ };
47
+ }
48
+ });
49
+
50
+ // src/ui/common/markdownAlert/AppCard.tsx
51
+ var AppCard_exports = {};
52
+ __export(AppCard_exports, {
53
+ default: () => AppCard_default
54
+ });
55
+ var AppCard_default;
56
+ var init_AppCard = __esm({
57
+ "src/ui/common/markdownAlert/AppCard.tsx"() {
58
+ init_Context();
59
+ init_styles_module();
60
+ AppCard_default = ({ data, loading }) => {
61
+ const chatStore = useChatStore();
62
+ const onClick = () => {
63
+ chatStore.switchAgent({ appKey: data.appKey, agentKey: data.agentKey, isVerify: true });
64
+ };
65
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, gap: 4, align: "center", className: styles_module_default2.appCard, onClick, children: [
66
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: data.iconUrl }),
67
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.appName, children: data.appName })
68
+ ] }) });
69
+ };
70
+ }
71
+ });
72
+
73
+ // src/ui/common/markdownAlert/FileView.tsx
74
+ var FileView_exports = {};
75
+ __export(FileView_exports, {
76
+ default: () => FileView_default
77
+ });
78
+ var FileView_default;
79
+ var init_FileView = __esm({
80
+ "src/ui/common/markdownAlert/FileView.tsx"() {
81
+ init_Context();
82
+ init_styles_module();
83
+ FileView_default = ({ data, loading }) => {
84
+ const chatStore = useChatStore();
85
+ const onClick = () => {
86
+ chatStore.setPreview(data, false);
87
+ };
88
+ 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: [
89
+ /* @__PURE__ */ jsxRuntime.jsx(common.FileIcon, { suffix: data.suffix }),
90
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
91
+ ] }) });
92
+ };
93
+ }
94
+ });
95
+
96
+ // src/ui/common/markdownAlert/IndexQuote.tsx
97
+ var IndexQuote_exports = {};
98
+ __export(IndexQuote_exports, {
99
+ default: () => IndexQuote_default
100
+ });
101
+ var IndexQuote_default;
102
+ var init_IndexQuote = __esm({
103
+ "src/ui/common/markdownAlert/IndexQuote.tsx"() {
104
+ IndexQuote_default = ({ data, loading }) => {
105
+ const onClick = () => {
106
+ window.open(data.fileUrl, "_blank");
107
+ };
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 }) }) });
113
+ };
114
+ }
115
+ });
116
+
117
+ // src/ui/common/markdownAlert/EditableMarkdownCard.tsx
118
+ var EditableMarkdownCard_exports = {};
119
+ __export(EditableMarkdownCard_exports, {
120
+ default: () => EditableMarkdownCard_default
121
+ });
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]);
138
+ 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 }) }) }) });
150
+ };
151
+ }
152
+ });
153
+
154
+ // src/ui/common/markdownAlert/FileEdit.tsx
155
+ var FileEdit_exports = {};
156
+ __export(FileEdit_exports, {
157
+ default: () => FileEdit_default
158
+ });
159
+ var FileEdit_default;
160
+ var init_FileEdit = __esm({
161
+ "src/ui/common/markdownAlert/FileEdit.tsx"() {
162
+ init_Context();
163
+ init_styles_module();
164
+ FileEdit_default = ({ data, loading }) => {
165
+ const chatStore = useChatStore();
166
+ const onClick = () => {
167
+ chatStore.setPreview(data, false);
168
+ };
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
+ ] }) });
173
+ };
174
+ }
175
+ });
176
+
177
+ // src/ui/common/markdownAlert/QuoteList.tsx
178
+ var QuoteList_exports = {};
179
+ __export(QuoteList_exports, {
180
+ default: () => QuoteList_default
181
+ });
182
+ var QuoteList_default;
183
+ var init_QuoteList = __esm({
184
+ "src/ui/common/markdownAlert/QuoteList.tsx"() {
185
+ init_styles_module();
186
+ QuoteList_default = ({ data, loading }) => {
187
+ console.log("QuoteList data", data, loading);
188
+ 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
+ ]
205
+ }
206
+ ) });
207
+ };
208
+ }
209
+ });
210
+
211
+ // src/core/constants.ts
212
+ var DEFAULT_NEW_CONV_ID = "newConvId";
213
+ var ChatRoleMap = {
214
+ 1: "user",
215
+ 2: "assistant"
216
+ };
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
+ };
270
+ function processChunk(chunk, onChunk) {
271
+ if (onChunk) {
272
+ onChunk(typeof chunk === "string" ? chunk : JSON.stringify(chunk));
273
+ }
274
+ }
275
+ function parseBuffer(buffer, onChunk) {
276
+ let bufferF = buffer;
277
+ let jsonStartIndex = bufferF.indexOf("{");
278
+ let jsonEndIndex = -1;
279
+ while (jsonStartIndex !== -1) {
280
+ let braceCount = 0;
281
+ let inString = false;
282
+ for (let i = jsonStartIndex; i < bufferF.length; i++) {
283
+ const char = bufferF[i];
284
+ if (char === '"' && bufferF[i - 1] !== "\\") {
285
+ inString = !inString;
286
+ }
287
+ if (!inString) {
288
+ if (char === "{") braceCount++;
289
+ if (char === "}") braceCount--;
290
+ }
291
+ if (braceCount === 0) {
292
+ jsonEndIndex = i;
293
+ break;
294
+ }
295
+ }
296
+ if (jsonEndIndex !== -1) {
297
+ const jsonString = bufferF.slice(jsonStartIndex, jsonEndIndex + 1);
298
+ try {
299
+ const parsed = JSON.parse(jsonString);
300
+ processChunk(parsed, onChunk);
301
+ } catch (e) {
302
+ console.warn("Failed to parse JSON chunk:", jsonString);
303
+ }
304
+ bufferF = bufferF.slice(jsonEndIndex + 1).trim();
305
+ jsonStartIndex = bufferF.indexOf("{");
306
+ jsonEndIndex = -1;
307
+ } else {
308
+ break;
309
+ }
310
+ }
311
+ return bufferF;
312
+ }
313
+ async function handleHttpError(status, message4) {
314
+ const error = new Error(`${status}: ${message4}`);
315
+ console.error("request error:", error);
316
+ await antd.message.error("\u670D\u52A1\u5668\u5F00\u5C0F\u5DEE\u5566~\u{1F616}");
317
+ }
318
+ async function handleStreamResponse(response, options) {
319
+ const { onChunk } = options;
320
+ const reader = response.body.getReader();
321
+ const decoder = new TextDecoder();
322
+ let buffer = "";
323
+ while (true) {
324
+ const { done, value } = await reader.read();
325
+ if (done) {
326
+ buffer = parseBuffer(buffer, onChunk);
327
+ break;
328
+ }
329
+ buffer += decoder.decode(value, { stream: true });
330
+ buffer = parseBuffer(buffer, onChunk);
331
+ }
332
+ }
333
+ async function request(url, data = {}, options = {}) {
334
+ const { stream = false, method = "POST", headers = {}, signal } = options;
335
+ const controller = new AbortController();
336
+ signal?.addEventListener("abort", () => controller.abort());
337
+ let targetURL = "/api" + url;
338
+ let body = data;
339
+ if (method === "GET") {
340
+ targetURL = buildURLWithParams(targetURL, data);
341
+ body = void 0;
342
+ } else {
343
+ if (!(body instanceof FormData)) {
344
+ headers["Content-Type"] = "application/json";
345
+ body = JSON.stringify(body);
346
+ }
347
+ }
348
+ const response = await fetch(targetURL, {
349
+ method,
350
+ headers: {
351
+ ...common.getToken() && { [common.TOKEN_KEY]: common.getToken() },
352
+ ...headers
353
+ },
354
+ body,
355
+ signal: controller.signal
356
+ });
357
+ if (!response.ok) {
358
+ const message4 = await response.text();
359
+ return await handleHttpError(response.status, message4);
360
+ }
361
+ if (stream && response.body) {
362
+ return handleStreamResponse(response, options);
363
+ }
364
+ const r = await response.json();
365
+ if (r.code !== 200) {
366
+ return await handleHttpError(r.code, r.message);
367
+ }
368
+ return r;
369
+ }
370
+ var get = (url, params = {}, options = {}) => request(url, params, { ...options, method: "GET" });
371
+ var post = (url, data = {}, options = {}) => request(url, data, { ...options, method: "POST" });
372
+ var put = (url, data = {}, options = {}) => request(url, data, { ...options, method: "PUT" });
373
+ var del = (url, data = {}, options = {}) => request(url, data, { ...options, method: "DELETE" });
374
+ var fetchRequest_default = { delete: del, get, post, put };
375
+
376
+ // src/services/index.tsx
377
+ var agentInfoQuery = (agentId) => {
378
+ return common.request.get("/agent/detail", { agentId });
379
+ };
380
+ var agentsQuery = () => {
381
+ return common.request.get("/agent");
382
+ };
383
+ var conversationsQuery = (params) => {
384
+ return common.request.get("/agent/conversation", params);
385
+ };
386
+ var deleteConversation = (params) => {
387
+ return common.request.delete("/agent/conversation", params);
388
+ };
389
+ var chatMessagesQuery = (params) => {
390
+ return common.request.get("/agent/message", params);
391
+ };
392
+ var chatMessageSuggestedQuery = (agentId, messageId) => {
393
+ return common.request.get("/agent/message/suggested", { agentId, messageId });
394
+ };
395
+ var updateFeedback = (params) => {
396
+ return common.request.put("/agent/message/feedback", params);
397
+ };
398
+ var uploadFile = (formData) => {
399
+ return common.request.post("/agent/file", formData);
400
+ };
401
+ var sendMessage = (params) => {
402
+ return fetchRequest_default.post(
403
+ "/agent/chat",
404
+ { ...params, stream: true },
405
+ {
406
+ stream: true,
407
+ onChunk: (chunk) => {
408
+ if (params.onMessageEvent) {
409
+ const event = JSON.parse(chunk);
410
+ params.onMessageEvent(event);
411
+ }
412
+ }
413
+ }
414
+ );
415
+ };
416
+
417
+ // src/stores/index.ts
418
+ var defaultLayout = {
419
+ conversationList: true,
420
+ conversationListHeader: true,
421
+ preview: true,
422
+ messageList: true,
423
+ senderHeader: false,
424
+ sender: true,
425
+ senderPrompts: true,
426
+ senderFooter: false,
427
+ senderExtraBtn: false,
428
+ referencesBtn: false,
429
+ header: true,
430
+ headerTitle: true,
431
+ headerConversationListBtn: true,
432
+ headerNewConversationBtn: true,
433
+ headerCloseBtn: false
434
+ };
435
+ function createChatStore() {
436
+ const config = valtio.proxy({
437
+ hooks: {},
438
+ layout: {},
439
+ preview: {
440
+ file: {},
441
+ isEdit: false
442
+ },
443
+ userInfo: {},
444
+ params: {}
445
+ });
446
+ const setPreview = (file = {}, isEdit = false) => {
447
+ if (config.layout.preview) {
448
+ config.preview = {
449
+ file,
450
+ isEdit
451
+ };
452
+ } else {
453
+ if (file?.fileUrl) {
454
+ window.open(file.fileUrl, "_blank");
455
+ }
456
+ }
457
+ };
458
+ const setLayout = (layout) => {
459
+ config.layout = common.deepMerge(defaultLayout, layout);
460
+ };
461
+ const setConfigParams = (params = {}) => {
462
+ config.params = { bizId: "", ...params };
463
+ };
464
+ const setHooks = (hooks = {}) => {
465
+ config.hooks = hooks;
466
+ };
467
+ const getUserInfo = () => {
468
+ config.userInfo = transform(common.getCurrentUser(), {
469
+ id: "id",
470
+ name: "name",
471
+ iconUrl: "avatar",
472
+ description: "name"
473
+ });
474
+ };
475
+ const agents = valtio.proxy({
476
+ // 商品列表
477
+ list: [],
478
+ loading: false
479
+ });
480
+ const getAgentList = async () => {
481
+ try {
482
+ agents.loading = true;
483
+ const { data } = await agentsQuery();
484
+ agents.list = data;
485
+ } finally {
486
+ agents.loading = false;
487
+ }
488
+ };
489
+ const conversation = valtio.proxy({
490
+ // 每个会话单独存储
491
+ active: {},
492
+ messages: {}
493
+ // feedback: {
494
+ // open: false,
495
+ // loading: false,
496
+ // recordId: '',
497
+ // target: undefined as number | undefined
498
+ // }
499
+ });
500
+ const setReferences = (references) => {
501
+ conversation.messages[conversation.active.key].references = references;
502
+ };
503
+ const setContent = (content) => {
504
+ conversation.messages[conversation.active.key].content = content;
505
+ };
506
+ const setFileList = (files = []) => {
507
+ conversation.messages[conversation.active.key].files = files;
508
+ };
509
+ const setHeaderOpen = (headerOpen) => {
510
+ conversation.messages[conversation.active.key].headerOpen = headerOpen;
511
+ };
512
+ const removeQuestionList = (key) => {
513
+ if (conversation.messages[key].questionList?.length) {
514
+ conversation.messages[key].questionList = [];
515
+ }
516
+ };
517
+ const getQuestionList = async (conversationId, message4) => {
518
+ if (!message4.id || !message4.content) return;
519
+ const { data } = await chatMessageSuggestedQuery(agent.active.id, message4.id);
520
+ conversation.messages[conversationId].questionList = data;
521
+ };
522
+ const feedback = async (conversationId, messageId, rating, index) => {
523
+ try {
524
+ await updateFeedback({ agentId: agent.active.id, messageId, rating, bizId: config.params.bizId });
525
+ conversation.messages[conversationId].message.items[index].feedback = rating;
526
+ } finally {
527
+ }
528
+ };
529
+ const conversations = valtio.proxy({
530
+ list: {
531
+ items: [],
532
+ lastId: "",
533
+ hasMore: false
534
+ },
535
+ loading: false,
536
+ delLoading: false
537
+ });
538
+ const setInitMessage = async (key) => {
539
+ conversation.messages[key] = {
540
+ content: "",
541
+ files: [],
542
+ // 上传文件内容
543
+ headerOpen: false,
544
+ loading: false,
545
+ message: {
546
+ lastId: "",
547
+ hasMore: false,
548
+ items: []
549
+ },
550
+ questionList: []
551
+ // 推荐问题
552
+ };
553
+ };
554
+ const agent = valtio.proxy({
555
+ active: {},
556
+ loading: false
557
+ });
558
+ const switchAgent = async ({ appKey, agentKey, isVerify = false }, conversationId) => {
559
+ const agentId = `${appKey}:${agentKey}`;
560
+ if (agent.active.id === agentId) return;
561
+ const canProceed = await config.hooks?.onBeforeSwitchAgent?.(agentId);
562
+ if (canProceed === false) return;
563
+ try {
564
+ agent.loading = true;
565
+ if (isVerify) {
566
+ }
567
+ const { data } = await agentInfoQuery(agentId);
568
+ agent.active = data;
569
+ config.hooks?.onAfterSwitchAgent?.(agentId);
570
+ switchConversation({ key: conversationId });
571
+ } finally {
572
+ agent.loading = false;
573
+ }
574
+ };
575
+ const switchConversation = async (chat) => {
576
+ const chatKey = chat?.key || `${agent.active.id}-${DEFAULT_NEW_CONV_ID}`;
577
+ if (conversation.active.key === chatKey) return;
578
+ const canProceed = await config.hooks?.onBeforeSwitchConversation?.(chatKey);
579
+ if (canProceed === false) return;
580
+ conversation.active = chat?.key ? chat : { key: chatKey };
581
+ if (!conversation.messages[chatKey]) {
582
+ setInitMessage(chatKey);
583
+ }
584
+ config.hooks?.onAfterSwitchConversation?.(chatKey);
585
+ if (!chatKey.endsWith(DEFAULT_NEW_CONV_ID) && conversation.messages[chatKey].message.items.length === 0) {
586
+ getMessages(agent.active.id, chatKey);
587
+ }
588
+ };
589
+ const getConversations = async (agentId, lastId, limit = 20) => {
590
+ try {
591
+ conversations.loading = true;
592
+ const { data } = await conversationsQuery({ bizId: config.params.bizId, agentId, lastId, limit });
593
+ if (agent.active.id !== agentId) return;
594
+ const items = transforms(data?.items || [], {
595
+ key: "id",
596
+ label: "name",
597
+ group: (c) => {
598
+ return classifyTime(c.createTime);
599
+ },
600
+ timestamp: "createTime"
601
+ });
602
+ conversations.list = {
603
+ ...data,
604
+ items: lastId ? [...conversations.list.items, ...items] : items
605
+ };
606
+ } finally {
607
+ conversations.loading = false;
608
+ }
609
+ };
610
+ const getMessages = async (agentId, conversationId, lastId) => {
611
+ if (conversationId) {
612
+ if (!conversationId.endsWith(DEFAULT_NEW_CONV_ID)) {
613
+ try {
614
+ const { data } = await chatMessagesQuery({
615
+ bizId: config.params.bizId,
616
+ agentId,
617
+ conversationId,
618
+ lastId
619
+ // limit
620
+ });
621
+ const messageList = transforms(data?.items || [], {
622
+ id: "messageId",
623
+ role: (msg) => ChatRoleMap[msg.role],
624
+ content: "message",
625
+ files: "files",
626
+ feedback: "feedback",
627
+ status: "success"
628
+ });
629
+ conversation.messages[conversationId].message = {
630
+ ...data,
631
+ items: lastId ? [...messageList, ...conversation.messages[conversationId].message.items] : messageList
632
+ };
633
+ } finally {
634
+ }
635
+ }
636
+ }
637
+ };
638
+ const delConversation = async (chat) => {
639
+ try {
640
+ conversations.delLoading = true;
641
+ await deleteConversation({ agentId: agent.active.id, conversationId: chat.key, bizId: config.params.bizId });
642
+ antd.message.success("\u5220\u9664\u6210\u529F");
643
+ conversations.list.items = conversations.list.items.filter((item) => item.key !== chat.key);
644
+ if (conversation.active.key === chat.key) {
645
+ conversation.active = {
646
+ key: `${agent.active.id}-${DEFAULT_NEW_CONV_ID}`
647
+ };
648
+ }
649
+ delete conversation.messages[chat.key];
650
+ } finally {
651
+ conversations.delLoading = false;
652
+ }
653
+ };
654
+ const removePlaceholder = (key, msgId) => {
655
+ if (conversation.messages[key]) {
656
+ const index = conversation.messages[key].message.items.findLastIndex((m) => m.id === msgId);
657
+ if (index !== -1) {
658
+ conversation.messages[key].message.items.splice(index, 1);
659
+ }
660
+ }
661
+ };
662
+ const updatePlaceholderMessage = (key, msgId, chunk) => {
663
+ if (chunk.conversationId && chunk.conversationId !== key && !conversation.messages[chunk.conversationId]) {
664
+ conversation.messages[chunk.conversationId] = conversation.messages[key];
665
+ delete conversation.messages[key];
666
+ if (key === conversation.active.key) {
667
+ conversation.active = {
668
+ key: chunk.conversationId
669
+ };
670
+ }
671
+ if (key.startsWith(agent.active.id)) {
672
+ getConversations(agent.active.id);
673
+ }
674
+ }
675
+ let placeholder = {};
676
+ if (conversation.messages[chunk.conversationId]) {
677
+ placeholder = conversation.messages[chunk.conversationId].message.items.findLast((m) => m.id === msgId);
678
+ } else if (conversation.messages[key]) {
679
+ placeholder = conversation.messages[key].message.items.findLast((m) => m.id === msgId);
680
+ }
681
+ if (!placeholder) return;
682
+ if (chunk.type === "TEXT_MESSAGE_CONTENT") {
683
+ const textEvent = chunk;
684
+ placeholder.content += textEvent.message;
685
+ return;
686
+ }
687
+ if (chunk.type === "TEXT_MESSAGE_END") {
688
+ const textEvent = chunk;
689
+ placeholder.id = textEvent.messageId;
690
+ placeholder.status = "success";
691
+ }
692
+ if (chunk.type === "RUN_ERROR") {
693
+ const textEvent = chunk;
694
+ placeholder.status = "error";
695
+ placeholder.content = textEvent.message;
696
+ } else if (chunk.code && chunk.code !== common.OK) {
697
+ removePlaceholder(key, msgId);
698
+ }
699
+ conversation.messages[chunk.conversationId].loading = false;
700
+ };
701
+ const onSendMessage = async (message4, files = []) => {
702
+ const conversationId = conversation.active.key;
703
+ if (conversation.messages[conversationId].loading) return;
704
+ let newMsgContent = "", newImgList;
705
+ if (message4) {
706
+ newMsgContent = message4;
707
+ newImgList = files;
708
+ } else {
709
+ const references = conversation.messages[conversationId].references;
710
+ if (references?.type === 1 && references.content.markdown) {
711
+ newMsgContent = references.content.markdown + "\n";
712
+ }
713
+ newMsgContent = newMsgContent + conversation.messages[conversationId].content;
714
+ newImgList = conversation.messages[conversationId].files;
715
+ }
716
+ if (!newMsgContent) return;
717
+ const canProceed = await config.hooks?.onBeforeSend?.(newMsgContent, newImgList);
718
+ if (canProceed === false) return;
719
+ conversation.messages[conversationId].loading = true;
720
+ const userMsg = {
721
+ id: `user-${Date.now()}`,
722
+ role: "user",
723
+ content: newMsgContent,
724
+ files: newImgList,
725
+ status: "success"
726
+ };
727
+ const placeholderId = `placeholder-${Date.now()}`;
728
+ const placeholder = {
729
+ id: placeholderId,
730
+ role: "assistant",
731
+ content: "",
732
+ status: "loading"
733
+ };
734
+ conversation.messages[conversationId].message.items.push(userMsg, placeholder);
735
+ if (!message4) {
736
+ setContent("");
737
+ setFileList([]);
738
+ setReferences();
739
+ setHeaderOpen(false);
740
+ }
741
+ removeQuestionList(conversationId);
742
+ try {
743
+ sendMessage({
744
+ agentId: agent.active.id,
745
+ conversationId: conversationId.endsWith(DEFAULT_NEW_CONV_ID) ? void 0 : conversationId,
746
+ message: userMsg.content,
747
+ files: userMsg.files,
748
+ ...config.params,
749
+ onMessageEvent: (event) => {
750
+ updatePlaceholderMessage(conversationId, placeholderId, event);
751
+ }
752
+ });
753
+ config.hooks?.onAfterSend?.();
754
+ } catch (error) {
755
+ removePlaceholder(conversationId, placeholderId);
756
+ conversation.messages[conversationId].loading = false;
757
+ }
758
+ };
759
+ const onCancelReceive = () => {
760
+ conversation.messages[conversation.active.key].loading = false;
761
+ };
762
+ return {
763
+ config,
764
+ setLayout,
765
+ setHooks,
766
+ setConfigParams,
767
+ setPreview,
768
+ getUserInfo,
769
+ agents,
770
+ getAgentList,
771
+ conversation,
772
+ setReferences,
773
+ setContent,
774
+ setFileList,
775
+ setHeaderOpen,
776
+ removeQuestionList,
777
+ getQuestionList,
778
+ feedback,
779
+ conversations,
780
+ setInitMessage,
781
+ agent,
782
+ switchAgent,
783
+ getConversations,
784
+ getMessages,
785
+ switchConversation,
786
+ delConversation,
787
+ removePlaceholder,
788
+ updatePlaceholderMessage,
789
+ onSendMessage,
790
+ onCancelReceive
791
+ };
792
+ }
793
+ init_Context();
794
+
795
+ // src/ui/common/AgentHeader.tsx
796
+ init_Context();
797
+
798
+ // src/ui/common/ConversationList.tsx
799
+ init_Context();
800
+
801
+ // src/ui/common/styles.module.less
802
+ var styles_module_default = {
803
+ loadingMessage: "styles_module_loadingMessage",
804
+ nsConversations: "styles_module_nsConversations",
805
+ nsBody: "styles_module_nsBody",
806
+ nsBodyWidth: "styles_module_nsBodyWidth",
807
+ nsBubbleList: "styles_module_nsBubbleList",
808
+ nsChatTitle: "styles_module_nsChatTitle",
809
+ nsChatHeaderPopover: "styles_module_nsChatHeaderPopover",
810
+ chatWelcomeWrap: "styles_module_chatWelcomeWrap",
811
+ chatWelcome: "styles_module_chatWelcome",
812
+ chatWelcomePrompts: "styles_module_chatWelcomePrompts",
813
+ senderListTitle: "styles_module_senderListTitle",
814
+ senderList: "styles_module_senderList",
815
+ senderListItem: "styles_module_senderListItem",
816
+ senderListFooter: "styles_module_senderListFooter",
817
+ nsChatUserName: "styles_module_nsChatUserName",
818
+ nsSenderHeaderContent: "styles_module_nsSenderHeaderContent"
819
+ };
820
+ var ConversationList_default = () => {
821
+ const chatStore = useChatStore();
822
+ const agentState = valtio.useSnapshot(chatStore.agent);
823
+ const conversationsState = valtio.useSnapshot(chatStore.conversations);
824
+ const conversationState = valtio.useSnapshot(chatStore.conversation);
825
+ react.useEffect(() => {
826
+ if (agentState.active.id) {
827
+ chatStore.getConversations(agentState.active.id);
828
+ }
829
+ }, [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(
831
+ InfiniteScroll__default.default,
832
+ {
833
+ dataLength: conversationsState.list.items.length,
834
+ next: () => {
835
+ console.log("next");
836
+ chatStore.getConversations(agentState.active.id, conversationsState.list.lastId);
837
+ },
838
+ hasMore: conversationsState.list.hasMore,
839
+ loader: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { indicator: /* @__PURE__ */ jsxRuntime.jsx(icons.RedoOutlined, { spin: true }), size: "small" }) }),
840
+ style: { overflow: "hidden" },
841
+ scrollableTarget: "scrollableDiv",
842
+ children: /* @__PURE__ */ jsxRuntime.jsx(
843
+ x.Conversations,
844
+ {
845
+ className: styles_module_default.nsConversations,
846
+ items: conversationsState.list.items,
847
+ activeKey: conversationState.active.key,
848
+ onActiveChange: async (key) => chatStore.switchConversation({ key }),
849
+ groupable: true,
850
+ menu: (conversation) => ({
851
+ items: [
852
+ {
853
+ label: "\u5220\u9664\u4F1A\u8BDD",
854
+ key: "delete",
855
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DeleteOutlined, {}),
856
+ danger: true,
857
+ onClick: (menuInfo) => {
858
+ menuInfo.domEvent.stopPropagation();
859
+ chatStore.delConversation(conversation);
860
+ }
861
+ }
862
+ ]
863
+ })
864
+ }
865
+ )
866
+ }
867
+ ) }) });
868
+ };
869
+ var AgentHeader_default = () => {
870
+ const chatStore = useChatStore();
871
+ const agentState = valtio.useSnapshot(chatStore.agent);
872
+ 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: [
875
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", children: [
876
+ /* @__PURE__ */ jsxRuntime.jsx(
877
+ common.RenderWrapper,
878
+ {
879
+ control: configState.layout.headerTitle,
880
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
881
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 22, src: agentState.active.iconUrl, alt: agentState.active.name }),
882
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default.nsChatTitle, children: agentState.active.name })
883
+ ] })
884
+ }
885
+ ),
886
+ " "
887
+ ] }),
888
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { size: 0, children: [
889
+ /* @__PURE__ */ jsxRuntime.jsx(
890
+ common.RenderWrapper,
891
+ {
892
+ control: configState.layout.headerNewConversationBtn,
893
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}), onClick: () => chatStore.switchConversation() })
894
+ }
895
+ ),
896
+ /* @__PURE__ */ jsxRuntime.jsx(
897
+ common.RenderWrapper,
898
+ {
899
+ control: configState.layout.headerConversationListBtn,
900
+ DefaultComponent: conversationsState.list.items.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
901
+ antd.Popover,
902
+ {
903
+ getPopupContainer: (e) => e,
904
+ placement: "bottom",
905
+ classNames: { body: styles_module_default.nsChatHeaderPopover },
906
+ content: /* @__PURE__ */ jsxRuntime.jsx(ConversationList_default, {}),
907
+ trigger: ["click"],
908
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CommentOutlined, {}) })
909
+ }
910
+ )
911
+ }
912
+ ),
913
+ /* @__PURE__ */ jsxRuntime.jsx(
914
+ common.RenderWrapper,
915
+ {
916
+ 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, {}) })
918
+ }
919
+ )
920
+ ] })
921
+ ] }) });
922
+ };
923
+
924
+ // src/ui/common/markdownAlert/index.ts
925
+ var customComponents = {
926
+ appCard: () => Promise.resolve().then(() => (init_AppCard(), AppCard_exports)),
927
+ fileView: () => Promise.resolve().then(() => (init_FileView(), FileView_exports)),
928
+ indexQuote: () => Promise.resolve().then(() => (init_IndexQuote(), IndexQuote_exports)),
929
+ editableMarkdownCard: () => Promise.resolve().then(() => (init_EditableMarkdownCard(), EditableMarkdownCard_exports)),
930
+ fileEdit: () => Promise.resolve().then(() => (init_FileEdit(), FileEdit_exports)),
931
+ quoteList: () => Promise.resolve().then(() => (init_QuoteList(), QuoteList_exports))
932
+ };
933
+ var MessageRender_default = ({ message: message4, placement }) => {
934
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, children: [
935
+ message4.content && /* @__PURE__ */ jsxRuntime.jsx(x.Bubble, { placement, content: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: message4.content, customComponents }) }),
936
+ message4.files?.map((file, index) => /* @__PURE__ */ jsxRuntime.jsx(
937
+ x.Bubble,
938
+ {
939
+ className: "m-t-8",
940
+ variant: "borderless",
941
+ placement,
942
+ content: /* @__PURE__ */ jsxRuntime.jsx(
943
+ x.Attachments.FileCard,
944
+ {
945
+ item: {
946
+ uid: file.id,
947
+ name: file.name,
948
+ url: file.url
949
+ }
950
+ },
951
+ index
952
+ )
953
+ },
954
+ index
955
+ ))
956
+ ] });
957
+ };
958
+
959
+ // src/ui/common/BubbleListItems.tsx
960
+ init_Context();
961
+ function extractThinkContent(content) {
962
+ let main = content;
963
+ const thinkContents = [];
964
+ let buffer = "";
965
+ const regex = /<think>(.*?)<\/think>/gs;
966
+ for (const match of content.matchAll(regex)) {
967
+ const thinkText = match[1].trim();
968
+ thinkContents.push(thinkText);
969
+ main = main.replace(match[0], "");
970
+ }
971
+ const lastStart = content.lastIndexOf("<think>");
972
+ const lastEnd = content.lastIndexOf("</think>");
973
+ if (lastStart > lastEnd) {
974
+ buffer = content.slice(lastStart).replace("<think>", "");
975
+ main = main.slice(0, lastStart);
976
+ }
977
+ return { mainContent: main, thinkContents, thinkBuffer: buffer };
978
+ }
979
+ function renderMarkdownPanel(content, label, key) {
980
+ return {
981
+ key,
982
+ label,
983
+ children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content, customComponents })
984
+ };
985
+ }
986
+ var MessageAIRender_default = ({ message: message4, placement }) => {
987
+ const { mainContent, thinkContents, thinkBuffer } = react.useMemo(() => {
988
+ if (!message4?.content) return { mainContent: "", thinkContents: [], thinkBuffer: "" };
989
+ return extractThinkContent(message4.content);
990
+ }, [message4?.content]);
991
+ const isWaiting = !message4 || !message4.content && message4.status === "loading";
992
+ if (isWaiting) {
993
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Typography, { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { size: "small" }) });
994
+ }
995
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, children: /* @__PURE__ */ jsxRuntime.jsx(
996
+ x.Bubble,
997
+ {
998
+ placement,
999
+ className: classNames2__default.default({ [styles_module_default.loadingMessage]: message4.status === "loading" }),
1000
+ content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1001
+ thinkContents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1002
+ antd.Collapse,
1003
+ {
1004
+ ghost: true,
1005
+ size: "small",
1006
+ defaultActiveKey: thinkContents.map((_, i) => `think-${i}`),
1007
+ items: thinkContents.map((content, index) => renderMarkdownPanel(content, `\u601D\u8003\u8FC7\u7A0B`, `think-${index}`))
1008
+ }
1009
+ ),
1010
+ thinkBuffer && /* @__PURE__ */ jsxRuntime.jsx(
1011
+ antd.Collapse,
1012
+ {
1013
+ ghost: true,
1014
+ size: "small",
1015
+ defaultActiveKey: ["buffer-think"],
1016
+ items: [renderMarkdownPanel(thinkBuffer, "\u4ED4\u7EC6\u601D\u8003\u4E2D...", "buffer-think")]
1017
+ }
1018
+ ),
1019
+ mainContent && message4.status === "error" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1020
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CloseCircleOutlined, { color: "red" }),
1021
+ " ",
1022
+ mainContent
1023
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: mainContent, customComponents })
1024
+ ] })
1025
+ }
1026
+ ) });
1027
+ };
1028
+ var BubbleListItems_default = ({ avatar = true }) => {
1029
+ const chatStore = useChatStore();
1030
+ const agentState = valtio.useSnapshot(chatStore.agent);
1031
+ const conversationState = valtio.useSnapshot(chatStore.conversation);
1032
+ const configState = valtio.useSnapshot(chatStore.config);
1033
+ const conversationRoles = react.useMemo(() => {
1034
+ return {
1035
+ user: {
1036
+ user: "user",
1037
+ placement: "end",
1038
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.user) ? /* @__PURE__ */ jsxRuntime.jsx(common.UserAvatar, { size: 30, avatarSrc: configState.userInfo?.iconUrl, userName: configState.userInfo?.name }) : null
1039
+ },
1040
+ assistant: {
1041
+ user: "assistant",
1042
+ placement: "start",
1043
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.assistant) ? { src: agentState.active.iconUrl, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.OpenAIOutlined, {}) } : null
1044
+ }
1045
+ };
1046
+ }, [configState.userInfo, agentState.active, avatar]);
1047
+ const chatMessage = react.useMemo(
1048
+ () => conversationState.messages[conversationState.active.key] || {},
1049
+ [conversationState.messages[conversationState.active.key]]
1050
+ );
1051
+ const placeholderNode = react.useMemo(
1052
+ () => [
1053
+ {
1054
+ key: "placeholder",
1055
+ content: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { direction: "vertical", size: 16, className: styles_module_default.chatWelcomeWrap, children: [
1056
+ /* @__PURE__ */ jsxRuntime.jsx(
1057
+ x.Welcome,
1058
+ {
1059
+ className: classNames2__default.default(styles_module_default.chatWelcome, "p-t-32"),
1060
+ variant: "borderless",
1061
+ icon: /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { shape: "square", size: 58, src: agentState.active.iconUrl }),
1062
+ title: `\u4F60\u597D\uFF0C\u6211\u662F${agentState.active.name || ""}`,
1063
+ description: agentState.active.description || ""
1064
+ }
1065
+ ),
1066
+ agentState.active.recommendQuestions?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1067
+ x.Prompts,
1068
+ {
1069
+ className: "m-t-16",
1070
+ wrap: true,
1071
+ items: [
1072
+ {
1073
+ key: "1",
1074
+ label: "\u{1F914} \u63A8\u8350\u95EE\u9898:",
1075
+ children: agentState.active.recommendQuestions.map(({ question, id }) => ({
1076
+ key: id,
1077
+ description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.onSendMessage(question), className: classNames2__default.default(styles_module_default.chatWelcomePrompts, "text-ellipsis"), children: question })
1078
+ }))
1079
+ }
1080
+ ]
1081
+ }
1082
+ )
1083
+ ] }),
1084
+ variant: "borderless"
1085
+ }
1086
+ ],
1087
+ [agentState.active]
1088
+ );
1089
+ const questionList = react.useMemo(
1090
+ () => chatMessage?.questionList?.length ? [
1091
+ {
1092
+ key: "questionList",
1093
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1094
+ x.Prompts,
1095
+ {
1096
+ className: "m-b-16",
1097
+ styles: {
1098
+ list: {
1099
+ overflow: "auto"
1100
+ }
1101
+ },
1102
+ vertical: true,
1103
+ items: chatMessage?.questionList.map(({ question, id }) => ({
1104
+ key: id,
1105
+ description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.onSendMessage(question), children: question })
1106
+ }))
1107
+ }
1108
+ ),
1109
+ variant: "borderless",
1110
+ avatar: { style: { visibility: "hidden" } }
1111
+ }
1112
+ ] : [],
1113
+ [chatMessage?.questionList]
1114
+ );
1115
+ const chatRecords = react.useMemo(() => {
1116
+ return (chatMessage?.message?.items || []).map((message4, index) => {
1117
+ return {
1118
+ key: message4.id || -index,
1119
+ placement: conversationRoles[message4.role].placement,
1120
+ variant: "borderless",
1121
+ avatar: conversationRoles[message4.role].avatar,
1122
+ content: message4.role === "assistant" ? /* @__PURE__ */ jsxRuntime.jsx(MessageAIRender_default, { message: message4, placement: conversationRoles[message4.role].placement }) : /* @__PURE__ */ jsxRuntime.jsx(MessageRender_default, { message: message4, placement: conversationRoles[message4.role].placement }),
1123
+ // loadingRender: () => <Spin size="small" />,
1124
+ footer: message4.role === "assistant" && message4.id && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { children: [
1125
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => copy(message4.content), color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CopyOutlined, {}) }),
1126
+ /* @__PURE__ */ jsxRuntime.jsx(
1127
+ antd.Button,
1128
+ {
1129
+ color: message4.feedback === "like" ? "primary" : "default",
1130
+ disabled: message4.status === "loading",
1131
+ size: "small",
1132
+ variant: "text",
1133
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LikeOutlined, {}),
1134
+ onClick: () => chatStore.feedback(conversationState.active.key, message4.id, "like", index)
1135
+ }
1136
+ ),
1137
+ /* @__PURE__ */ jsxRuntime.jsx(
1138
+ antd.Button,
1139
+ {
1140
+ color: message4.feedback === "dislike" ? "primary" : "default",
1141
+ disabled: message4.status === "loading",
1142
+ size: "small",
1143
+ variant: "text",
1144
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DislikeOutlined, {}),
1145
+ onClick: () => chatStore.feedback(conversationState.active.key, message4.id, "dislike", index)
1146
+ }
1147
+ )
1148
+ ] })
1149
+ // ...(isHasTime
1150
+ // ? { rootClassName: styles.hasSendTime, classNames: { header: styles.sendTime }, header: <span>{formatDate(message.sendDate)}</span> }
1151
+ // : {})
1152
+ };
1153
+ });
1154
+ }, [chatMessage?.message]);
1155
+ const bubbleListItems = react.useMemo(() => {
1156
+ const list = [];
1157
+ if (chatRecords.length > 0) {
1158
+ list.push(...chatRecords, ...questionList);
1159
+ }
1160
+ if (list.length) {
1161
+ return list;
1162
+ }
1163
+ return [...placeholderNode];
1164
+ }, [chatRecords, questionList, placeholderNode]);
1165
+ const listRef = react.useRef(null);
1166
+ react.useEffect(() => {
1167
+ if (bubbleListItems.length && (listRef.current?.nativeElement.scrollHeight ?? 0) - ((listRef.current?.nativeElement.scrollTop ?? 0) + (listRef.current?.nativeElement.clientHeight ?? 0)) < 100) {
1168
+ listRef.current?.scrollTo({ key: bubbleListItems[bubbleListItems.length - 1].key, block: "end" });
1169
+ }
1170
+ }, [bubbleListItems]);
1171
+ return /* @__PURE__ */ jsxRuntime.jsx(
1172
+ x.Bubble.List,
1173
+ {
1174
+ ref: listRef,
1175
+ items: bubbleListItems,
1176
+ className: classNames2__default.default(styles_module_default.nsBubbleList, "height-full", "scroll-fade-in")
1177
+ },
1178
+ conversationState.active.key
1179
+ );
1180
+ };
1181
+ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSizeTip, fileList = [], onChange, extraParams }, ref) => {
1182
+ const fileListRef = react.useRef([]);
1183
+ const [attachedFiles, setAttachedFiles, getAttachedFiles] = common.useRefState([]);
1184
+ react.useEffect(() => {
1185
+ if (JSON.stringify(fileList) !== JSON.stringify(fileListRef.current)) {
1186
+ fileListRef.current = fileList;
1187
+ const mapped = fileList.map((file) => ({
1188
+ ...file,
1189
+ uid: file.id,
1190
+ status: "done"
1191
+ }));
1192
+ setAttachedFiles(mapped);
1193
+ }
1194
+ }, [fileList]);
1195
+ react.useEffect(() => {
1196
+ const files = attachedFiles.filter((file) => file.status === "done").map((file) => {
1197
+ const f = { ...file };
1198
+ delete f.status;
1199
+ delete f.uid;
1200
+ delete f.size;
1201
+ return f;
1202
+ });
1203
+ fileListRef.current = files;
1204
+ onChange(files);
1205
+ }, [attachedFiles]);
1206
+ const onErrorTip = common.useDebounce((errorMsg) => {
1207
+ antd.message.error(errorMsg);
1208
+ }, 300);
1209
+ const onBeforeUpload = (files) => {
1210
+ if (common.isNumber(maxCount) && files.length + attachedFiles.length > maxCount) {
1211
+ onErrorTip(`\u6700\u591A\u53EA\u80FD\u4E0A\u4F20${maxCount}\u4E2A\u6587\u4EF6`);
1212
+ return Promise.reject(false);
1213
+ }
1214
+ };
1215
+ const onCustomRequest = async ({ file }) => {
1216
+ if (fileSize && file.size > fileSize) {
1217
+ antd.message.error(`${fileSizeTip}`);
1218
+ return;
1219
+ }
1220
+ setAttachedFiles([
1221
+ ...getAttachedFiles(),
1222
+ {
1223
+ type: file.type,
1224
+ name: file.name,
1225
+ uid: file.uid,
1226
+ status: "uploading",
1227
+ percent: 70,
1228
+ size: file.size
1229
+ }
1230
+ ]);
1231
+ try {
1232
+ const formData = new FormData();
1233
+ formData.append("file", file);
1234
+ if (common.isObject(extraParams)) {
1235
+ Object.keys(extraParams).forEach((key) => {
1236
+ if (common.isNullOrUnDef(extraParams[key])) return;
1237
+ formData.append(key, extraParams[key]);
1238
+ });
1239
+ }
1240
+ const { data } = await uploadFile(formData);
1241
+ if (!data?.url && data?.type === "image") {
1242
+ data.url = await getBase64(file);
1243
+ }
1244
+ setAttachedFiles(
1245
+ getAttachedFiles().map((f) => {
1246
+ if (f.uid === file.uid) {
1247
+ return { ...data, uid: data.id, status: "done", size: f.size };
1248
+ } else {
1249
+ return f;
1250
+ }
1251
+ })
1252
+ );
1253
+ } catch (error) {
1254
+ console.log("\u4E0A\u4F20\u6587\u4EF6\u9519\u8BEF\uFF1A", error);
1255
+ setAttachedFiles(
1256
+ getAttachedFiles().map((f) => {
1257
+ if (f.uid === file.uid) {
1258
+ return { ...f, status: "error", description: "\u4E0A\u4F20\u5931\u8D25" };
1259
+ } else {
1260
+ return f;
1261
+ }
1262
+ })
1263
+ );
1264
+ }
1265
+ };
1266
+ const onRemove = (file) => {
1267
+ setAttachedFiles(attachedFiles.filter((f) => f.uid !== file.uid));
1268
+ };
1269
+ react.useImperativeHandle(
1270
+ ref,
1271
+ () => ({
1272
+ validateFile: () => {
1273
+ const files = getAttachedFiles();
1274
+ const uploadingFiles = files.filter((file) => file.status === "uploading");
1275
+ if (uploadingFiles.length > 0) {
1276
+ antd.message.error("\u8BF7\u7B49\u5F85\u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210");
1277
+ return false;
1278
+ }
1279
+ const errorFiles = files.filter((file) => file.status === "error");
1280
+ if (errorFiles.length > 0) {
1281
+ antd.message.error("\u8BF7\u68C0\u67E5\u4E0A\u4F20\u5931\u8D25\u7684\u6587\u4EF6");
1282
+ return false;
1283
+ }
1284
+ return true;
1285
+ }
1286
+ }),
1287
+ []
1288
+ );
1289
+ const acceptStr = react.useMemo(() => {
1290
+ if (!accept?.length) return;
1291
+ const fileTypeMap = {
1292
+ document: [
1293
+ ".txt",
1294
+ ".md",
1295
+ ".mdx",
1296
+ ".markdown",
1297
+ ".pdf",
1298
+ ".html",
1299
+ ".xlsx",
1300
+ ".xls",
1301
+ ".doc",
1302
+ ".docx",
1303
+ ".csv",
1304
+ ".eml",
1305
+ ".msg",
1306
+ ".pptx",
1307
+ ".ppt",
1308
+ ".xml",
1309
+ ".epub"
1310
+ ],
1311
+ image: [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"]
1312
+ };
1313
+ const accepts = [];
1314
+ accept?.forEach((type) => {
1315
+ if (fileTypeMap[type]) {
1316
+ accepts.push(...fileTypeMap[type]);
1317
+ }
1318
+ });
1319
+ if (accepts.length === 0) {
1320
+ accepts.push(...accept);
1321
+ }
1322
+ return accepts.join(",");
1323
+ }, [accept]);
1324
+ return /* @__PURE__ */ jsxRuntime.jsx(
1325
+ x.Attachments,
1326
+ {
1327
+ className: "nsAttachments",
1328
+ accept: acceptStr,
1329
+ multiple: !common.isNumber(maxCount) || maxCount > 1,
1330
+ maxCount,
1331
+ customRequest: onCustomRequest,
1332
+ beforeUpload: (file, files) => onBeforeUpload(files),
1333
+ items: attachedFiles,
1334
+ onRemove,
1335
+ placeholder: (type) => type === "drop" ? { title: "\u5C06\u6587\u4EF6\u653E\u5230\u8FD9\u91CC" } : {
1336
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloudUploadOutlined, {}),
1337
+ title: "\u63D0\u4EA4\u6587\u4EF6",
1338
+ description: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: "\u5355\u51FB\u6216\u62D6\u52A8\u6587\u4EF6\u5230\u6B64\u533A\u57DF\u8FDB\u884C\u4E0A\u4F20; " }) })
1339
+ }
1340
+ }
1341
+ );
1342
+ });
1343
+ var ChatSender_default = react.forwardRef(
1344
+ ({
1345
+ placeholder,
1346
+ content,
1347
+ fileList = [],
1348
+ headerOpen = false,
1349
+ loading = false,
1350
+ onContentChange,
1351
+ onFileListChange,
1352
+ onHeaderOpenChange,
1353
+ onSend,
1354
+ onCancel,
1355
+ extraHeader,
1356
+ extraFooter,
1357
+ extraFooterBelow,
1358
+ sendButtonProps,
1359
+ fileUpload
1360
+ }, ref) => {
1361
+ const senderRef = react.useRef(null);
1362
+ const { inputValue, setInputValue } = common.useSyncInput(content || "", onContentChange);
1363
+ const attachmentsNode = fileUpload?.enabled && /* @__PURE__ */ jsxRuntime.jsx(antd.Badge, { dot: !!fileList?.length && !headerOpen, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperClipOutlined, {}), onClick: () => onHeaderOpenChange(!headerOpen) }) });
1364
+ const attachmentsRef = react.useRef();
1365
+ const senderHeader = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1366
+ /* @__PURE__ */ jsxRuntime.jsx(x.Sender.Header, { title: "\u9009\u62E9\u6587\u4EF6", open: headerOpen, onOpenChange: onHeaderOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(
1367
+ Attachments_default,
1368
+ {
1369
+ ref: attachmentsRef,
1370
+ fileList,
1371
+ onChange: onFileListChange,
1372
+ accept: fileUpload?.allowedFileTypes,
1373
+ maxCount: fileUpload?.maxFileCount,
1374
+ extraParams: fileUpload?.extraParams
1375
+ }
1376
+ ) }),
1377
+ extraHeader
1378
+ ] });
1379
+ const onSubmit = () => {
1380
+ if (!attachmentsRef.current?.validateFile || attachmentsRef.current.validateFile()) {
1381
+ onSend();
1382
+ }
1383
+ };
1384
+ react.useImperativeHandle(
1385
+ ref,
1386
+ () => ({
1387
+ focus: (options) => {
1388
+ senderRef.current?.focus(options);
1389
+ }
1390
+ }),
1391
+ []
1392
+ );
1393
+ return /* @__PURE__ */ jsxRuntime.jsx(x.Suggestion, { items: [], onSelect: (itemVal) => setInputValue(`[${itemVal}]:`), children: ({}) => /* @__PURE__ */ jsxRuntime.jsx(
1394
+ x.Sender,
1395
+ {
1396
+ ref: senderRef,
1397
+ value: inputValue,
1398
+ header: senderHeader,
1399
+ onSubmit,
1400
+ onChange: setInputValue,
1401
+ autoSize: { minRows: 2, maxRows: 6 },
1402
+ onCancel,
1403
+ footer: ({ components }) => {
1404
+ const { SendButton, LoadingButton } = components;
1405
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, children: [
1406
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", gap: 12, children: [
1407
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { className: "flex-1", gap: 6, align: "center", children: [
1408
+ attachmentsNode,
1409
+ extraFooter,
1410
+ " "
1411
+ ] }),
1412
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { align: "center", children: loading ? /* @__PURE__ */ jsxRuntime.jsx(LoadingButton, {}) : /* @__PURE__ */ jsxRuntime.jsx(SendButton, { ...sendButtonProps }) })
1413
+ ] }),
1414
+ extraFooterBelow
1415
+ ] });
1416
+ },
1417
+ actions: false,
1418
+ placeholder: placeholder || "\u6709\u4EC0\u4E48\u6211\u80FD\u5E2E\u60A8\u7684\u5417\uFF1F"
1419
+ }
1420
+ ) });
1421
+ }
1422
+ );
1423
+
1424
+ // src/ui/common/ChatSender.tsx
1425
+ init_Context();
1426
+ var ChatSender_default2 = () => {
1427
+ const chatStore = useChatStore();
1428
+ const agentState = valtio.useSnapshot(chatStore.agent);
1429
+ const conversationState = valtio.useSnapshot(chatStore.conversation);
1430
+ const configState = valtio.useSnapshot(chatStore.config);
1431
+ const chatMessage = react.useMemo(
1432
+ () => conversationState.messages[conversationState.active.key] || {},
1433
+ [conversationState.messages[conversationState.active.key]]
1434
+ );
1435
+ const referenceHandle = (con) => {
1436
+ if (chatMessage?.loading) return;
1437
+ chatStore.setContent(con);
1438
+ setTimeout(() => {
1439
+ chatStore.onSendMessage();
1440
+ }, 10);
1441
+ };
1442
+ return /* @__PURE__ */ jsxRuntime.jsx(
1443
+ ChatSender_default,
1444
+ {
1445
+ content: chatMessage.content,
1446
+ fileList: chatMessage.files,
1447
+ headerOpen: chatMessage.headerOpen,
1448
+ loading: chatMessage.loading,
1449
+ onContentChange: chatStore.setContent,
1450
+ onFileListChange: chatStore.setFileList,
1451
+ onHeaderOpenChange: chatStore.setHeaderOpen,
1452
+ onSend: () => chatStore.onSendMessage(),
1453
+ fileUpload: {
1454
+ ...agentState.active?.parameters?.fileUpload,
1455
+ extraParams: { agentId: agentState.active.id }
1456
+ },
1457
+ extraFooter: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1458
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { size: "small", color: "primary", variant: "filled", children: "\u6DF1\u5EA6\u601D\u8003" }),
1459
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.senderExtraBtn })
1460
+ ] }),
1461
+ extraHeader: /* @__PURE__ */ jsxRuntime.jsx(
1462
+ x.Sender.Header,
1463
+ {
1464
+ title: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { children: [
1465
+ /* @__PURE__ */ jsxRuntime.jsx(icons.EnterOutlined, {}),
1466
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { type: "secondary", children: chatMessage?.references?.content?.name })
1467
+ ] }),
1468
+ open: !!chatMessage?.references?.content?.name,
1469
+ onOpenChange: () => chatStore.setReferences(),
1470
+ classNames: {
1471
+ content: common.shouldRender(configState.layout.referencesBtn) ? "" : styles_module_default.nsSenderHeaderContent
1472
+ },
1473
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1474
+ common.RenderWrapper,
1475
+ {
1476
+ control: configState.layout.referencesBtn,
1477
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { gap: 8, children: ["\u6DF1\u5EA6\u89E3\u8BFB", "\u6982\u8981\u89E3\u8BFB"].map((con) => /* @__PURE__ */ jsxRuntime.jsxs(antd.Button, { color: "primary", variant: "filled", onClick: () => referenceHandle(con), children: [
1478
+ con,
1479
+ " \u2192"
1480
+ ] }, con)) })
1481
+ }
1482
+ )
1483
+ }
1484
+ )
1485
+ }
1486
+ );
1487
+ };
1488
+
1489
+ // src/ui/common/ConversationListHeader.tsx
1490
+ init_Context();
1491
+ var ConversationListHeader_default = () => {
1492
+ const chatStore = useChatStore();
1493
+ const agentState = valtio.useSnapshot(chatStore.agent);
1494
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-24", children: [
1495
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { align: "center", gap: 8, children: [
1496
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 36, src: agentState.active.iconUrl }),
1497
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles_module_default.nsChatUserName, children: agentState.active.name })
1498
+ ] }),
1499
+ /* @__PURE__ */ jsxRuntime.jsx(
1500
+ antd.Button,
1501
+ {
1502
+ block: true,
1503
+ type: "primary",
1504
+ shape: "round",
1505
+ onClick: () => chatStore.switchConversation(),
1506
+ className: classNames2__default.default("m-t-16"),
1507
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}),
1508
+ children: "\u65B0\u5EFA\u4F1A\u8BDD"
1509
+ }
1510
+ )
1511
+ ] });
1512
+ };
1513
+
1514
+ // src/ui/common/SenderPromptsItems.tsx
1515
+ init_Context();
1516
+ var SenderPromptsItems_default = () => {
1517
+ const chatStore = useChatStore();
1518
+ const agentState = valtio.useSnapshot(chatStore.agent);
1519
+ const component = react.useMemo(
1520
+ () => agentState.active.labels?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, wrap: true, children: [
1521
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { disabled: true, color: "default", variant: "text", children: "\u968F\u4FBF\u804A\u804A" }),
1522
+ agentState.active.labels.map((question) => /* @__PURE__ */ jsxRuntime.jsx(
1523
+ antd.Popover,
1524
+ {
1525
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1526
+ antd.List,
1527
+ {
1528
+ itemLayout: "horizontal",
1529
+ split: false,
1530
+ className: styles_module_default.senderList,
1531
+ 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 }),
1533
+ 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
+ }
1535
+ ),
1536
+ title: /* @__PURE__ */ jsxRuntime.jsx(
1537
+ "div",
1538
+ {
1539
+ className: classNames2__default.default(styles_module_default.senderListTitle, "text-ellipsis"),
1540
+ children: `${agentState.active.name}\u5F00\u59CB\u5173\u6CE8${question.labelName}\u5185\u5BB9\uFF01`
1541
+ }
1542
+ ),
1543
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "filled", children: question.labelName })
1544
+ },
1545
+ question.id
1546
+ ))
1547
+ ] }),
1548
+ [agentState.active.labels]
1549
+ );
1550
+ return component;
1551
+ };
1552
+
1553
+ // src/ui/layouts/styles.module.less
1554
+ var styles_module_default3 = {
1555
+ nsPreviewHeader: "styles_module_nsPreviewHeader",
1556
+ nsPreviewHeaderTitle: "styles_module_nsPreviewHeaderTitle",
1557
+ nsChatTitle: "styles_module_nsChatTitle2"
1558
+ };
1559
+ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultAgent }, ref) => {
1560
+ const chatStore = react.useMemo(() => createChatStore(), []);
1561
+ react.useEffect(() => {
1562
+ chatStore.getUserInfo();
1563
+ if (defaultAgent?.appKey && defaultAgent?.agentKey) {
1564
+ chatStore.switchAgent({ appKey: defaultAgent.appKey, agentKey: defaultAgent.agentKey }, defaultAgent.conversationId);
1565
+ }
1566
+ }, []);
1567
+ react.useEffect(() => {
1568
+ chatStore.setLayout(layout);
1569
+ }, [layout]);
1570
+ react.useEffect(() => {
1571
+ chatStore.setConfigParams(params);
1572
+ }, [params]);
1573
+ react.useEffect(() => {
1574
+ chatStore.setHooks(hooks);
1575
+ }, [hooks]);
1576
+ const agentState = valtio.useSnapshot(chatStore.agent);
1577
+ const configState = valtio.useSnapshot(chatStore.config);
1578
+ react.useImperativeHandle(
1579
+ ref,
1580
+ () => ({
1581
+ sendMessage: chatStore.onSendMessage,
1582
+ switchAgent: chatStore.switchAgent,
1583
+ switchConversation: chatStore.switchConversation,
1584
+ setReferences: chatStore.setReferences,
1585
+ setMessage: chatStore.setContent,
1586
+ setFiles: chatStore.setFileList,
1587
+ setParams: chatStore.setConfigParams,
1588
+ setLayout: chatStore.setLayout
1589
+ }),
1590
+ []
1591
+ );
1592
+ const setSplitterSizes = (sizes) => {
1593
+ console.log(sizes);
1594
+ };
1595
+ 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
+ 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
+ /* @__PURE__ */ jsxRuntime.jsx(
1598
+ common.RenderWrapper,
1599
+ {
1600
+ control: configState.layout.conversationListHeader,
1601
+ DefaultComponent: ConversationListHeader_default
1602
+ }
1603
+ ),
1604
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(
1605
+ common.RenderWrapper,
1606
+ {
1607
+ control: configState.layout.conversationList,
1608
+ DefaultComponent: ConversationList_default
1609
+ }
1610
+ ) })
1611
+ ] }) }),
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"
1623
+ }
1624
+ ),
1625
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => chatStore.setPreview(), children: "\u5173\u95ED" })
1626
+ ] })
1627
+ ] }),
1628
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: configState.preview.file.fileUrl && /* @__PURE__ */ jsxRuntime.jsx(
1629
+ common.FilePreview,
1630
+ {
1631
+ ...configState.preview.file,
1632
+ pdfParams: {
1633
+ isHasThumbnails: false
1634
+ }
1635
+ }
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: [
1639
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.header, DefaultComponent: AgentHeader_default }),
1640
+ /* @__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
+ common.shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(
1642
+ common.RenderWrapper,
1643
+ {
1644
+ control: configState.layout.messageList,
1645
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(BubbleListItems_default, { avatar: { user: false, assistant: true } })
1646
+ }
1647
+ ) }),
1648
+ /* @__PURE__ */ jsxRuntime.jsx(
1649
+ common.RenderWrapper,
1650
+ {
1651
+ control: configState.layout.senderHeader,
1652
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default3.nsChatTitle, children: [
1653
+ "\u6211\u662F ",
1654
+ agentState.active.name
1655
+ ] })
1656
+ }
1657
+ ),
1658
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, gap: 8, children: [
1659
+ /* @__PURE__ */ jsxRuntime.jsx(
1660
+ common.RenderWrapper,
1661
+ {
1662
+ control: configState.layout.senderPrompts,
1663
+ DefaultComponent: SenderPromptsItems_default
1664
+ }
1665
+ ),
1666
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.sender, DefaultComponent: ChatSender_default2 })
1667
+ ] }),
1668
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.senderFooter, DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}) })
1669
+ ] }) })
1670
+ ] }) })
1671
+ ] }) }) }) }) });
1672
+ });
1673
+
1674
+ exports.AgentChat = layouts_default;
1675
+ //# sourceMappingURL=index.cjs.js.map
1676
+ //# sourceMappingURL=index.cjs.js.map