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