@zero-library/chat-agent 2.0.10 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -7,14 +7,14 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
  var react = require('react');
8
8
  var icons = require('@ant-design/icons');
9
9
  var x = require('@ant-design/x');
10
- var classNames6 = require('classnames');
10
+ var classNames7 = require('classnames');
11
11
  var valtio = require('valtio');
12
12
  var InfiniteScroll = require('react-infinite-scroll-component');
13
13
 
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
15
 
16
16
  var dayjs__default = /*#__PURE__*/_interopDefault(dayjs);
17
- var classNames6__default = /*#__PURE__*/_interopDefault(classNames6);
17
+ var classNames7__default = /*#__PURE__*/_interopDefault(classNames7);
18
18
  var InfiniteScroll__default = /*#__PURE__*/_interopDefault(InfiniteScroll);
19
19
 
20
20
  var __defProp = Object.defineProperty;
@@ -56,13 +56,7 @@ function transform(source, fieldMap) {
56
56
  function transforms(sources, fieldMap) {
57
57
  return sources?.map((source) => transform(source, fieldMap)) || [];
58
58
  }
59
- function buildURLWithParams(url, params) {
60
- const query = new URLSearchParams(
61
- Object.entries(params || {}).flatMap(([key, val]) => Array.isArray(val) ? val.map((v) => [key, String(v)]) : [[key, String(val)]])
62
- ).toString();
63
- return query ? `${url}${url.includes("?") ? "&" : "?"}${query}` : url;
64
- }
65
- var copy, classifyTime, getBase64;
59
+ var copy, classifyTime;
66
60
  var init_utils = __esm({
67
61
  "src/core/utils.ts"() {
68
62
  copy = (value) => {
@@ -87,28 +81,20 @@ var init_utils = __esm({
87
81
  return "\u66F4\u65E9";
88
82
  }
89
83
  };
90
- getBase64 = (file) => {
91
- return new Promise((resolve, reject) => {
92
- const reader = new FileReader();
93
- reader.onload = () => resolve(reader.result);
94
- reader.onerror = reject;
95
- reader.readAsDataURL(file);
96
- });
97
- };
98
84
  }
99
85
  });
100
86
  var ChatProvider, useChatStore;
101
87
  var init_Context = __esm({
102
88
  "src/stores/Context.ts"() {
103
- ({ ValtioProvider: ChatProvider, useValtioStore: useChatStore } = common.createValtioContext());
89
+ ({ ValtioProvider: ChatProvider, useValtioStore: useChatStore } = common.useCreateValtioContext());
104
90
  }
105
91
  });
106
92
 
107
93
  // src/ui/common/markdownAlert/styles.module.less
108
- var styles_module_default2;
94
+ var styles_module_default;
109
95
  var init_styles_module = __esm({
110
96
  "src/ui/common/markdownAlert/styles.module.less"() {
111
- styles_module_default2 = {
97
+ styles_module_default = {
112
98
  appCard: "styles_module_appCard",
113
99
  fileView: "styles_module_fileView",
114
100
  fileEdit: "styles_module_fileEdit",
@@ -133,9 +119,9 @@ var init_AppCard = __esm({
133
119
  AppCard_default = ({ data, loading }) => {
134
120
  const chatStore = useChatStore();
135
121
  const onClick = () => {
136
- chatStore.switchAgent({ appKey: data.appKey, agentKey: data.agentKey, isVerify: true });
122
+ chatStore.switchAgentConversation(`${data.appKey}:${data.agentKey}`);
137
123
  };
138
- 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: [
124
+ 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_default.appCard, onClick, children: [
139
125
  /* @__PURE__ */ jsxRuntime.jsx("img", { src: data.iconUrl }),
140
126
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.appName, children: data.appName })
141
127
  ] }) });
@@ -158,7 +144,7 @@ var init_FileView = __esm({
158
144
  const onClick = () => {
159
145
  chatStore.setPreview(data, false);
160
146
  };
161
- 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: [
147
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", className: styles_module_default.fileView, onClick, children: [
162
148
  /* @__PURE__ */ jsxRuntime.jsx(common.FileIcon, { suffix: data.suffix }),
163
149
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
164
150
  ] }) });
@@ -236,7 +222,7 @@ var init_MdEdit = __esm({
236
222
  react.useEffect(() => {
237
223
  setValue(data.content);
238
224
  }, [data.content]);
239
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default2.mdEdit, children: [
225
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default.mdEdit, children: [
240
226
  /* @__PURE__ */ jsxRuntime.jsx(common.MarkdownEditor, { disabled: loading, value, onChange: setValue, showToolbar: false }),
241
227
  !loading && /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "end", className: "m-t-16", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "primary", variant: "outlined", onClick: onOk, children: "\u786E\u8BA4\u63D0\u7EB2\u601D\u8DEF\uFF0C\u5F00\u59CB\u5199\u4F5C" }) })
242
228
  ] });
@@ -260,8 +246,8 @@ var init_FileEdit = __esm({
260
246
  const onPreview = () => {
261
247
  chatStore.setPreview(data, true);
262
248
  };
263
- return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: styles_module_default2.fileEdit, children: [
264
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", justify: "space-between", className: styles_module_default2.fileEditHeader, children: [
249
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: styles_module_default.fileEdit, children: [
250
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", justify: "space-between", className: styles_module_default.fileEditHeader, children: [
265
251
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", className: "flex-1", children: [
266
252
  /* @__PURE__ */ jsxRuntime.jsx(common.FileIcon, { suffix: "md", fontSize: 18 }),
267
253
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
@@ -271,7 +257,7 @@ var init_FileEdit = __esm({
271
257
  /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CopyOutlined, {}), onClick: () => copy(data.content), children: "\u590D\u5236" })
272
258
  ] }) })
273
259
  ] }),
274
- /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { gap: 8, align: "center", className: styles_module_default2.fileEditContent, children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: data.content }) })
260
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { gap: 8, align: "center", className: styles_module_default.fileEditContent, children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: data.content }) })
275
261
  ] });
276
262
  };
277
263
  }
@@ -303,7 +289,7 @@ var init_QuoteList = __esm({
303
289
  /* @__PURE__ */ jsxRuntime.jsx(
304
290
  antd.Collapse,
305
291
  {
306
- className: styles_module_default2.quoteList,
292
+ className: styles_module_default.quoteList,
307
293
  bordered: false,
308
294
  ghost: true,
309
295
  expandIcon: ({ isActive }) => /* @__PURE__ */ jsxRuntime.jsx(icons.CaretRightOutlined, { rotate: isActive ? 90 : 0 }),
@@ -325,171 +311,58 @@ var init_QuoteList = __esm({
325
311
  // src/ui/layouts/index.tsx
326
312
  init_file();
327
313
 
328
- // src/core/constants.ts
329
- var DEFAULT_NEW_CONV_ID = "newConvId";
330
- var ChatRoleMap = {
331
- 1: "user",
332
- 2: "assistant"
333
- };
334
-
335
314
  // src/stores/index.ts
336
315
  init_utils();
337
-
338
- // src/core/fetchRequest.ts
339
- init_utils();
340
- function processChunk(chunk, onChunk) {
341
- if (onChunk) {
342
- onChunk(typeof chunk === "string" ? chunk : JSON.stringify(chunk));
343
- }
344
- }
345
- function parseBuffer(buffer, onChunk) {
346
- let bufferF = buffer;
347
- let jsonStartIndex = bufferF.indexOf("{");
348
- let jsonEndIndex = -1;
349
- while (jsonStartIndex !== -1) {
350
- let braceCount = 0;
351
- let inString = false;
352
- for (let i = jsonStartIndex; i < bufferF.length; i++) {
353
- const char = bufferF[i];
354
- if (char === '"' && bufferF[i - 1] !== "\\") {
355
- inString = !inString;
356
- }
357
- if (!inString) {
358
- if (char === "{") braceCount++;
359
- if (char === "}") braceCount--;
360
- }
361
- if (braceCount === 0) {
362
- jsonEndIndex = i;
363
- break;
364
- }
365
- }
366
- if (jsonEndIndex !== -1) {
367
- const jsonString = bufferF.slice(jsonStartIndex, jsonEndIndex + 1);
368
- try {
369
- const parsed = JSON.parse(jsonString);
370
- processChunk(parsed, onChunk);
371
- } catch (e) {
372
- console.warn("Failed to parse JSON chunk:", jsonString);
373
- }
374
- bufferF = bufferF.slice(jsonEndIndex + 1).trim();
375
- jsonStartIndex = bufferF.indexOf("{");
376
- jsonEndIndex = -1;
377
- } else {
378
- break;
379
- }
380
- }
381
- return bufferF;
382
- }
383
- async function handleHttpError(status, message4) {
384
- const error = new Error(`${status}: ${message4}`);
385
- console.error("request error:", error);
386
- await antd.message.error("\u670D\u52A1\u5668\u5F00\u5C0F\u5DEE\u5566~\u{1F616}");
387
- }
388
- async function handleStreamResponse(response, options) {
389
- const { onChunk } = options;
390
- const reader = response.body.getReader();
391
- const decoder = new TextDecoder();
392
- let buffer = "";
393
- while (true) {
394
- const { done, value } = await reader.read();
395
- if (done) {
396
- buffer = parseBuffer(buffer, onChunk);
397
- break;
398
- }
399
- buffer += decoder.decode(value, { stream: true });
400
- buffer = parseBuffer(buffer, onChunk);
401
- }
402
- }
403
- async function request2(url, data = {}, options = {}) {
404
- const { stream = false, method = "POST", headers = {}, signal } = options;
405
- const controller = new AbortController();
406
- signal?.addEventListener("abort", () => controller.abort());
407
- let targetURL = "/api" + url;
408
- let body = data;
409
- if (method === "GET") {
410
- targetURL = buildURLWithParams(targetURL, data);
411
- body = void 0;
412
- } else {
413
- if (!(body instanceof FormData)) {
414
- headers["Content-Type"] = "application/json";
415
- body = JSON.stringify(body);
416
- }
417
- }
418
- const response = await fetch(targetURL, {
419
- method,
420
- headers: {
421
- ...common.getToken() && { [common.TOKEN_KEY]: common.getToken() },
422
- ...headers
423
- },
424
- body,
425
- signal: controller.signal
426
- });
427
- if (!response.ok) {
428
- const message4 = await response.text();
429
- return await handleHttpError(response.status, message4);
430
- }
431
- if (stream && response.body) {
432
- return handleStreamResponse(response, options);
433
- }
434
- const r = await response.json();
435
- if (r.code !== 200) {
436
- return await handleHttpError(r.code, r.message);
437
- }
438
- return r;
439
- }
440
- var get = (url, params = {}, options = {}) => request2(url, params, { ...options, method: "GET" });
441
- var post = (url, data = {}, options = {}) => request2(url, data, { ...options, method: "POST" });
442
- var put = (url, data = {}, options = {}) => request2(url, data, { ...options, method: "PUT" });
443
- var del = (url, data = {}, options = {}) => request2(url, data, { ...options, method: "DELETE" });
444
- var fetchRequest_default = { delete: del, get, post, put };
445
-
446
- // src/services/index.ts
447
- var agentInfoQuery = (agentId) => {
448
- return common.request.get("/agent/detail", { agentId });
316
+ var conversationsQuery = (params) => {
317
+ return common.request.get("/lolr/conversation", params);
449
318
  };
450
- var agentsQuery = () => {
451
- return common.request.get("/agent");
319
+ var conversationCreate = (params) => {
320
+ return common.request.post("/lolr/conversation", params);
452
321
  };
453
- var conversationsQuery = (params) => {
454
- return common.request.get("/agent/conversation", params);
322
+ var conversationDelete = (conversationId) => {
323
+ return common.request.delete("/agent/conversation", { conversationId });
455
324
  };
456
- var deleteConversation = (params) => {
457
- return common.request.delete("/agent/conversation", params);
325
+ var conversationRecentQuery = (params) => {
326
+ return common.request.get("/lolr/conversation/recent", params);
458
327
  };
459
- var chatMessagesQuery = (params) => {
460
- return common.request.get("/agent/message", params);
328
+ var conversationMessagesQuery = (params) => {
329
+ return common.request.get("/lolr/conversation/message", params);
461
330
  };
462
- var chatMessageSuggestedQuery = (agentId, messageId) => {
463
- return common.request.get("/agent/message/suggested", { agentId, messageId });
331
+ var feedbackUpdate = (params) => {
332
+ return common.request.put("/lolr/conversation/message/feedback", params);
464
333
  };
465
- var updateFeedback = (params) => {
466
- return common.request.put("/agent/message/feedback", params);
334
+ var messageSuggestedQuery = (msgId, maxCount = 3) => {
335
+ return common.request.get("/lolr/conversation/suggest", { msgId, maxCount });
467
336
  };
468
- var uploadFile = (formData) => {
469
- return common.request.post("/agent/file", formData);
337
+ var conversationMemberQuery = (conversationId) => {
338
+ return common.request.get("/lolr/conversation/member", { conversationId });
470
339
  };
471
- var sendChatMessage = (params) => {
472
- return fetchRequest_default.post(
473
- "/agent/chat",
474
- { ...params, stream: true },
475
- {
476
- stream: true,
477
- onChunk: (chunk) => {
478
- if (params.onMessageEvent) {
479
- const event = JSON.parse(chunk);
480
- params.onMessageEvent(event);
481
- }
482
- }
483
- }
484
- );
340
+ var conversationMessageSend = (params) => {
341
+ return common.request.post("/lolr/conversation/send", params);
342
+ };
343
+ var conversationStop = (conversationId) => {
344
+ return common.request.post("/lolr/conversation/stop", { conversationId });
345
+ };
346
+ var agentInfoQuery = (agentId) => {
347
+ return common.request.get("/lolr/agent/detail", { agentId });
348
+ };
349
+ var agentCharacterQuery = (agentId) => {
350
+ return common.request.get("/lolr/character", { agentId });
351
+ };
352
+ var agentCharacterSelect = (agentId, characterId) => {
353
+ return common.request.post("/lolr/character/user", { agentId, characterId });
354
+ };
355
+ var fileUpload = (formData) => {
356
+ return common.request.post("/lolr/storage/upload", formData, { timeout: 5 * 60 * 1e3 });
485
357
  };
486
358
 
487
359
  // src/stores/index.ts
488
- var defaultLayout = {
360
+ var defaultAgentLayout = {
489
361
  leftPanel: false,
490
362
  conversationList: true,
491
363
  preview: true,
492
364
  messageList: true,
365
+ firstMessage: false,
493
366
  senderHeader: false,
494
367
  sender: true,
495
368
  senderPrompts: true,
@@ -498,6 +371,28 @@ var defaultLayout = {
498
371
  chatHeader: true,
499
372
  disclaimerNotice: true
500
373
  };
374
+ var defaultExpertLayout = {
375
+ leftPanel: false,
376
+ conversationList: false,
377
+ preview: false,
378
+ messageList: true,
379
+ firstMessage: false,
380
+ senderHeader: false,
381
+ sender: true,
382
+ senderPrompts: false,
383
+ senderFooter: false,
384
+ globalHeader: false,
385
+ chatHeader: {
386
+ props: {
387
+ title: true,
388
+ closeBtn: false,
389
+ newConversationBtn: false,
390
+ agentCharacter: false,
391
+ conversationListBtn: false
392
+ }
393
+ },
394
+ disclaimerNotice: false
395
+ };
501
396
  function createChatStore() {
502
397
  const config = valtio.proxy({
503
398
  hooks: {},
@@ -526,492 +421,487 @@ function createChatStore() {
526
421
  }
527
422
  }
528
423
  };
529
- const setLayout = (layout) => {
424
+ const setLayout = (layout, receiverType = 3) => {
425
+ const defaultLayout = receiverType === 3 ? defaultAgentLayout : defaultExpertLayout;
530
426
  config.layout = common.deepMerge(defaultLayout, layout);
531
427
  };
532
428
  const setConfigParams = (params = {}) => {
533
- config.params = { bizId: "", ...params };
429
+ config.params = { ...params };
534
430
  };
535
431
  const setHooks = (hooks = {}) => {
536
432
  config.hooks = hooks;
537
433
  };
538
- const getUserInfo = () => {
539
- config.userInfo = transform(common.getCurrentUser(), {
540
- id: "id",
434
+ const setUserInfo = (userInfo) => {
435
+ config.userInfo = transform(userInfo || common.getCurrentUser(), {
436
+ id: (userInfo2) => {
437
+ return String(userInfo2["id"]);
438
+ },
541
439
  name: "name",
542
440
  iconUrl: "avatar",
543
441
  description: "name"
544
442
  });
545
443
  };
546
- const agents = valtio.proxy({
547
- // 商品列表
444
+ const receiver = valtio.proxy({
445
+ active: {},
446
+ loading: false,
447
+ params: {}
448
+ // 透传参数,后期可能扩展不透传参数
449
+ });
450
+ const setReceiverParams = (params) => {
451
+ if (common.isObject(params)) {
452
+ Object.assign(receiver.params, params);
453
+ } else {
454
+ receiver.params = {};
455
+ }
456
+ };
457
+ const switchAgent = async (agentId) => {
458
+ if (receiver.active.id === agentId) return;
459
+ const canProceed = await config.hooks?.onBeforeSwitchAgent?.(agentId);
460
+ if (canProceed === false) return;
461
+ try {
462
+ receiver.loading = true;
463
+ const { data } = await agentInfoQuery(agentId);
464
+ receiver.active = transform(data, {
465
+ name: "agentName",
466
+ logo: "logo",
467
+ description: "description",
468
+ id: "id",
469
+ config: "config",
470
+ isAvailable: "isAvailable",
471
+ feature: (agentInfo) => {
472
+ if (agentInfo.feature) {
473
+ try {
474
+ return JSON.parse(agentInfo.feature);
475
+ } catch (e) {
476
+ }
477
+ }
478
+ return {};
479
+ }
480
+ });
481
+ receiver.active.type = 3;
482
+ setReceiverParams();
483
+ if (receiver.active.feature?.deepThink) {
484
+ setReceiverParams({ thinkMode: "2" });
485
+ }
486
+ config.hooks?.onAfterSwitchAgent?.(agentId);
487
+ } finally {
488
+ receiver.loading = false;
489
+ }
490
+ };
491
+ const switchExpert = (expert) => {
492
+ if (receiver.active.id === expert.memberId) return;
493
+ receiver.active = transform(expert, {
494
+ name: "memberName",
495
+ logo: "memberAvatar",
496
+ id: "memberId"
497
+ });
498
+ receiver.active.type = 2;
499
+ setReceiverParams();
500
+ };
501
+ const character = valtio.proxy({
548
502
  list: [],
549
- loading: false
503
+ active: {},
504
+ open: false,
505
+ loading: false,
506
+ switchLoading: false
550
507
  });
551
- const getAgentList = async () => {
508
+ const getCharacters = async (agentId) => {
509
+ try {
510
+ character.loading = true;
511
+ const res = await agentCharacterQuery(agentId);
512
+ if (receiver.active.id !== agentId) return;
513
+ character.list = res.data;
514
+ character.active = res.data.find((item) => item.selected);
515
+ } finally {
516
+ character.loading = false;
517
+ }
518
+ };
519
+ const openCharacterList = () => {
520
+ character.open = true;
521
+ };
522
+ const closeCharacterList = () => {
523
+ character.open = false;
524
+ };
525
+ const switchCharacter = async (c) => {
526
+ if (!c.id) return;
552
527
  try {
553
- agents.loading = true;
554
- const { data } = await agentsQuery();
555
- agents.list = data;
528
+ character.switchLoading = true;
529
+ await agentCharacterSelect(receiver.active.id, c.id);
530
+ character.active = { ...c };
531
+ closeCharacterList();
556
532
  } finally {
557
- agents.loading = false;
533
+ character.switchLoading = false;
534
+ }
535
+ };
536
+ const conversations = valtio.proxy({
537
+ list: {
538
+ items: [],
539
+ params: {
540
+ pageNum: 1,
541
+ pageSize: 1e3
542
+ }
543
+ },
544
+ updateIndex: 0,
545
+ // 当前会话索引, 创建会话时更新,促使页面更新会话列表
546
+ loading: false,
547
+ delLoading: false
548
+ });
549
+ const getConversations = async (targetId, targetType) => {
550
+ try {
551
+ conversations.loading = true;
552
+ const { data } = await conversationsQuery({
553
+ targetId,
554
+ targetType,
555
+ businessId: config.params.businessId,
556
+ businessType: config.params.businessType,
557
+ ...conversations.list.params
558
+ });
559
+ if (receiver.active.id !== targetId) return;
560
+ const items = transforms(data?.items || [], {
561
+ key: "id",
562
+ id: "id",
563
+ label: "title",
564
+ group: (c) => {
565
+ return classifyTime(c.updateTime);
566
+ },
567
+ timestamp: "updateTime"
568
+ });
569
+ conversations.list.items = items;
570
+ } finally {
571
+ conversations.loading = false;
572
+ }
573
+ };
574
+ const delConversation = async (conversationId) => {
575
+ try {
576
+ const canProceed = await config.hooks?.onBeforeDelConversation?.(conversationId);
577
+ if (canProceed === false) return;
578
+ conversations.delLoading = true;
579
+ await conversationDelete(conversationId);
580
+ antd.message.success("\u5220\u9664\u6210\u529F");
581
+ conversations.list.items = conversations.list.items.filter((item) => item.key !== conversationId);
582
+ delete conversation.messages[conversationId];
583
+ if (conversation.active.id === conversationId) {
584
+ createAgentConversation();
585
+ }
586
+ config.hooks?.onAfterDelConversation?.(conversationId, conversation.active.id === conversationId);
587
+ } finally {
588
+ conversations.delLoading = false;
558
589
  }
559
590
  };
560
591
  const conversation = valtio.proxy({
561
592
  // 每个会话单独存储
562
- active: {},
563
- messages: {}
564
- // feedback: {
565
- // open: false,
566
- // loading: false,
567
- // recordId: '',
568
- // target: undefined as number | undefined
569
- // }
593
+ active: {
594
+ id: "",
595
+ member: {}
596
+ },
597
+ messages: {},
598
+ feedback: {
599
+ // open: false,
600
+ loading: false
601
+ // recordId: '',
602
+ // target: undefined as number | undefined
603
+ }
570
604
  });
605
+ const setSpeakHuman = (speakHuman) => {
606
+ conversation.messages[conversation.active.id].speakHuman = speakHuman;
607
+ };
571
608
  const setReferences = (references) => {
572
- conversation.messages[conversation.active.key].references = references;
609
+ conversation.messages[conversation.active.id].references = references;
573
610
  };
574
611
  const setContent = (content) => {
575
- conversation.messages[conversation.active.key].content = content;
612
+ conversation.messages[conversation.active.id].content = content;
576
613
  };
577
614
  const setFileList = (files = []) => {
578
- conversation.messages[conversation.active.key].files = files;
615
+ conversation.messages[conversation.active.id].files = files;
579
616
  };
580
617
  const setHeaderOpen = (headerOpen) => {
581
- conversation.messages[conversation.active.key].headerOpen = headerOpen;
618
+ conversation.messages[conversation.active.id].headerOpen = headerOpen;
582
619
  };
583
- const removeQuestionList = (key) => {
584
- if (conversation.messages[key].questionList?.length) {
585
- conversation.messages[key].questionList = [];
620
+ const removeQuestionList = (conversationId) => {
621
+ if (conversation.messages[conversationId].questionList?.length) {
622
+ conversation.messages[conversationId].questionList = [];
586
623
  }
587
624
  };
588
- const getQuestionList = async (conversationId, message4) => {
589
- if (!message4.id || !message4.content) return;
590
- const { data } = await chatMessageSuggestedQuery(agent.active.id, message4.id);
625
+ const getQuestionList = async (conversationId, messageId) => {
626
+ const messages = conversation.messages[conversationId]?.message;
627
+ if (!messages?.length) return;
628
+ let lastMessage = messages[messages.length - 1];
629
+ if (!lastMessage || lastMessage.sender.type !== 3 || lastMessage.id !== messageId) return;
630
+ const { data } = await messageSuggestedQuery(messageId);
631
+ lastMessage = messages[messages.length - 1];
632
+ if (lastMessage.id !== messageId) return;
591
633
  conversation.messages[conversationId].questionList = data;
592
634
  };
593
- const feedback = async (conversationId, messageId, rating, index) => {
635
+ const feedback = async (conversationId, messageId, msgFeedback, index) => {
594
636
  try {
595
- await updateFeedback({ agentId: agent.active.id, messageId, rating, bizId: config.params.bizId });
596
- conversation.messages[conversationId].message.items[index].feedback = rating;
637
+ conversation.feedback.loading = true;
638
+ await feedbackUpdate({ conversationId, id: messageId, msgFeedback });
639
+ antd.message.success("\u611F\u8C22\u60A8\u7684\u53CD\u9988");
640
+ conversation.messages[conversationId].message[index].msgFeedback = msgFeedback;
597
641
  } finally {
642
+ conversation.feedback.loading = false;
598
643
  }
599
644
  };
600
- const conversations = valtio.proxy({
601
- list: {
602
- items: [],
603
- lastId: "",
604
- hasMore: false
605
- },
606
- loading: false,
607
- delLoading: false
608
- });
609
- const setInitMessage = async (key) => {
610
- conversation.messages[key] = {
645
+ const setInitMessage = async (conversationId) => {
646
+ conversation.messages[conversationId] = {
611
647
  content: "",
612
648
  files: [],
613
649
  // 上传文件内容
614
650
  headerOpen: false,
615
651
  loading: false,
616
- message: {
617
- lastId: "",
618
- hasMore: false,
619
- items: []
620
- },
652
+ message: [],
621
653
  questionList: []
622
654
  // 推荐问题
623
655
  };
624
656
  };
625
- const agent = valtio.proxy({
626
- active: {},
627
- loading: false,
628
- params: {}
629
- });
630
- const setAgentParams = (params = {}) => {
631
- agent.params = {
632
- thinkMode: "2",
633
- ...params
634
- };
635
- };
636
- const switchAgent = async ({ appKey, agentKey, isVerify = false }, conversationId) => {
637
- const agentId = `${appKey}:${agentKey}`;
638
- if (agent.active.id === agentId) return;
639
- const canProceed = await config.hooks?.onBeforeSwitchAgent?.(agentId);
640
- if (canProceed === false) return;
641
- try {
642
- agent.loading = true;
643
- if (isVerify) {
644
- }
645
- const { data } = await agentInfoQuery(agentId);
646
- agent.active = data;
647
- setAgentParams();
648
- config.hooks?.onAfterSwitchAgent?.(agentId);
649
- switchConversation({ key: conversationId });
650
- } finally {
651
- agent.loading = false;
652
- }
653
- };
654
- const switchConversation = async (chat) => {
655
- const chatKey = chat?.key || `${agent.active.id}-${DEFAULT_NEW_CONV_ID}`;
656
- if (conversation.active.key === chatKey) return;
657
- const isNew = !chat?.key;
658
- const canProceed = await config.hooks?.onBeforeSwitchConversation?.(chatKey, isNew);
659
- if (canProceed === false) return;
660
- conversation.active = chat?.key ? chat : { key: chatKey };
661
- setPreview();
662
- if (!conversation.messages[chatKey]) {
663
- setInitMessage(chatKey);
664
- }
665
- config.hooks?.onAfterSwitchConversation?.(chatKey, isNew);
666
- if (!isNew && conversation.messages[chatKey].message.items.length === 0) {
667
- getMessages(agent.active.id, chatKey);
657
+ const resolveConversationId = async (receiverId, strategy = 2) => {
658
+ if (strategy === 1) {
659
+ const { data } = await conversationRecentQuery({
660
+ receiverId: String(receiverId),
661
+ receiverType: 3,
662
+ businessId: config.params.businessId,
663
+ businessType: config.params.businessType
664
+ });
665
+ return data;
666
+ } else {
667
+ const { data } = await conversationCreate({
668
+ receiverId: String(receiverId),
669
+ receiverType: 3,
670
+ businessId: config.params.businessId,
671
+ businessType: config.params.businessType,
672
+ businessData: config.params.businessData,
673
+ source: config.params.source,
674
+ type: 1
675
+ });
676
+ conversations.updateIndex = conversations.updateIndex + 1;
677
+ return data;
668
678
  }
669
679
  };
670
- const getConversations = async (agentId, lastId, limit = 20) => {
680
+ const initConversation = async (conversationId) => {
671
681
  try {
672
- conversations.loading = true;
673
- const { data } = await conversationsQuery({ bizId: config.params.bizId, agentId, lastId, limit });
674
- if (agent.active.id !== agentId) return;
675
- const items = transforms(data?.items || [], {
676
- key: "id",
677
- label: "name",
678
- group: (c) => {
679
- return classifyTime(c.createTime);
680
- },
681
- timestamp: "createTime"
682
+ const { data } = await conversationMemberQuery(conversationId);
683
+ conversation.active = { id: conversationId, member: {} };
684
+ data.forEach((member) => {
685
+ if (member.memberType === 3) {
686
+ conversation.active.member.agent = member;
687
+ } else {
688
+ if (member.memberId === config.userInfo.id) {
689
+ conversation.active.member.user = member;
690
+ } else {
691
+ conversation.active.member.other = member;
692
+ }
693
+ }
682
694
  });
683
- conversations.list = {
684
- ...data,
685
- items: lastId ? [...conversations.list.items, ...items] : items
686
- };
687
695
  } finally {
688
- conversations.loading = false;
689
696
  }
690
697
  };
691
- const getMessages = async (agentId, conversationId, lastId) => {
698
+ const switchAgentConversation = async (agentId, strategy) => {
699
+ await switchAgent(agentId);
700
+ const conversationId = await resolveConversationId(agentId, strategy);
692
701
  if (conversationId) {
693
- if (!conversationId.endsWith(DEFAULT_NEW_CONV_ID)) {
694
- try {
695
- const { data } = await chatMessagesQuery({
696
- bizId: config.params.bizId,
697
- agentId,
698
- conversationId,
699
- lastId
700
- // limit
701
- });
702
- const messageList = transforms(data?.items || [], {
703
- id: "messageId",
704
- role: (msg) => ChatRoleMap[msg.role],
705
- content: "message",
706
- files: "files",
707
- feedback: "feedback",
708
- status: "success"
709
- });
710
- conversation.messages[conversationId].message = {
711
- ...data,
712
- items: lastId ? [...messageList, ...conversation.messages[conversationId].message.items] : messageList
713
- };
714
- } finally {
715
- }
716
- }
702
+ switchConversation(conversationId);
717
703
  }
718
704
  };
719
- const delConversation = async (chat) => {
720
- try {
721
- conversations.delLoading = true;
722
- await deleteConversation({ agentId: agent.active.id, conversationId: chat.key, bizId: config.params.bizId });
723
- antd.message.success("\u5220\u9664\u6210\u529F");
724
- conversations.list.items = conversations.list.items.filter((item) => item.key !== chat.key);
725
- if (conversation.active.key === chat.key) {
726
- conversation.active = {
727
- key: `${agent.active.id}-${DEFAULT_NEW_CONV_ID}`
728
- };
729
- }
730
- delete conversation.messages[chat.key];
731
- } finally {
732
- conversations.delLoading = false;
705
+ const createAgentConversation = async () => {
706
+ const conversationId = await resolveConversationId(receiver.active.id);
707
+ if (conversationId) {
708
+ switchConversation(conversationId);
733
709
  }
734
710
  };
735
- const removePlaceholder = (key, msgId) => {
736
- if (conversation.messages[key]) {
737
- const index = conversation.messages[key].message.items.findLastIndex((m) => m.id === msgId);
738
- if (index !== -1) {
739
- conversation.messages[key].message.items.splice(index, 1);
740
- }
711
+ const switchConversation = async (conversationId) => {
712
+ if (conversation.active.id === conversationId) return;
713
+ const canProceed = await config.hooks?.onBeforeSwitchConversation?.(conversationId);
714
+ if (canProceed === false) return;
715
+ await initConversation(conversationId);
716
+ setPreview();
717
+ config.hooks?.onAfterSwitchConversation?.(conversationId);
718
+ getMessages(conversationId);
719
+ if (conversation.active.member.agent) {
720
+ switchAgent(conversation.active.member.agent.memberId);
721
+ } else if (conversation.active.member.other) {
722
+ switchExpert(conversation.active.member.other);
741
723
  }
742
724
  };
743
- const updatePlaceholderMessage = (key, msgId, chunk) => {
744
- if (chunk.conversationId && chunk.conversationId !== key && !conversation.messages[chunk.conversationId]) {
745
- conversation.messages[chunk.conversationId] = conversation.messages[key];
746
- delete conversation.messages[key];
747
- if (key === conversation.active.key) {
748
- conversation.active = {
749
- key: chunk.conversationId
750
- };
751
- }
752
- if (key.startsWith(agent.active.id)) {
753
- getConversations(agent.active.id);
754
- }
755
- }
756
- let placeholder = {};
757
- if (conversation.messages[chunk.conversationId]) {
758
- placeholder = conversation.messages[chunk.conversationId].message.items.findLast((m) => m.id === msgId);
759
- } else if (conversation.messages[key]) {
760
- placeholder = conversation.messages[key].message.items.findLast((m) => m.id === msgId);
761
- }
762
- if (!placeholder) return;
763
- if (chunk.type === "TEXT_MESSAGE_CONTENT") {
764
- const textEvent = chunk;
765
- placeholder.content += textEvent.message;
766
- return;
767
- }
768
- if (chunk.type === "TEXT_MESSAGE_END") {
769
- const textEvent = chunk;
770
- placeholder.id = textEvent.messageId;
771
- placeholder.status = "success";
725
+ const getMessages = async (conversationId) => {
726
+ const canProceed = await config.hooks?.onBeforeInitMessages?.(conversationId);
727
+ if (canProceed === false) return;
728
+ if (!conversation.messages[conversationId]) {
729
+ setInitMessage(conversationId);
772
730
  }
773
- if (chunk.type === "RUN_ERROR") {
774
- const textEvent = chunk;
775
- placeholder.status = "error";
776
- placeholder.content = textEvent.message;
777
- } else if (chunk.code && chunk.code !== common.OK) {
778
- removePlaceholder(key, msgId);
731
+ if (conversation.messages[conversationId].message.length === 0) {
732
+ try {
733
+ const { data } = await conversationMessagesQuery({
734
+ pageNo: 1,
735
+ pageSize: 1e3,
736
+ conversationId
737
+ });
738
+ conversation.messages[conversationId].message = data.items;
739
+ } finally {
740
+ }
741
+ config.hooks?.onAfterInitMessages?.(conversation.messages[conversationId].message);
779
742
  }
780
- conversation.messages[chunk.conversationId].loading = false;
781
743
  };
782
- const sendMessage = async (message4, files = [], params) => {
783
- const conversationId = conversation.active.key;
744
+ const pickReceiver = () => {
745
+ const { agent, other } = conversation.active.member;
746
+ if (conversation.messages[conversation.active.id].speakHuman && other) return other;
747
+ if (agent) return agent;
748
+ if (other) return other;
749
+ return void 0;
750
+ };
751
+ const sendMessage = async (message3, files = [], params) => {
752
+ const conversationId = conversation.active.id;
784
753
  if (conversation.messages[conversationId].loading) return;
785
- let newMsgContent = "", newImgList;
754
+ let msgContent = "", msgFiles;
786
755
  const references = conversation.messages[conversationId].references;
787
- if (message4) {
788
- newMsgContent = message4;
789
- newImgList = files;
756
+ if (message3) {
757
+ msgContent = message3;
758
+ msgFiles = files;
790
759
  } else {
791
760
  if (references?.type === 1 && references?.content?.markdown) {
792
- newMsgContent = references.content.markdown + "\n";
761
+ msgContent = references.content.markdown + "\n";
793
762
  }
794
- newMsgContent = newMsgContent + conversation.messages[conversationId].content;
795
- newImgList = conversation.messages[conversationId].files;
763
+ msgContent = msgContent + conversation.messages[conversationId].content;
764
+ msgFiles = conversation.messages[conversationId].files;
796
765
  }
797
- if (!newMsgContent) return;
798
- const canProceed = await config.hooks?.onBeforeSend?.(newMsgContent, newImgList);
766
+ if (!msgContent) return;
767
+ const canProceed = await config.hooks?.onBeforeSend?.(msgContent, msgFiles);
799
768
  if (canProceed === false) return;
800
769
  conversation.messages[conversationId].loading = true;
801
- const userMsg = {
802
- id: `user-${Date.now()}`,
803
- role: "user",
804
- content: newMsgContent,
805
- files: newImgList,
806
- status: "success"
770
+ const sendReceiver = pickReceiver();
771
+ const sendParams = {
772
+ conversationId,
773
+ msgContent,
774
+ msgFiles,
775
+ // quoteMsgId
776
+ receiverId: sendReceiver.memberId,
777
+ receiverType: sendReceiver.memberType,
778
+ returnType: 2,
779
+ senderId: conversation.active.member.user.memberId,
780
+ senderType: conversation.active.member.user.memberType,
781
+ source: config.params.source,
782
+ stream: true
807
783
  };
808
- const placeholderId = `placeholder-${Date.now()}`;
809
- const placeholder = {
810
- id: placeholderId,
811
- role: "assistant",
812
- content: "",
813
- status: "loading"
814
- };
815
- conversation.messages[conversationId].message.items.push(userMsg, placeholder);
816
- const extraParams = {
817
- ...config.params
818
- };
819
- if (!extraParams.params) {
820
- extraParams.params = {};
821
- }
822
- Object.assign(extraParams.params, agent.params, message4 ? {} : references?.params, params);
823
- if (!message4) {
784
+ const extraParams = common.deepCopy(config.params.params || {});
785
+ Object.assign(extraParams, receiver.params, message3 ? {} : references?.params, params);
786
+ sendParams.params = JSON.stringify(extraParams);
787
+ if (!message3) {
824
788
  setContent("");
825
789
  setFileList([]);
826
790
  setReferences();
827
791
  setHeaderOpen(false);
828
792
  }
829
- removeQuestionList(conversationId);
830
793
  try {
831
- sendChatMessage({
832
- agentId: agent.active.id,
833
- conversationId: conversationId.endsWith(DEFAULT_NEW_CONV_ID) ? void 0 : conversationId,
834
- message: userMsg.content,
835
- files: userMsg.files,
836
- ...extraParams,
837
- onMessageEvent: (event) => {
838
- updatePlaceholderMessage(conversationId, placeholderId, event);
839
- }
840
- });
794
+ await conversationMessageSend(sendParams);
841
795
  config.hooks?.onAfterSend?.();
842
- } catch (error) {
843
- removePlaceholder(conversationId, placeholderId);
796
+ } finally {
844
797
  conversation.messages[conversationId].loading = false;
845
798
  }
846
799
  };
847
- const cancelReceive = () => {
848
- conversation.messages[conversation.active.key].loading = false;
800
+ const cancelReceive = async () => {
801
+ await conversationStop(conversation.active.id);
802
+ };
803
+ const updateConversationTitle = (conversationId, title) => {
804
+ const idx = conversations.list.items.findIndex((item) => item.id === conversationId);
805
+ if (idx === -1) return;
806
+ conversations.list.items[idx].title = title;
807
+ };
808
+ const findMsgIndex = (conversationId, msgId) => {
809
+ const messages = conversation.messages[conversationId]?.message || [];
810
+ return messages.findLastIndex((item) => item.id === msgId);
811
+ };
812
+ const startCallback = (msg) => {
813
+ if (msg.conversationTitle && conversations.list.items.length) {
814
+ updateConversationTitle(msg.conversationId, msg.conversationTitle);
815
+ }
816
+ removeQuestionList(msg.conversationId);
817
+ const messages = conversation.messages[msg.conversationId].message;
818
+ messages.push(msg.sender.type === 3 ? { ...msg, msgContent: "\u6B63\u5728\u52AA\u529B\u601D\u8003\u4E2D" } : msg);
819
+ conversation.messages[msg.conversationId].loading = true;
820
+ };
821
+ const stepCallback = (msg) => {
822
+ const messages = conversation.messages[msg.conversationId].message;
823
+ const idx = findMsgIndex(msg.conversationId, msg.id);
824
+ if (idx === -1) return;
825
+ messages[idx] = msg;
826
+ conversation.messages[msg.conversationId].loading = true;
827
+ };
828
+ const contentCallback = (msg) => {
829
+ const messages = conversation.messages[msg.conversationId].message;
830
+ const idx = findMsgIndex(msg.conversationId, msg.id);
831
+ if (idx === -1) return;
832
+ const message3 = messages[idx];
833
+ conversation.messages[msg.conversationId].loading = true;
834
+ if (message3?.type === "STEP_STARTED" || message3?.type === "TEXT_MESSAGE_START") {
835
+ messages[idx] = msg;
836
+ return;
837
+ }
838
+ messages[idx] = {
839
+ ...message3,
840
+ msgContent: message3.msgContent + (msg.msgContent || "")
841
+ };
842
+ };
843
+ const endCallback = (msg) => {
844
+ const messages = conversation.messages[msg.conversationId].message;
845
+ const idx = findMsgIndex(msg.conversationId, msg.id);
846
+ if (idx === -1) return;
847
+ messages[idx] = { ...messages[idx], type: void 0 };
848
+ conversation.messages[msg.conversationId].loading = false;
849
+ getQuestionList(msg.conversationId, msg.id);
850
+ };
851
+ const acceptMessage = (newMessage) => {
852
+ const conversationId = newMessage.data.conversationId;
853
+ if (!conversation.messages[conversationId]?.message) return;
854
+ switch (newMessage.data.type) {
855
+ case "TEXT_MESSAGE_START":
856
+ startCallback(newMessage.data);
857
+ break;
858
+ case "STEP_STARTED":
859
+ stepCallback(newMessage.data);
860
+ break;
861
+ case "TEXT_MESSAGE_CONTENT":
862
+ contentCallback(newMessage.data);
863
+ break;
864
+ case "TEXT_MESSAGE_END":
865
+ endCallback(newMessage.data);
866
+ break;
867
+ }
849
868
  };
850
869
  return {
851
870
  config,
871
+ setPreview,
852
872
  setLayout,
853
873
  setHooks,
854
874
  setConfigParams,
855
- setPreview,
856
- getUserInfo,
857
- agents,
858
- getAgentList,
875
+ setUserInfo,
876
+ character,
877
+ getCharacters,
878
+ openCharacterList,
879
+ closeCharacterList,
880
+ switchCharacter,
881
+ receiver,
882
+ setReceiverParams,
883
+ conversations,
884
+ getConversations,
885
+ delConversation,
859
886
  conversation,
887
+ setSpeakHuman,
860
888
  setReferences,
861
889
  setContent,
862
890
  setFileList,
863
891
  setHeaderOpen,
864
- removeQuestionList,
865
- getQuestionList,
866
892
  feedback,
867
- conversations,
868
- setInitMessage,
869
- agent,
870
- setAgentParams,
871
- switchAgent,
872
- getConversations,
873
- getMessages,
893
+ switchAgentConversation,
894
+ createAgentConversation,
874
895
  switchConversation,
875
- delConversation,
876
- removePlaceholder,
877
896
  sendMessage,
878
- cancelReceive
897
+ cancelReceive,
898
+ acceptMessage
879
899
  };
880
900
  }
881
901
 
882
902
  // src/ui/layouts/index.tsx
883
903
  init_Context();
884
904
 
885
- // src/ui/common/AgentHeader.tsx
886
- init_Context();
887
-
888
- // src/ui/common/ConversationList.tsx
889
- init_Context();
890
-
891
- // src/ui/common/styles.module.less
892
- var styles_module_default = {
893
- loadingMessage: "styles_module_loadingMessage",
894
- conversationListPanel: "styles_module_conversationListPanel",
895
- nsConversations: "styles_module_nsConversations",
896
- nsBodyWidth: "styles_module_nsBodyWidth",
897
- nsBubbleList: "styles_module_nsBubbleList",
898
- nsAgentHeader: "styles_module_nsAgentHeader",
899
- nsChatTitle: "styles_module_nsChatTitle",
900
- nsChatHeaderPopover: "styles_module_nsChatHeaderPopover",
901
- chatWelcomeWrap: "styles_module_chatWelcomeWrap",
902
- chatWelcome: "styles_module_chatWelcome",
903
- chatWelcomePrompts: "styles_module_chatWelcomePrompts",
904
- senderListTitle: "styles_module_senderListTitle",
905
- senderList: "styles_module_senderList",
906
- senderListItem: "styles_module_senderListItem",
907
- senderListFooter: "styles_module_senderListFooter",
908
- nsChatUserName: "styles_module_nsChatUserName",
909
- nsSenderReferenceHeaderTitle: "styles_module_nsSenderReferenceHeaderTitle",
910
- nsSenderReferenceHeaderContent: "styles_module_nsSenderReferenceHeaderContent"
911
- };
912
- var ConversationList_default = () => {
913
- const chatStore = useChatStore();
914
- const agentState = valtio.useSnapshot(chatStore.agent);
915
- const conversationsState = valtio.useSnapshot(chatStore.conversations);
916
- const conversationState = valtio.useSnapshot(chatStore.conversation);
917
- react.useEffect(() => {
918
- if (agentState.active.id) {
919
- chatStore.getConversations(agentState.active.id);
920
- }
921
- }, [agentState.active.id]);
922
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full scroll-fade-in", id: "scrollableDiv", children: conversationsState.list.items.length ? /* @__PURE__ */ jsxRuntime.jsx(
923
- InfiniteScroll__default.default,
924
- {
925
- dataLength: conversationsState.list.items.length,
926
- next: () => {
927
- console.log("next");
928
- chatStore.getConversations(agentState.active.id, conversationsState.list.lastId);
929
- },
930
- hasMore: conversationsState.list.hasMore,
931
- loader: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { indicator: /* @__PURE__ */ jsxRuntime.jsx(icons.RedoOutlined, { spin: true }), size: "small" }) }),
932
- style: { overflow: "hidden" },
933
- scrollableTarget: "scrollableDiv",
934
- children: /* @__PURE__ */ jsxRuntime.jsx(
935
- x.Conversations,
936
- {
937
- className: styles_module_default.nsConversations,
938
- items: conversationsState.list.items,
939
- activeKey: conversationState.active.key,
940
- onActiveChange: async (key) => chatStore.switchConversation({ key }),
941
- groupable: true,
942
- menu: (conversation) => ({
943
- items: [
944
- {
945
- label: "\u5220\u9664\u4F1A\u8BDD",
946
- key: "delete",
947
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DeleteOutlined, {}),
948
- danger: true,
949
- onClick: (menuInfo) => {
950
- menuInfo.domEvent.stopPropagation();
951
- chatStore.delConversation(conversation);
952
- }
953
- }
954
- ]
955
- })
956
- }
957
- )
958
- }
959
- ) : /* @__PURE__ */ jsxRuntime.jsx(antd.Empty, { description: "\u6682\u65E0\u4F1A\u8BDD\u8BB0\u5F55", image: antd.Empty.PRESENTED_IMAGE_SIMPLE }) }) });
960
- };
961
- var AgentHeader_default = ({ title = true, closeBtn = false, newConversationBtn = true, conversationListBtn = true }) => {
962
- const chatStore = useChatStore();
963
- const agentState = valtio.useSnapshot(chatStore.agent);
964
- const configState = valtio.useSnapshot(chatStore.config);
965
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", className: styles_module_default.nsAgentHeader, children: [
966
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", children: [
967
- /* @__PURE__ */ jsxRuntime.jsx(
968
- common.RenderWrapper,
969
- {
970
- control: title,
971
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
972
- /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 22, src: agentState.active.iconUrl, alt: agentState.active.name }),
973
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default.nsChatTitle, children: agentState.active.name })
974
- ] })
975
- }
976
- ),
977
- " "
978
- ] }),
979
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { size: 0, children: [
980
- /* @__PURE__ */ jsxRuntime.jsx(
981
- common.RenderWrapper,
982
- {
983
- control: newConversationBtn,
984
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}), onClick: () => chatStore.switchConversation() })
985
- }
986
- ),
987
- /* @__PURE__ */ jsxRuntime.jsx(
988
- common.RenderWrapper,
989
- {
990
- control: conversationListBtn,
991
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(
992
- antd.Popover,
993
- {
994
- getPopupContainer: (e) => e,
995
- placement: "bottom",
996
- classNames: { body: styles_module_default.nsChatHeaderPopover },
997
- content: /* @__PURE__ */ jsxRuntime.jsx(ConversationList_default, {}),
998
- trigger: ["click"],
999
- children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CommentOutlined, {}) })
1000
- }
1001
- )
1002
- }
1003
- ),
1004
- /* @__PURE__ */ jsxRuntime.jsx(
1005
- common.RenderWrapper,
1006
- {
1007
- control: closeBtn,
1008
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", size: "large", onClick: configState.hooks?.onHeaderClose, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloseOutlined, {}) })
1009
- }
1010
- )
1011
- ] })
1012
- ] }) });
1013
- };
1014
-
1015
905
  // src/ui/common/markdownAlert/index.ts
1016
906
  var customComponents = {
1017
907
  appCard: () => Promise.resolve().then(() => (init_AppCard(), AppCard_exports)),
@@ -1021,10 +911,10 @@ var customComponents = {
1021
911
  fileEdit: () => Promise.resolve().then(() => (init_FileEdit(), FileEdit_exports)),
1022
912
  quoteList: () => Promise.resolve().then(() => (init_QuoteList(), QuoteList_exports))
1023
913
  };
1024
- var MessageRender_default = ({ message: message4, placement }) => {
914
+ var MessageRender_default = ({ message: message3, placement }) => {
1025
915
  return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, children: [
1026
- message4.content && /* @__PURE__ */ jsxRuntime.jsx(x.Bubble, { placement, content: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: message4.content, customComponents }) }),
1027
- message4.files?.map((file, index) => /* @__PURE__ */ jsxRuntime.jsx(
916
+ message3.msgContent && /* @__PURE__ */ jsxRuntime.jsx(x.Bubble, { placement, content: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: message3.msgContent, customComponents }) }),
917
+ message3.msgFiles?.map((file) => /* @__PURE__ */ jsxRuntime.jsx(
1028
918
  x.Bubble,
1029
919
  {
1030
920
  className: "m-t-8",
@@ -1034,22 +924,57 @@ var MessageRender_default = ({ message: message4, placement }) => {
1034
924
  x.Attachments.FileCard,
1035
925
  {
1036
926
  item: {
1037
- uid: file.id,
927
+ uid: file.content,
1038
928
  name: file.name,
1039
- url: file.url
929
+ url: file.content
1040
930
  }
1041
931
  },
1042
- index
932
+ file.content
1043
933
  )
1044
934
  },
1045
- index
935
+ file.content
1046
936
  ))
1047
937
  ] });
1048
938
  };
1049
939
 
940
+ // src/core/constants.ts
941
+ var MEMBER_TYPE = {
942
+ 1: "user",
943
+ 2: "other",
944
+ 3: "agent"
945
+ };
946
+
1050
947
  // src/ui/common/BubbleListItems.tsx
1051
948
  init_utils();
1052
949
  init_Context();
950
+
951
+ // src/ui/common/styles.module.less
952
+ var styles_module_default2 = {
953
+ loadingMessage: "styles_module_loadingMessage",
954
+ conversationListPanel: "styles_module_conversationListPanel",
955
+ nsConversations: "styles_module_nsConversations",
956
+ nsBodyWidth: "styles_module_nsBodyWidth",
957
+ nsBubbleList: "styles_module_nsBubbleList",
958
+ nsChatHeader: "styles_module_nsChatHeader",
959
+ nsChatTitle: "styles_module_nsChatTitle",
960
+ nsChatHeaderPopover: "styles_module_nsChatHeaderPopover",
961
+ chatWelcomeWrap: "styles_module_chatWelcomeWrap",
962
+ chatWelcome: "styles_module_chatWelcome",
963
+ chatWelcomePrompts: "styles_module_chatWelcomePrompts",
964
+ senderListTitle: "styles_module_senderListTitle",
965
+ senderList: "styles_module_senderList",
966
+ senderListItem: "styles_module_senderListItem",
967
+ senderListFooter: "styles_module_senderListFooter",
968
+ nsChatUserName: "styles_module_nsChatUserName",
969
+ nsSenderReferenceHeaderTitle: "styles_module_nsSenderReferenceHeaderTitle",
970
+ nsSenderReferenceHeaderContent: "styles_module_nsSenderReferenceHeaderContent",
971
+ avatarListContainer: "styles_module_avatarListContainer",
972
+ avatarList: "styles_module_avatarList",
973
+ avatarListItem: "styles_module_avatarListItem",
974
+ avatarListItemIcon: "styles_module_avatarListItemIcon",
975
+ avatarListItemIconActive: "styles_module_avatarListItemIconActive",
976
+ avatarListItemName: "styles_module_avatarListItemName"
977
+ };
1053
978
  function extractThinkContent(content) {
1054
979
  let main = content;
1055
980
  const thinkContents = [];
@@ -1075,20 +1000,19 @@ function renderMarkdownPanel(content, label, key) {
1075
1000
  children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content, customComponents })
1076
1001
  };
1077
1002
  }
1078
- var MessageAIRender_default = ({ message: message4, placement }) => {
1003
+ var MessageAIRender_default = ({ message: message3, placement }) => {
1079
1004
  const { mainContent, thinkContents, thinkBuffer } = react.useMemo(() => {
1080
- if (!message4?.content) return { mainContent: "", thinkContents: [], thinkBuffer: "" };
1081
- return extractThinkContent(message4.content);
1082
- }, [message4?.content]);
1083
- const isWaiting = !message4 || !message4.content && message4.status === "loading";
1084
- if (isWaiting) {
1005
+ if (!message3?.msgContent) return { mainContent: "", thinkContents: [], thinkBuffer: "" };
1006
+ return extractThinkContent(message3.msgContent);
1007
+ }, [message3?.msgContent]);
1008
+ if (!message3.msgContent) {
1085
1009
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Typography, { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { size: "small" }) });
1086
1010
  }
1087
1011
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1088
1012
  x.Bubble,
1089
1013
  {
1090
1014
  placement,
1091
- className: classNames6__default.default({ [styles_module_default.loadingMessage]: message4.status === "loading" }),
1015
+ className: classNames7__default.default({ [styles_module_default2.loadingMessage]: message3.type && message3.type !== "TEXT_MESSAGE_END" }),
1092
1016
  content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1093
1017
  thinkContents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1094
1018
  antd.Collapse,
@@ -1108,54 +1032,67 @@ var MessageAIRender_default = ({ message: message4, placement }) => {
1108
1032
  items: [renderMarkdownPanel(thinkBuffer, "\u4ED4\u7EC6\u601D\u8003\u4E2D...", "buffer-think")]
1109
1033
  }
1110
1034
  ),
1111
- mainContent && message4.status === "error" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1112
- /* @__PURE__ */ jsxRuntime.jsx(icons.CloseCircleOutlined, { color: "red" }),
1113
- " ",
1114
- mainContent
1115
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: mainContent, customComponents })
1035
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: mainContent, customComponents })
1116
1036
  ] })
1117
1037
  }
1118
1038
  ) });
1119
1039
  };
1120
- var BubbleListItems_default = ({ avatar = true }) => {
1040
+ var BubbleListItems_default = ({ firstMessage = false, avatar = { user: false, agent: true, other: true } }) => {
1121
1041
  const chatStore = useChatStore();
1122
- const agentState = valtio.useSnapshot(chatStore.agent);
1042
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1123
1043
  const conversationState = valtio.useSnapshot(chatStore.conversation);
1124
- const configState = valtio.useSnapshot(chatStore.config);
1125
1044
  const conversationRoles = react.useMemo(() => {
1126
- return {
1127
- user: {
1045
+ const roles = {};
1046
+ if (conversationState.active.member.user) {
1047
+ roles.user = {
1128
1048
  user: "user",
1129
1049
  placement: "end",
1130
- avatar: (common.isBoolean(avatar) ? avatar : avatar?.user) ? /* @__PURE__ */ jsxRuntime.jsx(common.UserAvatar, { size: 30, avatarSrc: configState.userInfo?.iconUrl, userName: configState.userInfo?.name }) : null
1131
- },
1132
- assistant: {
1133
- user: "assistant",
1050
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.user) ? /* @__PURE__ */ jsxRuntime.jsx(
1051
+ common.UserAvatar,
1052
+ {
1053
+ size: 30,
1054
+ avatarSrc: conversationState.active.member.user?.memberAvatar,
1055
+ userName: conversationState.active.member.user?.memberName
1056
+ }
1057
+ ) : null
1058
+ };
1059
+ }
1060
+ if (conversationState.active.member.agent) {
1061
+ roles.agent = {
1062
+ user: "agent",
1134
1063
  placement: "start",
1135
- avatar: (common.isBoolean(avatar) ? avatar : avatar?.assistant) ? { src: agentState.active.iconUrl, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.OpenAIOutlined, {}) } : null
1136
- }
1137
- };
1138
- }, [configState.userInfo, agentState.active, avatar]);
1064
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.agent) ? { src: conversationState.active.member.agent?.memberAvatar, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.OpenAIOutlined, {}) } : null
1065
+ };
1066
+ }
1067
+ if (conversationState.active.member.other) {
1068
+ roles.other = {
1069
+ user: "other",
1070
+ placement: "start",
1071
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.other) ? { src: conversationState.active.member.other?.memberAvatar, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.OpenAIOutlined, {}) } : null
1072
+ };
1073
+ }
1074
+ return roles;
1075
+ }, [conversationState.active.member, avatar]);
1139
1076
  const chatMessage = react.useMemo(
1140
- () => conversationState.messages[conversationState.active.key] || {},
1141
- [conversationState.messages[conversationState.active.key]]
1077
+ () => conversationState.messages[conversationState.active.id] || {},
1078
+ [conversationState.messages[conversationState.active.id]]
1142
1079
  );
1143
1080
  const placeholderNode = react.useMemo(
1144
1081
  () => [
1145
1082
  {
1146
1083
  key: "placeholder",
1147
- content: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { direction: "vertical", size: 16, className: styles_module_default.chatWelcomeWrap, children: [
1084
+ content: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { direction: "vertical", size: 16, className: styles_module_default2.chatWelcomeWrap, children: [
1148
1085
  /* @__PURE__ */ jsxRuntime.jsx(
1149
1086
  x.Welcome,
1150
1087
  {
1151
- className: classNames6__default.default(styles_module_default.chatWelcome, "p-t-32"),
1088
+ className: classNames7__default.default(styles_module_default2.chatWelcome, "p-t-32"),
1152
1089
  variant: "borderless",
1153
- icon: /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { shape: "square", size: 58, src: agentState.active.iconUrl }),
1154
- title: `\u4F60\u597D\uFF0C\u6211\u662F${agentState.active.name || ""}`,
1155
- description: agentState.active.description || ""
1090
+ icon: /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { shape: "square", size: 58, src: receiverState.active.logo }),
1091
+ title: `\u4F60\u597D\uFF0C\u6211\u662F${receiverState.active.name || ""}`,
1092
+ description: /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: receiverState.active.description || "" } })
1156
1093
  }
1157
1094
  ),
1158
- agentState.active.recommendQuestions?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1095
+ receiverState.active.config?.recommendQuestions?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1159
1096
  x.Prompts,
1160
1097
  {
1161
1098
  className: "m-t-16",
@@ -1164,9 +1101,9 @@ var BubbleListItems_default = ({ avatar = true }) => {
1164
1101
  {
1165
1102
  key: "1",
1166
1103
  label: "\u{1F914} \u63A8\u8350\u95EE\u9898:",
1167
- children: agentState.active.recommendQuestions.map(({ question, id }) => ({
1168
- key: id,
1169
- description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.sendMessage(question), className: classNames6__default.default(styles_module_default.chatWelcomePrompts, "text-ellipsis"), children: question })
1104
+ children: receiverState.active.config.recommendQuestions.map(({ question }) => ({
1105
+ key: question,
1106
+ description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.sendMessage(question), className: classNames7__default.default(styles_module_default2.chatWelcomePrompts, "text-ellipsis"), children: question })
1170
1107
  }))
1171
1108
  }
1172
1109
  ]
@@ -1176,7 +1113,7 @@ var BubbleListItems_default = ({ avatar = true }) => {
1176
1113
  variant: "borderless"
1177
1114
  }
1178
1115
  ],
1179
- [agentState.active]
1116
+ [receiverState.active]
1180
1117
  );
1181
1118
  const questionList = react.useMemo(
1182
1119
  () => chatMessage?.questionList?.length ? [
@@ -1192,8 +1129,8 @@ var BubbleListItems_default = ({ avatar = true }) => {
1192
1129
  }
1193
1130
  },
1194
1131
  vertical: true,
1195
- items: chatMessage?.questionList.map(({ question, id }) => ({
1196
- key: id,
1132
+ items: chatMessage?.questionList.map((question) => ({
1133
+ key: question,
1197
1134
  description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.sendMessage(question), children: question })
1198
1135
  }))
1199
1136
  }
@@ -1205,36 +1142,37 @@ var BubbleListItems_default = ({ avatar = true }) => {
1205
1142
  [chatMessage?.questionList]
1206
1143
  );
1207
1144
  const chatRecords = react.useMemo(() => {
1208
- return (chatMessage?.message?.items || []).map((message4, index) => {
1145
+ return (chatMessage?.message || []).map((message3, index) => {
1146
+ const role = conversationRoles[MEMBER_TYPE[message3.sender.type]];
1209
1147
  return {
1210
- key: message4.id || -index,
1211
- placement: conversationRoles[message4.role].placement,
1148
+ key: message3.id,
1149
+ placement: role.placement,
1212
1150
  variant: "borderless",
1213
- avatar: conversationRoles[message4.role].avatar,
1214
- 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 }),
1151
+ avatar: role.avatar,
1152
+ content: role.user === "agent" ? /* @__PURE__ */ jsxRuntime.jsx(MessageAIRender_default, { message: message3, placement: role.placement }) : /* @__PURE__ */ jsxRuntime.jsx(MessageRender_default, { message: message3, placement: role.placement }),
1215
1153
  // loadingRender: () => <Spin size="small" />,
1216
- footer: message4.role === "assistant" && message4.id && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { children: [
1217
- /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => copy(message4.content), color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CopyOutlined, {}) }),
1154
+ footer: role.user === "agent" && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { children: [
1155
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => copy(message3.msgContent), color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CopyOutlined, {}) }),
1218
1156
  /* @__PURE__ */ jsxRuntime.jsx(
1219
1157
  antd.Button,
1220
1158
  {
1221
- color: message4.feedback === "like" ? "primary" : "default",
1222
- disabled: message4.status === "loading",
1159
+ color: message3.msgFeedback === 1 ? "primary" : "default",
1160
+ disabled: !!message3.type,
1223
1161
  size: "small",
1224
1162
  variant: "text",
1225
1163
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LikeOutlined, {}),
1226
- onClick: () => chatStore.feedback(conversationState.active.key, message4.id, "like", index)
1164
+ onClick: () => chatStore.feedback(conversationState.active.id, message3.id, 1, index)
1227
1165
  }
1228
1166
  ),
1229
1167
  /* @__PURE__ */ jsxRuntime.jsx(
1230
1168
  antd.Button,
1231
1169
  {
1232
- color: message4.feedback === "dislike" ? "primary" : "default",
1233
- disabled: message4.status === "loading",
1170
+ color: message3.msgFeedback === 2 ? "primary" : "default",
1171
+ disabled: !!message3.type,
1234
1172
  size: "small",
1235
1173
  variant: "text",
1236
1174
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DislikeOutlined, {}),
1237
- onClick: () => chatStore.feedback(conversationState.active.key, message4.id, "dislike", index)
1175
+ onClick: () => chatStore.feedback(conversationState.active.id, message3.id, 2, index)
1238
1176
  }
1239
1177
  )
1240
1178
  ] })
@@ -1244,8 +1182,22 @@ var BubbleListItems_default = ({ avatar = true }) => {
1244
1182
  };
1245
1183
  });
1246
1184
  }, [chatMessage?.message]);
1185
+ const firstMessageRecord = react.useMemo(() => {
1186
+ const isExist = common.shouldRender(firstMessage);
1187
+ return isExist ? [
1188
+ {
1189
+ key: "firstMessage",
1190
+ content: /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: firstMessage }),
1191
+ placement: "end"
1192
+ // avatar: { style: { visibility: 'hidden' } }
1193
+ }
1194
+ ] : [];
1195
+ }, [firstMessage]);
1247
1196
  const bubbleListItems = react.useMemo(() => {
1248
1197
  const list = [];
1198
+ if (firstMessageRecord.length > 0) {
1199
+ list.push(...firstMessageRecord);
1200
+ }
1249
1201
  if (chatRecords.length > 0) {
1250
1202
  list.push(...chatRecords, ...questionList);
1251
1203
  }
@@ -1253,7 +1205,7 @@ var BubbleListItems_default = ({ avatar = true }) => {
1253
1205
  return list;
1254
1206
  }
1255
1207
  return [...placeholderNode];
1256
- }, [chatRecords, questionList, placeholderNode]);
1208
+ }, [chatRecords, questionList, placeholderNode, firstMessageRecord]);
1257
1209
  const listRef = react.useRef(null);
1258
1210
  const autoScrollRef = react.useRef(true);
1259
1211
  const handleScroll = (el) => {
@@ -1284,16 +1236,193 @@ var BubbleListItems_default = ({ avatar = true }) => {
1284
1236
  autoScroll: false,
1285
1237
  ref: listRef,
1286
1238
  items: bubbleListItems,
1287
- className: classNames6__default.default(styles_module_default.nsBubbleList, "height-full", "scroll-fade-in"),
1239
+ className: classNames7__default.default(styles_module_default2.nsBubbleList, "height-full", "scroll-fade-in"),
1288
1240
  onScroll: handleScroll
1289
1241
  },
1290
- conversationState.active.key
1242
+ conversationState.active.id
1291
1243
  );
1292
1244
  };
1293
1245
 
1294
- // src/components/Attachments.tsx
1295
- init_utils();
1296
- var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSizeTip, fileList = [], onChange, extraParams }, ref) => {
1246
+ // src/ui/common/ChatHeader.tsx
1247
+ init_Context();
1248
+
1249
+ // src/ui/common/AgentCharacter.tsx
1250
+ init_Context();
1251
+
1252
+ // src/ui/common/CharacterList.tsx
1253
+ init_Context();
1254
+ var CharacterList_default = () => {
1255
+ const chatStore = useChatStore();
1256
+ const characterState = valtio.useSnapshot(chatStore.character);
1257
+ const [activeCharacter, setActiveCharacter] = react.useState(characterState.active);
1258
+ return /* @__PURE__ */ jsxRuntime.jsx(
1259
+ antd.Modal,
1260
+ {
1261
+ width: 500,
1262
+ title: "\u9009\u62E9\u6027\u683C",
1263
+ maskClosable: false,
1264
+ open: characterState.open,
1265
+ onCancel: chatStore.closeCharacterList,
1266
+ loading: characterState.loading,
1267
+ okText: "\u5207\u6362\u6027\u683C",
1268
+ onOk: () => chatStore.switchCharacter(activeCharacter),
1269
+ confirmLoading: characterState.switchLoading,
1270
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default2.avatarListContainer, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Row, { wrap: true, gutter: [16, 32], className: styles_module_default2.avatarList, children: characterState.list.map((item) => /* @__PURE__ */ jsxRuntime.jsx(antd.Col, { span: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, align: "center", className: styles_module_default2.avatarListItem, onClick: () => setActiveCharacter(item), children: [
1271
+ /* @__PURE__ */ jsxRuntime.jsx(
1272
+ antd.Avatar,
1273
+ {
1274
+ className: classNames7__default.default(styles_module_default2.avatarListItemIcon, "cursor-pointer", {
1275
+ [styles_module_default2.avatarListItemIconActive]: activeCharacter.id === item.id
1276
+ }),
1277
+ size: 50,
1278
+ src: /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.logo, alt: "\u5934\u50CF" })
1279
+ }
1280
+ ),
1281
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default2.avatarListItemName, children: item.characterName })
1282
+ ] }) }, item.id)) }) })
1283
+ }
1284
+ );
1285
+ };
1286
+ var AgentCharacter_default = () => {
1287
+ const chatStore = useChatStore();
1288
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1289
+ const characterState = valtio.useSnapshot(chatStore.character);
1290
+ react.useEffect(() => {
1291
+ if (receiverState.active.id && receiverState.active.type === 3) {
1292
+ chatStore.getCharacters(receiverState.active.id);
1293
+ }
1294
+ }, [receiverState.active.id]);
1295
+ return characterState.active.id && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1296
+ /* @__PURE__ */ jsxRuntime.jsx("div", { title: "\u6027\u683C", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { onClick: chatStore.openCharacterList, className: "cursor-pointer", src: characterState.active.logo }) }),
1297
+ characterState.open && /* @__PURE__ */ jsxRuntime.jsx(CharacterList_default, {})
1298
+ ] });
1299
+ };
1300
+
1301
+ // src/ui/common/ConversationList.tsx
1302
+ init_Context();
1303
+ var ConversationList_default = () => {
1304
+ const chatStore = useChatStore();
1305
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1306
+ const conversationsState = valtio.useSnapshot(chatStore.conversations);
1307
+ const conversationState = valtio.useSnapshot(chatStore.conversation);
1308
+ const getConversations = common.useDebounce(() => {
1309
+ chatStore.getConversations(receiverState.active.id, 3);
1310
+ }, 300);
1311
+ react.useEffect(() => {
1312
+ if (receiverState.active.id) {
1313
+ getConversations();
1314
+ }
1315
+ }, [receiverState.active.id, conversationsState.updateIndex]);
1316
+ const conversationList = react.useMemo(() => {
1317
+ return conversationsState.list.items.filter((item) => item.label);
1318
+ }, [conversationsState.list.items]);
1319
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "height-full scroll-fade-in", id: "scrollableDiv", children: conversationList.length ? /* @__PURE__ */ jsxRuntime.jsx(
1320
+ InfiniteScroll__default.default,
1321
+ {
1322
+ dataLength: conversationList.length,
1323
+ next: () => {
1324
+ console.log("next");
1325
+ },
1326
+ hasMore: false,
1327
+ loader: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { indicator: /* @__PURE__ */ jsxRuntime.jsx(icons.RedoOutlined, { spin: true }), size: "small" }) }),
1328
+ style: { overflow: "hidden" },
1329
+ scrollableTarget: "scrollableDiv",
1330
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1331
+ x.Conversations,
1332
+ {
1333
+ className: styles_module_default2.nsConversations,
1334
+ items: conversationList,
1335
+ activeKey: conversationState.active.id,
1336
+ onActiveChange: async (id) => chatStore.switchConversation(id),
1337
+ groupable: true,
1338
+ menu: (conversation) => ({
1339
+ items: [
1340
+ {
1341
+ label: "\u5220\u9664\u4F1A\u8BDD",
1342
+ key: "delete",
1343
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DeleteOutlined, {}),
1344
+ danger: true
1345
+ }
1346
+ ],
1347
+ onClick: (menuInfo) => {
1348
+ menuInfo.domEvent.stopPropagation();
1349
+ if (menuInfo.key === "delete") {
1350
+ chatStore.delConversation(conversation.id);
1351
+ }
1352
+ }
1353
+ })
1354
+ }
1355
+ )
1356
+ }
1357
+ ) : /* @__PURE__ */ jsxRuntime.jsx(antd.Empty, { description: "\u6682\u65E0\u4F1A\u8BDD\u8BB0\u5F55", image: antd.Empty.PRESENTED_IMAGE_SIMPLE }) }) });
1358
+ };
1359
+ var ChatHeader_default = ({
1360
+ title = true,
1361
+ closeBtn = false,
1362
+ newConversationBtn = true,
1363
+ agentCharacter = true,
1364
+ conversationListBtn = true
1365
+ }) => {
1366
+ const chatStore = useChatStore();
1367
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1368
+ const configState = valtio.useSnapshot(chatStore.config);
1369
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", className: styles_module_default2.nsChatHeader, children: [
1370
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", children: [
1371
+ /* @__PURE__ */ jsxRuntime.jsx(
1372
+ common.RenderWrapper,
1373
+ {
1374
+ control: title,
1375
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1376
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 22, src: receiverState.active.logo, alt: receiverState.active.name }),
1377
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default2.nsChatTitle, children: receiverState.active.name })
1378
+ ] })
1379
+ }
1380
+ ),
1381
+ " "
1382
+ ] }),
1383
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { size: 2, children: [
1384
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: agentCharacter, DefaultComponent: AgentCharacter_default }),
1385
+ /* @__PURE__ */ jsxRuntime.jsx(
1386
+ common.RenderWrapper,
1387
+ {
1388
+ control: newConversationBtn,
1389
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { title: "\u65B0\u5EFA\u4F1A\u8BDD", type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}), onClick: () => chatStore.createAgentConversation() })
1390
+ }
1391
+ ),
1392
+ /* @__PURE__ */ jsxRuntime.jsx(
1393
+ common.RenderWrapper,
1394
+ {
1395
+ control: conversationListBtn,
1396
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(
1397
+ antd.Popover,
1398
+ {
1399
+ getPopupContainer: (e) => e,
1400
+ placement: "bottom",
1401
+ classNames: { body: styles_module_default2.nsChatHeaderPopover },
1402
+ content: /* @__PURE__ */ jsxRuntime.jsx(ConversationList_default, {}),
1403
+ trigger: ["click"],
1404
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { title: "\u5386\u53F2\u4F1A\u8BDD", type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CommentOutlined, {}) })
1405
+ }
1406
+ )
1407
+ }
1408
+ ),
1409
+ /* @__PURE__ */ jsxRuntime.jsx(
1410
+ common.RenderWrapper,
1411
+ {
1412
+ control: closeBtn,
1413
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { title: "\u5173\u95ED", type: "text", size: "large", onClick: configState.hooks?.onHeaderClose, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloseOutlined, {}) })
1414
+ }
1415
+ )
1416
+ ] })
1417
+ ] }) });
1418
+ };
1419
+
1420
+ // src/components/styles.module.less
1421
+ var styles_module_default3 = {
1422
+ nsAttachments: "styles_module_nsAttachments"
1423
+ };
1424
+ var Attachments_default = react.forwardRef(({ fileUploadConfig = [], fileList = [], onChange, extraParams }, ref) => {
1425
+ const { message: message3 } = antd.App.useApp();
1297
1426
  const fileListRef = react.useRef([]);
1298
1427
  const [attachedFiles, setAttachedFiles, getAttachedFiles] = common.useRefState([]);
1299
1428
  react.useEffect(() => {
@@ -1301,7 +1430,8 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1301
1430
  fileListRef.current = fileList;
1302
1431
  const mapped = fileList.map((file) => ({
1303
1432
  ...file,
1304
- uid: file.id,
1433
+ uid: file.content,
1434
+ url: file.content,
1305
1435
  status: "done"
1306
1436
  }));
1307
1437
  setAttachedFiles(mapped);
@@ -1313,34 +1443,53 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1313
1443
  delete f.status;
1314
1444
  delete f.uid;
1315
1445
  delete f.size;
1446
+ delete f.url;
1316
1447
  return f;
1317
1448
  });
1318
1449
  fileListRef.current = files;
1319
1450
  onChange(files);
1320
1451
  }, [attachedFiles]);
1321
1452
  const onErrorTip = common.useDebounce((errorMsg) => {
1322
- antd.message.error(errorMsg);
1453
+ message3.error(errorMsg);
1323
1454
  }, 300);
1455
+ const findConfigByFile = (file) => {
1456
+ return fileUploadConfig.find((cfg) => cfg.allowedFileTypes?.includes(common.getFileSuffixName(file.name).toLocaleUpperCase()));
1457
+ };
1324
1458
  const onBeforeUpload = (files) => {
1325
- if (common.isNumber(maxCount) && files.length + attachedFiles.length > maxCount) {
1326
- onErrorTip(`\u6700\u591A\u53EA\u80FD\u4E0A\u4F20${maxCount}\u4E2A\u6587\u4EF6`);
1327
- return Promise.reject(false);
1459
+ for (const file of files) {
1460
+ const cfg = findConfigByFile(file);
1461
+ if (!cfg) {
1462
+ onErrorTip(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B\uFF1A${file.name} (${file.type})`);
1463
+ return Promise.reject(false);
1464
+ }
1465
+ if (common.isNumber(cfg.maxFileCount)) {
1466
+ const currentCount = attachedFiles.filter((f) => cfg.allowedFileTypes.includes(common.getFileSuffixName(f.name || "").toLocaleUpperCase())).length;
1467
+ if (currentCount + 1 > cfg.maxFileCount) {
1468
+ onErrorTip(`\u3010${file.name}\u3011\u6240\u5C5E\u7C7B\u578B\u6700\u591A\u53EA\u80FD\u4E0A\u4F20 ${cfg.maxFileCount} \u4E2A\u6587\u4EF6`);
1469
+ return Promise.reject(false);
1470
+ }
1471
+ }
1328
1472
  }
1329
1473
  };
1330
1474
  const onCustomRequest = async ({ file }) => {
1331
- if (fileSize && file.size > fileSize) {
1332
- antd.message.error(`${fileSizeTip}`);
1475
+ const cfg = findConfigByFile(file);
1476
+ if (!cfg) {
1477
+ onErrorTip(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B\uFF1A${file.name}`);
1478
+ return;
1479
+ }
1480
+ if (cfg.maxFileSize && file.size > cfg.maxFileSize * 1024 * 1024) {
1481
+ onErrorTip(`\u6587\u4EF6\u5927\u5C0F\u4E0D\u80FD\u8D85\u8FC7 ${cfg.maxFileSize} MB`);
1333
1482
  return;
1334
1483
  }
1335
1484
  setAttachedFiles([
1336
1485
  ...getAttachedFiles(),
1337
1486
  {
1338
- type: file.type,
1339
- name: file.name,
1340
1487
  uid: file.uid,
1341
1488
  status: "uploading",
1342
1489
  percent: 70,
1343
- size: file.size
1490
+ size: file.size,
1491
+ type: file.type,
1492
+ name: file.name
1344
1493
  }
1345
1494
  ]);
1346
1495
  try {
@@ -1352,14 +1501,11 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1352
1501
  formData.append(key, extraParams[key]);
1353
1502
  });
1354
1503
  }
1355
- const { data } = await uploadFile(formData);
1356
- if (!data?.url && data?.type === "image") {
1357
- data.url = await getBase64(file);
1358
- }
1504
+ const { data } = await fileUpload(formData);
1359
1505
  setAttachedFiles(
1360
1506
  getAttachedFiles().map((f) => {
1361
1507
  if (f.uid === file.uid) {
1362
- return { ...data, uid: data.id, status: "done", size: f.size };
1508
+ return { ...data, uid: data.content, url: data.content, status: "done", size: f.size };
1363
1509
  } else {
1364
1510
  return f;
1365
1511
  }
@@ -1388,12 +1534,12 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1388
1534
  const files = getAttachedFiles();
1389
1535
  const uploadingFiles = files.filter((file) => file.status === "uploading");
1390
1536
  if (uploadingFiles.length > 0) {
1391
- antd.message.error("\u8BF7\u7B49\u5F85\u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210");
1537
+ onErrorTip("\u8BF7\u7B49\u5F85\u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210");
1392
1538
  return false;
1393
1539
  }
1394
1540
  const errorFiles = files.filter((file) => file.status === "error");
1395
1541
  if (errorFiles.length > 0) {
1396
- antd.message.error("\u8BF7\u68C0\u67E5\u4E0A\u4F20\u5931\u8D25\u7684\u6587\u4EF6");
1542
+ onErrorTip("\u8BF7\u68C0\u67E5\u4E0A\u4F20\u5931\u8D25\u7684\u6587\u4EF6");
1397
1543
  return false;
1398
1544
  }
1399
1545
  return true;
@@ -1402,47 +1548,15 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1402
1548
  []
1403
1549
  );
1404
1550
  const acceptStr = react.useMemo(() => {
1405
- if (!accept?.length) return;
1406
- const fileTypeMap = {
1407
- document: [
1408
- ".txt",
1409
- ".md",
1410
- ".mdx",
1411
- ".markdown",
1412
- ".pdf",
1413
- ".html",
1414
- ".xlsx",
1415
- ".xls",
1416
- ".doc",
1417
- ".docx",
1418
- ".csv",
1419
- ".eml",
1420
- ".msg",
1421
- ".pptx",
1422
- ".ppt",
1423
- ".xml",
1424
- ".epub"
1425
- ],
1426
- image: [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"]
1427
- };
1428
- const accepts = [];
1429
- accept?.forEach((type) => {
1430
- if (fileTypeMap[type]) {
1431
- accepts.push(...fileTypeMap[type]);
1432
- }
1433
- });
1434
- if (accepts.length === 0) {
1435
- accepts.push(...accept);
1436
- }
1437
- return accepts.join(",");
1438
- }, [accept]);
1551
+ const allTypes = fileUploadConfig.flatMap((cfg) => cfg.allowedFileTypes || []);
1552
+ return allTypes.length ? allTypes.join(",") : void 0;
1553
+ }, [fileUploadConfig]);
1439
1554
  return /* @__PURE__ */ jsxRuntime.jsx(
1440
1555
  x.Attachments,
1441
1556
  {
1442
- className: "nsAttachments",
1557
+ className: styles_module_default3.nsAttachments,
1443
1558
  accept: acceptStr,
1444
- multiple: !common.isNumber(maxCount) || maxCount > 1,
1445
- maxCount,
1559
+ multiple: true,
1446
1560
  customRequest: onCustomRequest,
1447
1561
  beforeUpload: (file, files) => onBeforeUpload(files),
1448
1562
  items: attachedFiles,
@@ -1472,11 +1586,11 @@ var ChatSender_default = react.forwardRef(
1472
1586
  extraFooter,
1473
1587
  extraFooterBelow,
1474
1588
  sendButtonProps,
1475
- fileUpload
1589
+ fileUpload: fileUpload2
1476
1590
  }, ref) => {
1477
1591
  const senderRef = react.useRef(null);
1478
1592
  const { inputValue, setInputValue } = common.useSyncInput(content || "", onContentChange);
1479
- 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) }) });
1593
+ const attachmentsNode = (fileUpload2?.config?.length ?? 0 > 0) && /* @__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) }) });
1480
1594
  const attachmentsRef = react.useRef();
1481
1595
  const senderHeader = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1482
1596
  /* @__PURE__ */ jsxRuntime.jsx(x.Sender.Header, { title: "\u9009\u62E9\u6587\u4EF6", open: headerOpen, onOpenChange: onHeaderOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1485,9 +1599,8 @@ var ChatSender_default = react.forwardRef(
1485
1599
  ref: attachmentsRef,
1486
1600
  fileList,
1487
1601
  onChange: onFileListChange,
1488
- accept: fileUpload?.allowedFileTypes,
1489
- maxCount: fileUpload?.maxFileCount,
1490
- extraParams: fileUpload?.extraParams
1602
+ fileUploadConfig: fileUpload2.config,
1603
+ extraParams: fileUpload2.params
1491
1604
  }
1492
1605
  ) }),
1493
1606
  extraHeader
@@ -1542,11 +1655,11 @@ var ChatSender_default = react.forwardRef(
1542
1655
  init_Context();
1543
1656
  var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = false }) => {
1544
1657
  const chatStore = useChatStore();
1545
- const agentState = valtio.useSnapshot(chatStore.agent);
1658
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1546
1659
  const conversationState = valtio.useSnapshot(chatStore.conversation);
1547
1660
  const chatMessage = react.useMemo(
1548
- () => conversationState.messages[conversationState.active.key] || {},
1549
- [conversationState.messages[conversationState.active.key]]
1661
+ () => conversationState.messages[conversationState.active.id] || {},
1662
+ [conversationState.messages[conversationState.active.id]]
1550
1663
  );
1551
1664
  const referenceHandle = (con) => {
1552
1665
  if (chatMessage?.loading) return;
@@ -1567,22 +1680,37 @@ var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = fals
1567
1680
  onFileListChange: chatStore.setFileList,
1568
1681
  onHeaderOpenChange: chatStore.setHeaderOpen,
1569
1682
  onSend: () => chatStore.sendMessage(),
1683
+ onCancel: chatStore.cancelReceive,
1570
1684
  onFocus: chatStore.config.hooks?.onSenderFocus,
1571
1685
  fileUpload: {
1572
- ...agentState.active?.parameters?.fileUpload,
1573
- extraParams: { agentId: agentState.active.id }
1686
+ config: receiverState.active.config?.fileUpload
1574
1687
  },
1575
1688
  extraFooter: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1576
- /* @__PURE__ */ jsxRuntime.jsx(
1689
+ receiverState.active.feature?.deepThink && /* @__PURE__ */ jsxRuntime.jsx(
1577
1690
  antd.Button,
1578
1691
  {
1579
1692
  size: "small",
1580
- color: agentState.params.thinkMode === "1" ? "primary" : "default",
1693
+ color: receiverState.params.thinkMode === "1" ? "primary" : "default",
1581
1694
  variant: "filled",
1582
- onClick: () => chatStore.setAgentParams({ thinkMode: agentState.params.thinkMode === "1" ? "2" : "1" }),
1695
+ onClick: () => chatStore.setReceiverParams({ thinkMode: receiverState.params.thinkMode === "1" ? "2" : "1" }),
1583
1696
  children: "\u6DF1\u5EA6\u601D\u8003"
1584
1697
  }
1585
1698
  ),
1699
+ receiverState.active.feature?.switchManual && /* @__PURE__ */ jsxRuntime.jsx(
1700
+ antd.Button,
1701
+ {
1702
+ size: "small",
1703
+ title: chatMessage?.speakHuman ? "\u5F53\u524D\u72B6\u6001\u4E3A\u4EBA\u5DE5\u6A21\u5F0F\u3002\u60A8\u53D1\u9001\u7684\u95EE\u9898\u5C06\u76F4\u63A5\u53D1\u9001\u7ED9\u4E13\u5BB6\uFF0C\u667A\u80FD\u52A9\u624B\u5C06\u4E0D\u518D\u56DE\u590D" : "\u5F53\u524D\u72B6\u6001\u4E3A\u667A\u80FD\u52A9\u624B\u6A21\u5F0F\u3002\u60A8\u53D1\u9001\u7684\u95EE\u9898\u5C06\u53D1\u9001\u7ED9\u667A\u80FD\u52A9\u624B\uFF0C\u667A\u80FD\u52A9\u624B\u5C06\u56DE\u590D\u60A8",
1704
+ shape: "round",
1705
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.UserSwitchOutlined, {}),
1706
+ color: chatMessage?.speakHuman ? "primary" : "default",
1707
+ variant: "filled",
1708
+ onClick: () => {
1709
+ chatStore.setSpeakHuman?.(!chatMessage?.speakHuman);
1710
+ },
1711
+ children: "\u5411\u4E13\u5BB6\u54A8\u8BE2"
1712
+ }
1713
+ ),
1586
1714
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: extraBtn })
1587
1715
  ] }),
1588
1716
  extraHeader: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1595,8 +1723,8 @@ var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = fals
1595
1723
  open: !!chatMessage?.references?.content?.name,
1596
1724
  onOpenChange: () => chatStore.setReferences(),
1597
1725
  classNames: {
1598
- header: styles_module_default.nsSenderReferenceHeaderTitle,
1599
- content: common.shouldRender(referencesBtn) ? "" : styles_module_default.nsSenderReferenceHeaderContent
1726
+ header: styles_module_default2.nsSenderReferenceHeaderTitle,
1727
+ content: common.shouldRender(referencesBtn) ? "" : styles_module_default2.nsSenderReferenceHeaderContent
1600
1728
  },
1601
1729
  children: /* @__PURE__ */ jsxRuntime.jsx(
1602
1730
  common.RenderWrapper,
@@ -1618,11 +1746,11 @@ var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = fals
1618
1746
  init_Context();
1619
1747
  var ConversationListHeader_default = () => {
1620
1748
  const chatStore = useChatStore();
1621
- const agentState = valtio.useSnapshot(chatStore.agent);
1749
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1622
1750
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-24", children: [
1623
1751
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { align: "center", gap: 8, children: [
1624
- /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 36, src: agentState.active.iconUrl }),
1625
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles_module_default.nsChatUserName, children: agentState.active.name })
1752
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 36, src: receiverState.active.logo }),
1753
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles_module_default2.nsChatUserName, children: receiverState.active.name })
1626
1754
  ] }),
1627
1755
  /* @__PURE__ */ jsxRuntime.jsx(
1628
1756
  antd.Button,
@@ -1630,8 +1758,8 @@ var ConversationListHeader_default = () => {
1630
1758
  block: true,
1631
1759
  type: "primary",
1632
1760
  shape: "round",
1633
- onClick: () => chatStore.switchConversation(),
1634
- className: classNames6__default.default("m-t-16"),
1761
+ onClick: () => chatStore.createAgentConversation(),
1762
+ className: classNames7__default.default("m-t-16"),
1635
1763
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}),
1636
1764
  children: "\u65B0\u5EFA\u4F1A\u8BDD"
1637
1765
  }
@@ -1639,7 +1767,7 @@ var ConversationListHeader_default = () => {
1639
1767
  ] });
1640
1768
  };
1641
1769
  var ConversationListPanel_default = ({ header }) => {
1642
- return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames6__default.default("height-full", styles_module_default.conversationListPanel), children: [
1770
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames7__default.default("height-full", styles_module_default2.conversationListPanel), children: [
1643
1771
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: header, DefaultComponent: ConversationListHeader_default }),
1644
1772
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(ConversationList_default, {}) })
1645
1773
  ] });
@@ -1649,11 +1777,11 @@ var ConversationListPanel_default = ({ header }) => {
1649
1777
  init_Context();
1650
1778
  var SenderPromptsItems_default = () => {
1651
1779
  const chatStore = useChatStore();
1652
- const agentState = valtio.useSnapshot(chatStore.agent);
1780
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1653
1781
  const component = react.useMemo(
1654
- () => agentState.active.labels?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, wrap: true, children: [
1782
+ () => receiverState.active.config?.labels?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, className: "overflow-hidden", children: [
1655
1783
  /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { disabled: true, color: "default", variant: "text", children: "\u968F\u4FBF\u804A\u804A" }),
1656
- agentState.active.labels.map((question) => /* @__PURE__ */ jsxRuntime.jsx(
1784
+ receiverState.active.config.labels.map((question) => /* @__PURE__ */ jsxRuntime.jsx(
1657
1785
  antd.Popover,
1658
1786
  {
1659
1787
  content: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1661,67 +1789,72 @@ var SenderPromptsItems_default = () => {
1661
1789
  {
1662
1790
  itemLayout: "horizontal",
1663
1791
  split: false,
1664
- className: styles_module_default.senderList,
1665
- dataSource: question.hotQuestionList,
1666
- renderItem: (item) => /* @__PURE__ */ jsxRuntime.jsx(antd.List.Item, { onClick: () => chatStore.sendMessage(item.question), className: styles_module_default.senderListItem, children: item.question }),
1667
- 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)" })
1792
+ className: styles_module_default2.senderList,
1793
+ dataSource: question.items,
1794
+ renderItem: (item) => /* @__PURE__ */ jsxRuntime.jsx(antd.List.Item, { onClick: () => chatStore.sendMessage(item.question), className: styles_module_default2.senderListItem, children: item.question }),
1795
+ footer: /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "end", className: styles_module_default2.senderListFooter, children: "(\u60A8\u53EF\u70B9\u51FB\u4EE5\u4E0A\u95EE\u9898\u5F00\u542FAI\u4F53\u9A8C)" })
1668
1796
  }
1669
1797
  ),
1670
1798
  title: /* @__PURE__ */ jsxRuntime.jsx(
1671
1799
  "div",
1672
1800
  {
1673
- className: classNames6__default.default(styles_module_default.senderListTitle, "text-ellipsis"),
1674
- children: `${agentState.active.name}\u5F00\u59CB\u5173\u6CE8${question.labelName}\u5185\u5BB9\uFF01`
1801
+ className: classNames7__default.default(styles_module_default2.senderListTitle, "text-ellipsis"),
1802
+ children: `${receiverState.active.name}\u5F00\u59CB\u5173\u6CE8${question.name}\u5185\u5BB9\uFF01`
1675
1803
  }
1676
1804
  ),
1677
- children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "filled", children: question.labelName })
1805
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "filled", children: question.name })
1678
1806
  },
1679
1807
  question.id
1680
1808
  ))
1681
1809
  ] }),
1682
- [agentState.active.labels]
1810
+ [receiverState.active.config?.labels]
1683
1811
  );
1684
1812
  return component;
1685
1813
  };
1686
1814
 
1687
1815
  // src/ui/layouts/styles.module.less
1688
- var styles_module_default3 = {
1816
+ var styles_module_default4 = {
1689
1817
  nsPreviewHeader: "styles_module_nsPreviewHeader",
1690
1818
  nsPreviewHeaderTitle: "styles_module_nsPreviewHeaderTitle",
1691
1819
  nsChatSenderHeader: "styles_module_nsChatSenderHeader",
1692
1820
  nsDisclaimerNotice: "styles_module_nsDisclaimerNotice",
1693
1821
  nsChatLayout: "styles_module_nsChatLayout"
1694
1822
  };
1695
- var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultAgent }, ref) => {
1823
+ var layouts_default = react.forwardRef(({ theme, params, userInfo, hooks, layout, config }, ref) => {
1696
1824
  const chatStore = react.useMemo(() => createChatStore(), []);
1697
- react.useEffect(() => {
1698
- chatStore.getUserInfo();
1699
- if (defaultAgent?.appKey && defaultAgent?.agentKey) {
1700
- chatStore.switchAgent({ appKey: defaultAgent.appKey, agentKey: defaultAgent.agentKey }, defaultAgent.conversationId);
1825
+ common.useDeepEffect(() => {
1826
+ if (config?.conversationId) {
1827
+ chatStore.switchConversation(config.conversationId);
1828
+ return;
1701
1829
  }
1702
- }, []);
1830
+ if (config?.receiverId && config?.receiverType === 3) {
1831
+ chatStore.switchAgentConversation(config.receiverId, config.conversationStrategy);
1832
+ }
1833
+ }, [config]);
1703
1834
  react.useEffect(() => {
1704
- chatStore.setLayout(layout);
1705
- }, [layout]);
1835
+ chatStore.setUserInfo(userInfo);
1836
+ }, [userInfo]);
1837
+ react.useEffect(() => {
1838
+ chatStore.setLayout(layout, config?.receiverType);
1839
+ }, [layout, config?.receiverType]);
1706
1840
  react.useEffect(() => {
1707
1841
  chatStore.setConfigParams(params);
1708
1842
  }, [params]);
1709
1843
  react.useEffect(() => {
1710
1844
  chatStore.setHooks(hooks);
1711
1845
  }, [hooks]);
1712
- const agentState = valtio.useSnapshot(chatStore.agent);
1846
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1847
+ valtio.useSnapshot(chatStore.conversation);
1713
1848
  const configState = valtio.useSnapshot(chatStore.config);
1714
1849
  react.useImperativeHandle(
1715
1850
  ref,
1716
1851
  () => ({
1717
1852
  sendMessage: chatStore.sendMessage,
1718
- switchAgent: chatStore.switchAgent,
1853
+ switchAgentConversation: chatStore.switchAgentConversation,
1719
1854
  switchConversation: chatStore.switchConversation,
1720
1855
  setReferences: chatStore.setReferences,
1721
1856
  setMessage: chatStore.setContent,
1722
- setFiles: chatStore.setFileList,
1723
- setParams: chatStore.setConfigParams,
1724
- setLayout: chatStore.setLayout
1857
+ setFiles: chatStore.setFileList
1725
1858
  }),
1726
1859
  []
1727
1860
  );
@@ -1739,16 +1872,25 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1739
1872
  setSplitterSizes([0, "100%"]);
1740
1873
  }
1741
1874
  }, [hasPreView]);
1742
- 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.jsxs(antd.Flex, { vertical: true, className: classNames6__default.default(styles_module_default3.nsChatLayout, "height-full"), children: [
1743
- /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: AgentHeader_default }),
1875
+ common.useWebSocket({
1876
+ url: common.getWebSocketUrl(`/lolr/conversation/ws/subscribe?NS-TOKEN=${common.getToken()}`, common.isLocalhost() ? "192.168.6.23:9090" : ""),
1877
+ onMessage: chatStore.acceptMessage,
1878
+ clientHeartbeat: false,
1879
+ reconnectInterval: 1e4
1880
+ });
1881
+ react.useEffect(() => {
1882
+ configState.hooks?.onBeforeInit?.();
1883
+ }, []);
1884
+ return /* @__PURE__ */ jsxRuntime.jsx(x.XProvider, { theme: { cssVar: true, ...theme }, children: /* @__PURE__ */ jsxRuntime.jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: receiverState.loading, wrapperClassName: "full-spin", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames7__default.default(styles_module_default4.nsChatLayout, "height-full"), children: [
1885
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: ChatHeader_default }),
1744
1886
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { className: "full-scroll", children: [
1745
- /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.leftPanel, DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}) }),
1887
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.leftPanel }),
1746
1888
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.conversationList, DefaultComponent: ConversationListPanel_default }),
1747
1889
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Splitter, { className: "flex-1", onResize: setSplitterSizes, children: [
1748
1890
  /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, min: 600, size: sizes[0], children: hasPreView && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1749
1891
  configState.preview.file.fileUrl && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: "height-full", children: [
1750
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default3.nsPreviewHeader, children: [
1751
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default3.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1892
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default4.nsPreviewHeader, children: [
1893
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default4.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1752
1894
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "center", align: "center", children: [
1753
1895
  /* @__PURE__ */ jsxRuntime.jsx(
1754
1896
  antd.Button,
@@ -1793,27 +1935,21 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1793
1935
  }
1794
1936
  )
1795
1937
  ] }) }),
1796
- /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, max: 800, min: 400, size: sizes[1], children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames6__default.default("height-full"), children: [
1797
- /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: AgentHeader_default }),
1798
- /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, className: classNames6__default.default("full-scroll"), children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "center", vertical: true, gap: 24, className: classNames6__default.default("height-full p-t-8 p-b-8", styles_module_default.nsBodyWidth), children: [
1799
- common.shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(
1800
- common.RenderWrapper,
1801
- {
1802
- control: configState.layout.messageList,
1803
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(BubbleListItems_default, { avatar: { user: false, assistant: true } })
1804
- }
1805
- ) }),
1806
- /* @__PURE__ */ jsxRuntime.jsx(
1807
- common.RenderWrapper,
1808
- {
1809
- control: configState.layout.senderHeader,
1810
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default3.nsChatSenderHeader, children: [
1811
- "\u6211\u662F ",
1812
- agentState.active.name
1813
- ] })
1814
- }
1815
- ),
1938
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, max: 800, min: 400, size: sizes[1], children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames7__default.default("height-full"), children: [
1939
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: ChatHeader_default }),
1940
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, className: classNames7__default.default("full-scroll"), children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "center", vertical: true, gap: 24, className: classNames7__default.default("height-full p-t-8 p-b-8", styles_module_default2.nsBodyWidth), children: [
1941
+ common.shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.messageList, DefaultComponent: BubbleListItems_default }) }),
1816
1942
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, gap: 8, children: [
1943
+ /* @__PURE__ */ jsxRuntime.jsx(
1944
+ common.RenderWrapper,
1945
+ {
1946
+ control: configState.layout.senderHeader,
1947
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default4.nsChatSenderHeader, children: [
1948
+ "\u6211\u662F ",
1949
+ receiverState.active.name
1950
+ ] })
1951
+ }
1952
+ ),
1817
1953
  /* @__PURE__ */ jsxRuntime.jsx(
1818
1954
  common.RenderWrapper,
1819
1955
  {
@@ -1826,11 +1962,11 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1826
1962
  common.RenderWrapper,
1827
1963
  {
1828
1964
  control: configState.layout.disclaimerNotice,
1829
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default3.nsDisclaimerNotice, children: "\u5185\u5BB9\u7531AI\u751F\u6210\uFF0C\u4EC5\u4F9B\u53C2\u8003\uFF0C\u8BF7\u4ED4\u7EC6\u7504\u522B" })
1965
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default4.nsDisclaimerNotice, children: "\u5185\u5BB9\u7531AI\u751F\u6210\uFF0C\u4EC5\u4F9B\u53C2\u8003\uFF0C\u8BF7\u4ED4\u7EC6\u7504\u522B" })
1830
1966
  }
1831
1967
  )
1832
1968
  ] }),
1833
- /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.senderFooter, DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}) })
1969
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.senderFooter })
1834
1970
  ] }) })
1835
1971
  ] }) })
1836
1972
  ] })
@@ -1838,6 +1974,6 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1838
1974
  ] }) }) }) });
1839
1975
  });
1840
1976
 
1841
- exports.AgentChat = layouts_default;
1977
+ exports.ChatCopilot = layouts_default;
1842
1978
  //# sourceMappingURL=index.cjs.js.map
1843
1979
  //# sourceMappingURL=index.cjs.js.map