@zero-library/chat-agent 2.0.10 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,167 +311,53 @@ 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,
@@ -498,6 +370,19 @@ var defaultLayout = {
498
370
  chatHeader: true,
499
371
  disclaimerNotice: true
500
372
  };
373
+ var defaultExpertLayout = {
374
+ leftPanel: false,
375
+ conversationList: false,
376
+ preview: false,
377
+ messageList: true,
378
+ senderHeader: false,
379
+ sender: true,
380
+ senderPrompts: false,
381
+ senderFooter: false,
382
+ globalHeader: false,
383
+ chatHeader: false,
384
+ disclaimerNotice: false
385
+ };
501
386
  function createChatStore() {
502
387
  const config = valtio.proxy({
503
388
  hooks: {},
@@ -526,492 +411,487 @@ function createChatStore() {
526
411
  }
527
412
  }
528
413
  };
529
- const setLayout = (layout) => {
414
+ const setLayout = (layout, receiverType = 3) => {
415
+ const defaultLayout = receiverType === 3 ? defaultAgentLayout : defaultExpertLayout;
530
416
  config.layout = common.deepMerge(defaultLayout, layout);
531
417
  };
532
418
  const setConfigParams = (params = {}) => {
533
- config.params = { bizId: "", ...params };
419
+ config.params = { ...params };
534
420
  };
535
421
  const setHooks = (hooks = {}) => {
536
422
  config.hooks = hooks;
537
423
  };
538
- const getUserInfo = () => {
539
- config.userInfo = transform(common.getCurrentUser(), {
540
- id: "id",
424
+ const setUserInfo = (userInfo) => {
425
+ config.userInfo = transform(userInfo || common.getCurrentUser(), {
426
+ id: (userInfo2) => {
427
+ return String(userInfo2["id"]);
428
+ },
541
429
  name: "name",
542
430
  iconUrl: "avatar",
543
431
  description: "name"
544
432
  });
545
433
  };
546
- const agents = valtio.proxy({
547
- // 商品列表
434
+ const receiver = valtio.proxy({
435
+ active: {},
436
+ loading: false,
437
+ params: {}
438
+ // 透传参数,后期可能扩展不透传参数
439
+ });
440
+ const setReceiverParams = (params) => {
441
+ if (common.isObject(params)) {
442
+ Object.assign(receiver.params, params);
443
+ } else {
444
+ receiver.params = {};
445
+ }
446
+ };
447
+ const switchAgent = async (agentId) => {
448
+ if (receiver.active.id === agentId) return;
449
+ const canProceed = await config.hooks?.onBeforeSwitchAgent?.(agentId);
450
+ if (canProceed === false) return;
451
+ try {
452
+ receiver.loading = true;
453
+ const { data } = await agentInfoQuery(agentId);
454
+ receiver.active = transform(data, {
455
+ name: "agentName",
456
+ logo: "logo",
457
+ description: "description",
458
+ id: "id",
459
+ config: "config",
460
+ isAvailable: "isAvailable",
461
+ feature: (agentInfo) => {
462
+ if (agentInfo.feature) {
463
+ try {
464
+ return JSON.parse(agentInfo.feature);
465
+ } catch (e) {
466
+ }
467
+ }
468
+ return {};
469
+ }
470
+ });
471
+ receiver.active.type = 3;
472
+ setReceiverParams();
473
+ if (receiver.active.feature?.deepThink) {
474
+ setReceiverParams({ thinkMode: "2" });
475
+ }
476
+ config.hooks?.onAfterSwitchAgent?.(agentId);
477
+ } finally {
478
+ receiver.loading = false;
479
+ }
480
+ };
481
+ const switchExpert = (expert) => {
482
+ if (receiver.active.id === expert.memberId) return;
483
+ receiver.active = transform(expert, {
484
+ name: "memberName",
485
+ logo: "memberAvatar",
486
+ id: "memberId"
487
+ });
488
+ receiver.active.type = 2;
489
+ setReceiverParams();
490
+ };
491
+ const character = valtio.proxy({
548
492
  list: [],
549
- loading: false
493
+ active: {},
494
+ open: false,
495
+ loading: false,
496
+ switchLoading: false
550
497
  });
551
- const getAgentList = async () => {
498
+ const getCharacters = async (agentId) => {
552
499
  try {
553
- agents.loading = true;
554
- const { data } = await agentsQuery();
555
- agents.list = data;
500
+ character.loading = true;
501
+ const res = await agentCharacterQuery(agentId);
502
+ if (receiver.active.id !== agentId) return;
503
+ character.list = res.data;
504
+ character.active = res.data.find((item) => item.selected);
556
505
  } finally {
557
- agents.loading = false;
506
+ character.loading = false;
507
+ }
508
+ };
509
+ const openCharacterList = () => {
510
+ character.open = true;
511
+ };
512
+ const closeCharacterList = () => {
513
+ character.open = false;
514
+ };
515
+ const switchCharacter = async (c) => {
516
+ if (!c.id) return;
517
+ try {
518
+ character.switchLoading = true;
519
+ await agentCharacterSelect(receiver.active.id, c.id);
520
+ character.active = { ...c };
521
+ closeCharacterList();
522
+ } finally {
523
+ character.switchLoading = false;
524
+ }
525
+ };
526
+ const conversations = valtio.proxy({
527
+ list: {
528
+ items: [],
529
+ params: {
530
+ pageNum: 1,
531
+ pageSize: 1e3
532
+ }
533
+ },
534
+ updateIndex: 0,
535
+ // 当前会话索引, 创建会话时更新,促使页面更新会话列表
536
+ loading: false,
537
+ delLoading: false
538
+ });
539
+ const getConversations = async (targetId, targetType) => {
540
+ try {
541
+ conversations.loading = true;
542
+ const { data } = await conversationsQuery({
543
+ targetId,
544
+ targetType,
545
+ businessId: config.params.businessId,
546
+ businessType: config.params.businessType,
547
+ ...conversations.list.params
548
+ });
549
+ if (receiver.active.id !== targetId) return;
550
+ const items = transforms(data?.items || [], {
551
+ key: "id",
552
+ id: "id",
553
+ label: "title",
554
+ group: (c) => {
555
+ return classifyTime(c.updateTime);
556
+ },
557
+ timestamp: "updateTime"
558
+ });
559
+ conversations.list.items = items;
560
+ } finally {
561
+ conversations.loading = false;
562
+ }
563
+ };
564
+ const delConversation = async (conversationId) => {
565
+ try {
566
+ const canProceed = await config.hooks?.onBeforeDelConversation?.(conversationId);
567
+ if (canProceed === false) return;
568
+ conversations.delLoading = true;
569
+ await conversationDelete(conversationId);
570
+ antd.message.success("\u5220\u9664\u6210\u529F");
571
+ conversations.list.items = conversations.list.items.filter((item) => item.key !== conversationId);
572
+ delete conversation.messages[conversationId];
573
+ if (conversation.active.id === conversationId) {
574
+ createAgentConversation();
575
+ }
576
+ config.hooks?.onAfterDelConversation?.(conversationId, conversation.active.id === conversationId);
577
+ } finally {
578
+ conversations.delLoading = false;
558
579
  }
559
580
  };
560
581
  const conversation = valtio.proxy({
561
582
  // 每个会话单独存储
562
- active: {},
563
- messages: {}
564
- // feedback: {
565
- // open: false,
566
- // loading: false,
567
- // recordId: '',
568
- // target: undefined as number | undefined
569
- // }
583
+ active: {
584
+ id: "",
585
+ member: {}
586
+ },
587
+ messages: {},
588
+ feedback: {
589
+ // open: false,
590
+ loading: false
591
+ // recordId: '',
592
+ // target: undefined as number | undefined
593
+ }
570
594
  });
595
+ const setSpeakHuman = (speakHuman) => {
596
+ conversation.messages[conversation.active.id].speakHuman = speakHuman;
597
+ };
571
598
  const setReferences = (references) => {
572
- conversation.messages[conversation.active.key].references = references;
599
+ conversation.messages[conversation.active.id].references = references;
573
600
  };
574
601
  const setContent = (content) => {
575
- conversation.messages[conversation.active.key].content = content;
602
+ conversation.messages[conversation.active.id].content = content;
576
603
  };
577
604
  const setFileList = (files = []) => {
578
- conversation.messages[conversation.active.key].files = files;
605
+ conversation.messages[conversation.active.id].files = files;
579
606
  };
580
607
  const setHeaderOpen = (headerOpen) => {
581
- conversation.messages[conversation.active.key].headerOpen = headerOpen;
608
+ conversation.messages[conversation.active.id].headerOpen = headerOpen;
582
609
  };
583
- const removeQuestionList = (key) => {
584
- if (conversation.messages[key].questionList?.length) {
585
- conversation.messages[key].questionList = [];
610
+ const removeQuestionList = (conversationId) => {
611
+ if (conversation.messages[conversationId].questionList?.length) {
612
+ conversation.messages[conversationId].questionList = [];
586
613
  }
587
614
  };
588
- const getQuestionList = async (conversationId, message4) => {
589
- if (!message4.id || !message4.content) return;
590
- const { data } = await chatMessageSuggestedQuery(agent.active.id, message4.id);
615
+ const getQuestionList = async (conversationId, messageId) => {
616
+ const messages = conversation.messages[conversationId]?.message;
617
+ if (!messages?.length) return;
618
+ let lastMessage = messages[messages.length - 1];
619
+ if (!lastMessage || lastMessage.sender.type !== 3 || lastMessage.id !== messageId) return;
620
+ const { data } = await messageSuggestedQuery(messageId);
621
+ lastMessage = messages[messages.length - 1];
622
+ if (lastMessage.id !== messageId) return;
591
623
  conversation.messages[conversationId].questionList = data;
592
624
  };
593
- const feedback = async (conversationId, messageId, rating, index) => {
625
+ const feedback = async (conversationId, messageId, msgFeedback, index) => {
594
626
  try {
595
- await updateFeedback({ agentId: agent.active.id, messageId, rating, bizId: config.params.bizId });
596
- conversation.messages[conversationId].message.items[index].feedback = rating;
627
+ conversation.feedback.loading = true;
628
+ await feedbackUpdate({ conversationId, id: messageId, msgFeedback });
629
+ antd.message.success("\u611F\u8C22\u60A8\u7684\u53CD\u9988");
630
+ conversation.messages[conversationId].message[index].msgFeedback = msgFeedback;
597
631
  } finally {
632
+ conversation.feedback.loading = false;
598
633
  }
599
634
  };
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] = {
635
+ const setInitMessage = async (conversationId) => {
636
+ conversation.messages[conversationId] = {
611
637
  content: "",
612
638
  files: [],
613
639
  // 上传文件内容
614
640
  headerOpen: false,
615
641
  loading: false,
616
- message: {
617
- lastId: "",
618
- hasMore: false,
619
- items: []
620
- },
642
+ message: [],
621
643
  questionList: []
622
644
  // 推荐问题
623
645
  };
624
646
  };
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);
647
+ const resolveConversationId = async (receiverId, strategy = 2) => {
648
+ if (strategy === 1) {
649
+ const { data } = await conversationRecentQuery({
650
+ receiverId,
651
+ receiverType: 3,
652
+ businessId: config.params.businessId,
653
+ businessType: config.params.businessType
654
+ });
655
+ return data;
656
+ } else {
657
+ const { data } = await conversationCreate({
658
+ receiverId,
659
+ receiverType: 3,
660
+ businessId: config.params.businessId,
661
+ businessType: config.params.businessType,
662
+ businessData: config.params.businessData,
663
+ source: config.params.source,
664
+ type: 1
665
+ });
666
+ conversations.updateIndex = conversations.updateIndex + 1;
667
+ return data;
668
668
  }
669
669
  };
670
- const getConversations = async (agentId, lastId, limit = 20) => {
670
+ const initConversation = async (conversationId) => {
671
671
  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"
672
+ const { data } = await conversationMemberQuery(conversationId);
673
+ conversation.active = { id: conversationId, member: {} };
674
+ data.forEach((member) => {
675
+ if (member.memberType === 3) {
676
+ conversation.active.member.agent = member;
677
+ } else {
678
+ if (member.memberId === config.userInfo.id) {
679
+ conversation.active.member.user = member;
680
+ } else {
681
+ conversation.active.member.other = member;
682
+ }
683
+ }
682
684
  });
683
- conversations.list = {
684
- ...data,
685
- items: lastId ? [...conversations.list.items, ...items] : items
686
- };
687
685
  } finally {
688
- conversations.loading = false;
689
686
  }
690
687
  };
691
- const getMessages = async (agentId, conversationId, lastId) => {
688
+ const switchAgentConversation = async (agentId, strategy) => {
689
+ await switchAgent(agentId);
690
+ const conversationId = await resolveConversationId(agentId, strategy);
692
691
  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
- }
692
+ switchConversation(conversationId);
717
693
  }
718
694
  };
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;
695
+ const createAgentConversation = async () => {
696
+ const conversationId = await resolveConversationId(receiver.active.id);
697
+ if (conversationId) {
698
+ switchConversation(conversationId);
733
699
  }
734
700
  };
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
- }
701
+ const switchConversation = async (conversationId) => {
702
+ if (conversation.active.id === conversationId) return;
703
+ const canProceed = await config.hooks?.onBeforeSwitchConversation?.(conversationId);
704
+ if (canProceed === false) return;
705
+ await initConversation(conversationId);
706
+ setPreview();
707
+ config.hooks?.onAfterSwitchConversation?.(conversationId);
708
+ getMessages(conversationId);
709
+ if (conversation.active.member.agent) {
710
+ switchAgent(conversation.active.member.agent.memberId);
711
+ } else if (conversation.active.member.other) {
712
+ switchExpert(conversation.active.member.other);
741
713
  }
742
714
  };
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";
715
+ const getMessages = async (conversationId) => {
716
+ const canProceed = await config.hooks?.onBeforeInitMessages?.(conversationId);
717
+ if (canProceed === false) return;
718
+ if (!conversation.messages[conversationId]) {
719
+ setInitMessage(conversationId);
772
720
  }
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);
721
+ if (conversation.messages[conversationId].message.length === 0) {
722
+ try {
723
+ const { data } = await conversationMessagesQuery({
724
+ pageNo: 1,
725
+ pageSize: 1e3,
726
+ conversationId
727
+ });
728
+ conversation.messages[conversationId].message = data.items;
729
+ } finally {
730
+ }
731
+ config.hooks?.onAfterInitMessages?.(conversation.messages[conversationId].message);
779
732
  }
780
- conversation.messages[chunk.conversationId].loading = false;
781
733
  };
782
- const sendMessage = async (message4, files = [], params) => {
783
- const conversationId = conversation.active.key;
734
+ const pickReceiver = () => {
735
+ const { agent, other } = conversation.active.member;
736
+ if (conversation.messages[conversation.active.id].speakHuman && other) return other;
737
+ if (agent) return agent;
738
+ if (other) return other;
739
+ return void 0;
740
+ };
741
+ const sendMessage = async (message3, files = [], params) => {
742
+ const conversationId = conversation.active.id;
784
743
  if (conversation.messages[conversationId].loading) return;
785
- let newMsgContent = "", newImgList;
744
+ let msgContent = "", msgFiles;
786
745
  const references = conversation.messages[conversationId].references;
787
- if (message4) {
788
- newMsgContent = message4;
789
- newImgList = files;
746
+ if (message3) {
747
+ msgContent = message3;
748
+ msgFiles = files;
790
749
  } else {
791
750
  if (references?.type === 1 && references?.content?.markdown) {
792
- newMsgContent = references.content.markdown + "\n";
751
+ msgContent = references.content.markdown + "\n";
793
752
  }
794
- newMsgContent = newMsgContent + conversation.messages[conversationId].content;
795
- newImgList = conversation.messages[conversationId].files;
753
+ msgContent = msgContent + conversation.messages[conversationId].content;
754
+ msgFiles = conversation.messages[conversationId].files;
796
755
  }
797
- if (!newMsgContent) return;
798
- const canProceed = await config.hooks?.onBeforeSend?.(newMsgContent, newImgList);
756
+ if (!msgContent) return;
757
+ const canProceed = await config.hooks?.onBeforeSend?.(msgContent, msgFiles);
799
758
  if (canProceed === false) return;
800
759
  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"
807
- };
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
760
+ const sendReceiver = pickReceiver();
761
+ const sendParams = {
762
+ conversationId,
763
+ msgContent,
764
+ msgFiles,
765
+ // quoteMsgId
766
+ receiverId: sendReceiver.memberId,
767
+ receiverType: sendReceiver.memberType,
768
+ returnType: 2,
769
+ senderId: conversation.active.member.user.memberId,
770
+ senderType: conversation.active.member.user.memberType,
771
+ source: config.params.source,
772
+ stream: true
818
773
  };
819
- if (!extraParams.params) {
820
- extraParams.params = {};
821
- }
822
- Object.assign(extraParams.params, agent.params, message4 ? {} : references?.params, params);
823
- if (!message4) {
774
+ const extraParams = common.deepCopy(config.params.params || {});
775
+ Object.assign(extraParams, receiver.params, message3 ? {} : references?.params, params);
776
+ sendParams.params = JSON.stringify(extraParams);
777
+ if (!message3) {
824
778
  setContent("");
825
779
  setFileList([]);
826
780
  setReferences();
827
781
  setHeaderOpen(false);
828
782
  }
829
- removeQuestionList(conversationId);
830
783
  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
- });
784
+ await conversationMessageSend(sendParams);
841
785
  config.hooks?.onAfterSend?.();
842
- } catch (error) {
843
- removePlaceholder(conversationId, placeholderId);
786
+ } finally {
844
787
  conversation.messages[conversationId].loading = false;
845
788
  }
846
789
  };
847
- const cancelReceive = () => {
848
- conversation.messages[conversation.active.key].loading = false;
790
+ const cancelReceive = async () => {
791
+ await conversationStop(conversation.active.id);
792
+ };
793
+ const updateConversationTitle = (conversationId, title) => {
794
+ const idx = conversations.list.items.findIndex((item) => item.id === conversationId);
795
+ if (idx === -1) return;
796
+ conversations.list.items[idx].title = title;
797
+ };
798
+ const findMsgIndex = (conversationId, msgId) => {
799
+ const messages = conversation.messages[conversationId]?.message || [];
800
+ return messages.findLastIndex((item) => item.id === msgId);
801
+ };
802
+ const startCallback = (msg) => {
803
+ if (msg.conversationTitle && conversations.list.items.length) {
804
+ updateConversationTitle(msg.conversationId, msg.conversationTitle);
805
+ }
806
+ removeQuestionList(msg.conversationId);
807
+ const messages = conversation.messages[msg.conversationId].message;
808
+ messages.push(msg.sender.type === 3 ? { ...msg, msgContent: "\u6B63\u5728\u52AA\u529B\u601D\u8003\u4E2D" } : msg);
809
+ conversation.messages[msg.conversationId].loading = true;
810
+ };
811
+ const stepCallback = (msg) => {
812
+ const messages = conversation.messages[msg.conversationId].message;
813
+ const idx = findMsgIndex(msg.conversationId, msg.id);
814
+ if (idx === -1) return;
815
+ messages[idx] = msg;
816
+ conversation.messages[msg.conversationId].loading = true;
817
+ };
818
+ const contentCallback = (msg) => {
819
+ const messages = conversation.messages[msg.conversationId].message;
820
+ const idx = findMsgIndex(msg.conversationId, msg.id);
821
+ if (idx === -1) return;
822
+ const message3 = messages[idx];
823
+ conversation.messages[msg.conversationId].loading = true;
824
+ if (message3?.type === "STEP_STARTED" || message3?.type === "TEXT_MESSAGE_START") {
825
+ messages[idx] = msg;
826
+ return;
827
+ }
828
+ messages[idx] = {
829
+ ...message3,
830
+ msgContent: message3.msgContent + (msg.msgContent || "")
831
+ };
832
+ };
833
+ const endCallback = (msg) => {
834
+ const messages = conversation.messages[msg.conversationId].message;
835
+ const idx = findMsgIndex(msg.conversationId, msg.id);
836
+ if (idx === -1) return;
837
+ messages[idx] = { ...messages[idx], type: void 0 };
838
+ conversation.messages[msg.conversationId].loading = false;
839
+ getQuestionList(msg.conversationId, msg.id);
840
+ };
841
+ const acceptMessage = (newMessage) => {
842
+ const conversationId = newMessage.data.conversationId;
843
+ if (!conversation.messages[conversationId]?.message) return;
844
+ switch (newMessage.data.type) {
845
+ case "TEXT_MESSAGE_START":
846
+ startCallback(newMessage.data);
847
+ break;
848
+ case "STEP_STARTED":
849
+ stepCallback(newMessage.data);
850
+ break;
851
+ case "TEXT_MESSAGE_CONTENT":
852
+ contentCallback(newMessage.data);
853
+ break;
854
+ case "TEXT_MESSAGE_END":
855
+ endCallback(newMessage.data);
856
+ break;
857
+ }
849
858
  };
850
859
  return {
851
860
  config,
861
+ setPreview,
852
862
  setLayout,
853
863
  setHooks,
854
864
  setConfigParams,
855
- setPreview,
856
- getUserInfo,
857
- agents,
858
- getAgentList,
865
+ setUserInfo,
866
+ character,
867
+ getCharacters,
868
+ openCharacterList,
869
+ closeCharacterList,
870
+ switchCharacter,
871
+ receiver,
872
+ setReceiverParams,
873
+ conversations,
874
+ getConversations,
875
+ delConversation,
859
876
  conversation,
877
+ setSpeakHuman,
860
878
  setReferences,
861
879
  setContent,
862
880
  setFileList,
863
881
  setHeaderOpen,
864
- removeQuestionList,
865
- getQuestionList,
866
882
  feedback,
867
- conversations,
868
- setInitMessage,
869
- agent,
870
- setAgentParams,
871
- switchAgent,
872
- getConversations,
873
- getMessages,
883
+ switchAgentConversation,
884
+ createAgentConversation,
874
885
  switchConversation,
875
- delConversation,
876
- removePlaceholder,
877
886
  sendMessage,
878
- cancelReceive
887
+ cancelReceive,
888
+ acceptMessage
879
889
  };
880
890
  }
881
891
 
882
892
  // src/ui/layouts/index.tsx
883
893
  init_Context();
884
894
 
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
895
  // src/ui/common/markdownAlert/index.ts
1016
896
  var customComponents = {
1017
897
  appCard: () => Promise.resolve().then(() => (init_AppCard(), AppCard_exports)),
@@ -1021,10 +901,10 @@ var customComponents = {
1021
901
  fileEdit: () => Promise.resolve().then(() => (init_FileEdit(), FileEdit_exports)),
1022
902
  quoteList: () => Promise.resolve().then(() => (init_QuoteList(), QuoteList_exports))
1023
903
  };
1024
- var MessageRender_default = ({ message: message4, placement }) => {
904
+ var MessageRender_default = ({ message: message3, placement }) => {
1025
905
  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(
906
+ message3.msgContent && /* @__PURE__ */ jsxRuntime.jsx(x.Bubble, { placement, content: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: message3.msgContent, customComponents }) }),
907
+ message3.msgFiles?.map((file) => /* @__PURE__ */ jsxRuntime.jsx(
1028
908
  x.Bubble,
1029
909
  {
1030
910
  className: "m-t-8",
@@ -1034,22 +914,57 @@ var MessageRender_default = ({ message: message4, placement }) => {
1034
914
  x.Attachments.FileCard,
1035
915
  {
1036
916
  item: {
1037
- uid: file.id,
917
+ uid: file.content,
1038
918
  name: file.name,
1039
- url: file.url
919
+ url: file.content
1040
920
  }
1041
921
  },
1042
- index
922
+ file.content
1043
923
  )
1044
924
  },
1045
- index
925
+ file.content
1046
926
  ))
1047
927
  ] });
1048
928
  };
1049
929
 
930
+ // src/core/constants.ts
931
+ var MEMBER_TYPE = {
932
+ 1: "user",
933
+ 2: "other",
934
+ 3: "agent"
935
+ };
936
+
1050
937
  // src/ui/common/BubbleListItems.tsx
1051
938
  init_utils();
1052
939
  init_Context();
940
+
941
+ // src/ui/common/styles.module.less
942
+ var styles_module_default2 = {
943
+ loadingMessage: "styles_module_loadingMessage",
944
+ conversationListPanel: "styles_module_conversationListPanel",
945
+ nsConversations: "styles_module_nsConversations",
946
+ nsBodyWidth: "styles_module_nsBodyWidth",
947
+ nsBubbleList: "styles_module_nsBubbleList",
948
+ nsChatHeader: "styles_module_nsChatHeader",
949
+ nsChatTitle: "styles_module_nsChatTitle",
950
+ nsChatHeaderPopover: "styles_module_nsChatHeaderPopover",
951
+ chatWelcomeWrap: "styles_module_chatWelcomeWrap",
952
+ chatWelcome: "styles_module_chatWelcome",
953
+ chatWelcomePrompts: "styles_module_chatWelcomePrompts",
954
+ senderListTitle: "styles_module_senderListTitle",
955
+ senderList: "styles_module_senderList",
956
+ senderListItem: "styles_module_senderListItem",
957
+ senderListFooter: "styles_module_senderListFooter",
958
+ nsChatUserName: "styles_module_nsChatUserName",
959
+ nsSenderReferenceHeaderTitle: "styles_module_nsSenderReferenceHeaderTitle",
960
+ nsSenderReferenceHeaderContent: "styles_module_nsSenderReferenceHeaderContent",
961
+ avatarListContainer: "styles_module_avatarListContainer",
962
+ avatarList: "styles_module_avatarList",
963
+ avatarListItem: "styles_module_avatarListItem",
964
+ avatarListItemIcon: "styles_module_avatarListItemIcon",
965
+ avatarListItemIconActive: "styles_module_avatarListItemIconActive",
966
+ avatarListItemName: "styles_module_avatarListItemName"
967
+ };
1053
968
  function extractThinkContent(content) {
1054
969
  let main = content;
1055
970
  const thinkContents = [];
@@ -1075,20 +990,19 @@ function renderMarkdownPanel(content, label, key) {
1075
990
  children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content, customComponents })
1076
991
  };
1077
992
  }
1078
- var MessageAIRender_default = ({ message: message4, placement }) => {
993
+ var MessageAIRender_default = ({ message: message3, placement }) => {
1079
994
  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) {
995
+ if (!message3?.msgContent) return { mainContent: "", thinkContents: [], thinkBuffer: "" };
996
+ return extractThinkContent(message3.msgContent);
997
+ }, [message3?.msgContent]);
998
+ if (!message3.msgContent) {
1085
999
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Typography, { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { size: "small" }) });
1086
1000
  }
1087
1001
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1088
1002
  x.Bubble,
1089
1003
  {
1090
1004
  placement,
1091
- className: classNames6__default.default({ [styles_module_default.loadingMessage]: message4.status === "loading" }),
1005
+ className: classNames7__default.default({ [styles_module_default2.loadingMessage]: message3.type && message3.type !== "TEXT_MESSAGE_END" }),
1092
1006
  content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1093
1007
  thinkContents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1094
1008
  antd.Collapse,
@@ -1108,54 +1022,67 @@ var MessageAIRender_default = ({ message: message4, placement }) => {
1108
1022
  items: [renderMarkdownPanel(thinkBuffer, "\u4ED4\u7EC6\u601D\u8003\u4E2D...", "buffer-think")]
1109
1023
  }
1110
1024
  ),
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 })
1025
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderMarkdown, { content: mainContent, customComponents })
1116
1026
  ] })
1117
1027
  }
1118
1028
  ) });
1119
1029
  };
1120
- var BubbleListItems_default = ({ avatar = true }) => {
1030
+ var BubbleListItems_default = ({ avatar = { user: false, agent: true, other: true } }) => {
1121
1031
  const chatStore = useChatStore();
1122
- const agentState = valtio.useSnapshot(chatStore.agent);
1032
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1123
1033
  const conversationState = valtio.useSnapshot(chatStore.conversation);
1124
- const configState = valtio.useSnapshot(chatStore.config);
1125
1034
  const conversationRoles = react.useMemo(() => {
1126
- return {
1127
- user: {
1035
+ const roles = {};
1036
+ if (conversationState.active.member.user) {
1037
+ roles.user = {
1128
1038
  user: "user",
1129
1039
  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",
1040
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.user) ? /* @__PURE__ */ jsxRuntime.jsx(
1041
+ common.UserAvatar,
1042
+ {
1043
+ size: 30,
1044
+ avatarSrc: conversationState.active.member.user?.memberAvatar,
1045
+ userName: conversationState.active.member.user?.memberName
1046
+ }
1047
+ ) : null
1048
+ };
1049
+ }
1050
+ if (conversationState.active.member.agent) {
1051
+ roles.agent = {
1052
+ user: "agent",
1134
1053
  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]);
1054
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.agent) ? { src: conversationState.active.member.agent?.memberAvatar, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.OpenAIOutlined, {}) } : null
1055
+ };
1056
+ }
1057
+ if (conversationState.active.member.other) {
1058
+ roles.other = {
1059
+ user: "other",
1060
+ placement: "start",
1061
+ avatar: (common.isBoolean(avatar) ? avatar : avatar?.other) ? { src: conversationState.active.member.other?.memberAvatar, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.OpenAIOutlined, {}) } : null
1062
+ };
1063
+ }
1064
+ return roles;
1065
+ }, [conversationState.active.member, avatar]);
1139
1066
  const chatMessage = react.useMemo(
1140
- () => conversationState.messages[conversationState.active.key] || {},
1141
- [conversationState.messages[conversationState.active.key]]
1067
+ () => conversationState.messages[conversationState.active.id] || {},
1068
+ [conversationState.messages[conversationState.active.id]]
1142
1069
  );
1143
1070
  const placeholderNode = react.useMemo(
1144
1071
  () => [
1145
1072
  {
1146
1073
  key: "placeholder",
1147
- content: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { direction: "vertical", size: 16, className: styles_module_default.chatWelcomeWrap, children: [
1074
+ content: /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { direction: "vertical", size: 16, className: styles_module_default2.chatWelcomeWrap, children: [
1148
1075
  /* @__PURE__ */ jsxRuntime.jsx(
1149
1076
  x.Welcome,
1150
1077
  {
1151
- className: classNames6__default.default(styles_module_default.chatWelcome, "p-t-32"),
1078
+ className: classNames7__default.default(styles_module_default2.chatWelcome, "p-t-32"),
1152
1079
  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 || ""
1080
+ icon: /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { shape: "square", size: 58, src: receiverState.active.logo }),
1081
+ title: `\u4F60\u597D\uFF0C\u6211\u662F${receiverState.active.name || ""}`,
1082
+ description: /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: receiverState.active.description || "" } })
1156
1083
  }
1157
1084
  ),
1158
- agentState.active.recommendQuestions?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1085
+ receiverState.active.config?.recommendQuestions?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1159
1086
  x.Prompts,
1160
1087
  {
1161
1088
  className: "m-t-16",
@@ -1164,9 +1091,9 @@ var BubbleListItems_default = ({ avatar = true }) => {
1164
1091
  {
1165
1092
  key: "1",
1166
1093
  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 })
1094
+ children: receiverState.active.config.recommendQuestions.map(({ question }) => ({
1095
+ key: question,
1096
+ description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.sendMessage(question), className: classNames7__default.default(styles_module_default2.chatWelcomePrompts, "text-ellipsis"), children: question })
1170
1097
  }))
1171
1098
  }
1172
1099
  ]
@@ -1176,7 +1103,7 @@ var BubbleListItems_default = ({ avatar = true }) => {
1176
1103
  variant: "borderless"
1177
1104
  }
1178
1105
  ],
1179
- [agentState.active]
1106
+ [receiverState.active]
1180
1107
  );
1181
1108
  const questionList = react.useMemo(
1182
1109
  () => chatMessage?.questionList?.length ? [
@@ -1192,8 +1119,8 @@ var BubbleListItems_default = ({ avatar = true }) => {
1192
1119
  }
1193
1120
  },
1194
1121
  vertical: true,
1195
- items: chatMessage?.questionList.map(({ question, id }) => ({
1196
- key: id,
1122
+ items: chatMessage?.questionList.map((question) => ({
1123
+ key: question,
1197
1124
  description: /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: () => chatStore.sendMessage(question), children: question })
1198
1125
  }))
1199
1126
  }
@@ -1205,36 +1132,37 @@ var BubbleListItems_default = ({ avatar = true }) => {
1205
1132
  [chatMessage?.questionList]
1206
1133
  );
1207
1134
  const chatRecords = react.useMemo(() => {
1208
- return (chatMessage?.message?.items || []).map((message4, index) => {
1135
+ return (chatMessage?.message || []).map((message3, index) => {
1136
+ const role = conversationRoles[MEMBER_TYPE[message3.sender.type]];
1209
1137
  return {
1210
- key: message4.id || -index,
1211
- placement: conversationRoles[message4.role].placement,
1138
+ key: message3.id,
1139
+ placement: role.placement,
1212
1140
  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 }),
1141
+ avatar: role.avatar,
1142
+ 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
1143
  // 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, {}) }),
1144
+ footer: role.user === "agent" && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { children: [
1145
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { onClick: () => copy(message3.msgContent), color: "default", variant: "text", size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CopyOutlined, {}) }),
1218
1146
  /* @__PURE__ */ jsxRuntime.jsx(
1219
1147
  antd.Button,
1220
1148
  {
1221
- color: message4.feedback === "like" ? "primary" : "default",
1222
- disabled: message4.status === "loading",
1149
+ color: message3.msgFeedback === 1 ? "primary" : "default",
1150
+ disabled: !!message3.type,
1223
1151
  size: "small",
1224
1152
  variant: "text",
1225
1153
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LikeOutlined, {}),
1226
- onClick: () => chatStore.feedback(conversationState.active.key, message4.id, "like", index)
1154
+ onClick: () => chatStore.feedback(conversationState.active.id, message3.id, 1, index)
1227
1155
  }
1228
1156
  ),
1229
1157
  /* @__PURE__ */ jsxRuntime.jsx(
1230
1158
  antd.Button,
1231
1159
  {
1232
- color: message4.feedback === "dislike" ? "primary" : "default",
1233
- disabled: message4.status === "loading",
1160
+ color: message3.msgFeedback === 2 ? "primary" : "default",
1161
+ disabled: !!message3.type,
1234
1162
  size: "small",
1235
1163
  variant: "text",
1236
1164
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DislikeOutlined, {}),
1237
- onClick: () => chatStore.feedback(conversationState.active.key, message4.id, "dislike", index)
1165
+ onClick: () => chatStore.feedback(conversationState.active.id, message3.id, 2, index)
1238
1166
  }
1239
1167
  )
1240
1168
  ] })
@@ -1284,16 +1212,193 @@ var BubbleListItems_default = ({ avatar = true }) => {
1284
1212
  autoScroll: false,
1285
1213
  ref: listRef,
1286
1214
  items: bubbleListItems,
1287
- className: classNames6__default.default(styles_module_default.nsBubbleList, "height-full", "scroll-fade-in"),
1215
+ className: classNames7__default.default(styles_module_default2.nsBubbleList, "height-full", "scroll-fade-in"),
1288
1216
  onScroll: handleScroll
1289
1217
  },
1290
- conversationState.active.key
1218
+ conversationState.active.id
1291
1219
  );
1292
1220
  };
1293
1221
 
1294
- // src/components/Attachments.tsx
1295
- init_utils();
1296
- var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSizeTip, fileList = [], onChange, extraParams }, ref) => {
1222
+ // src/ui/common/ChatHeader.tsx
1223
+ init_Context();
1224
+
1225
+ // src/ui/common/AgentCharacter.tsx
1226
+ init_Context();
1227
+
1228
+ // src/ui/common/CharacterList.tsx
1229
+ init_Context();
1230
+ var CharacterList_default = () => {
1231
+ const chatStore = useChatStore();
1232
+ const characterState = valtio.useSnapshot(chatStore.character);
1233
+ const [activeCharacter, setActiveCharacter] = react.useState(characterState.active);
1234
+ return /* @__PURE__ */ jsxRuntime.jsx(
1235
+ antd.Modal,
1236
+ {
1237
+ width: 500,
1238
+ title: "\u9009\u62E9\u6027\u683C",
1239
+ maskClosable: false,
1240
+ open: characterState.open,
1241
+ onCancel: chatStore.closeCharacterList,
1242
+ loading: characterState.loading,
1243
+ okText: "\u5207\u6362\u6027\u683C",
1244
+ onOk: () => chatStore.switchCharacter(activeCharacter),
1245
+ confirmLoading: characterState.switchLoading,
1246
+ 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: [
1247
+ /* @__PURE__ */ jsxRuntime.jsx(
1248
+ antd.Avatar,
1249
+ {
1250
+ className: classNames7__default.default(styles_module_default2.avatarListItemIcon, "cursor-pointer", {
1251
+ [styles_module_default2.avatarListItemIconActive]: activeCharacter.id === item.id
1252
+ }),
1253
+ size: 50,
1254
+ src: /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.logo, alt: "\u5934\u50CF" })
1255
+ }
1256
+ ),
1257
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default2.avatarListItemName, children: item.characterName })
1258
+ ] }) }, item.id)) }) })
1259
+ }
1260
+ );
1261
+ };
1262
+ var AgentCharacter_default = () => {
1263
+ const chatStore = useChatStore();
1264
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1265
+ const characterState = valtio.useSnapshot(chatStore.character);
1266
+ react.useEffect(() => {
1267
+ if (receiverState.active.id && receiverState.active.type === 3) {
1268
+ chatStore.getCharacters(receiverState.active.id);
1269
+ }
1270
+ }, [receiverState.active.id]);
1271
+ return characterState.active.id && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1272
+ /* @__PURE__ */ jsxRuntime.jsx("div", { title: "\u6027\u683C", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { onClick: chatStore.openCharacterList, className: "cursor-pointer", src: characterState.active.logo }) }),
1273
+ characterState.open && /* @__PURE__ */ jsxRuntime.jsx(CharacterList_default, {})
1274
+ ] });
1275
+ };
1276
+
1277
+ // src/ui/common/ConversationList.tsx
1278
+ init_Context();
1279
+ var ConversationList_default = () => {
1280
+ const chatStore = useChatStore();
1281
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1282
+ const conversationsState = valtio.useSnapshot(chatStore.conversations);
1283
+ const conversationState = valtio.useSnapshot(chatStore.conversation);
1284
+ const getConversations = common.useDebounce(() => {
1285
+ chatStore.getConversations(receiverState.active.id, 3);
1286
+ }, 300);
1287
+ react.useEffect(() => {
1288
+ if (receiverState.active.id) {
1289
+ getConversations();
1290
+ }
1291
+ }, [receiverState.active.id, conversationsState.updateIndex]);
1292
+ const conversationList = react.useMemo(() => {
1293
+ return conversationsState.list.items.filter((item) => item.label);
1294
+ }, [conversationsState.list.items]);
1295
+ 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(
1296
+ InfiniteScroll__default.default,
1297
+ {
1298
+ dataLength: conversationList.length,
1299
+ next: () => {
1300
+ console.log("next");
1301
+ },
1302
+ hasMore: false,
1303
+ loader: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { indicator: /* @__PURE__ */ jsxRuntime.jsx(icons.RedoOutlined, { spin: true }), size: "small" }) }),
1304
+ style: { overflow: "hidden" },
1305
+ scrollableTarget: "scrollableDiv",
1306
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1307
+ x.Conversations,
1308
+ {
1309
+ className: styles_module_default2.nsConversations,
1310
+ items: conversationList,
1311
+ activeKey: conversationState.active.id,
1312
+ onActiveChange: async (id) => chatStore.switchConversation(id),
1313
+ groupable: true,
1314
+ menu: (conversation) => ({
1315
+ items: [
1316
+ {
1317
+ label: "\u5220\u9664\u4F1A\u8BDD",
1318
+ key: "delete",
1319
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DeleteOutlined, {}),
1320
+ danger: true
1321
+ }
1322
+ ],
1323
+ onClick: (menuInfo) => {
1324
+ menuInfo.domEvent.stopPropagation();
1325
+ if (menuInfo.key === "delete") {
1326
+ chatStore.delConversation(conversation.id);
1327
+ }
1328
+ }
1329
+ })
1330
+ }
1331
+ )
1332
+ }
1333
+ ) : /* @__PURE__ */ jsxRuntime.jsx(antd.Empty, { description: "\u6682\u65E0\u4F1A\u8BDD\u8BB0\u5F55", image: antd.Empty.PRESENTED_IMAGE_SIMPLE }) }) });
1334
+ };
1335
+ var ChatHeader_default = ({
1336
+ title = true,
1337
+ closeBtn = false,
1338
+ newConversationBtn = true,
1339
+ agentCharacter = true,
1340
+ conversationListBtn = true
1341
+ }) => {
1342
+ const chatStore = useChatStore();
1343
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1344
+ const configState = valtio.useSnapshot(chatStore.config);
1345
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", className: styles_module_default2.nsChatHeader, children: [
1346
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, align: "center", children: [
1347
+ /* @__PURE__ */ jsxRuntime.jsx(
1348
+ common.RenderWrapper,
1349
+ {
1350
+ control: title,
1351
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1352
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 22, src: receiverState.active.logo, alt: receiverState.active.name }),
1353
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default2.nsChatTitle, children: receiverState.active.name })
1354
+ ] })
1355
+ }
1356
+ ),
1357
+ " "
1358
+ ] }),
1359
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Space, { size: 2, children: [
1360
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: agentCharacter, DefaultComponent: AgentCharacter_default }),
1361
+ /* @__PURE__ */ jsxRuntime.jsx(
1362
+ common.RenderWrapper,
1363
+ {
1364
+ control: newConversationBtn,
1365
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { title: "\u65B0\u5EFA\u4F1A\u8BDD", type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}), onClick: () => chatStore.createAgentConversation() })
1366
+ }
1367
+ ),
1368
+ /* @__PURE__ */ jsxRuntime.jsx(
1369
+ common.RenderWrapper,
1370
+ {
1371
+ control: conversationListBtn,
1372
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(
1373
+ antd.Popover,
1374
+ {
1375
+ getPopupContainer: (e) => e,
1376
+ placement: "bottom",
1377
+ classNames: { body: styles_module_default2.nsChatHeaderPopover },
1378
+ content: /* @__PURE__ */ jsxRuntime.jsx(ConversationList_default, {}),
1379
+ trigger: ["click"],
1380
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { title: "\u5386\u53F2\u4F1A\u8BDD", type: "text", size: "large", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CommentOutlined, {}) })
1381
+ }
1382
+ )
1383
+ }
1384
+ ),
1385
+ /* @__PURE__ */ jsxRuntime.jsx(
1386
+ common.RenderWrapper,
1387
+ {
1388
+ control: closeBtn,
1389
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { title: "\u5173\u95ED", type: "text", size: "large", onClick: configState.hooks?.onHeaderClose, icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloseOutlined, {}) })
1390
+ }
1391
+ )
1392
+ ] })
1393
+ ] }) });
1394
+ };
1395
+
1396
+ // src/components/styles.module.less
1397
+ var styles_module_default3 = {
1398
+ nsAttachments: "styles_module_nsAttachments"
1399
+ };
1400
+ var Attachments_default = react.forwardRef(({ fileUploadConfig = [], fileList = [], onChange, extraParams }, ref) => {
1401
+ const { message: message3 } = antd.App.useApp();
1297
1402
  const fileListRef = react.useRef([]);
1298
1403
  const [attachedFiles, setAttachedFiles, getAttachedFiles] = common.useRefState([]);
1299
1404
  react.useEffect(() => {
@@ -1301,7 +1406,8 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1301
1406
  fileListRef.current = fileList;
1302
1407
  const mapped = fileList.map((file) => ({
1303
1408
  ...file,
1304
- uid: file.id,
1409
+ uid: file.content,
1410
+ url: file.content,
1305
1411
  status: "done"
1306
1412
  }));
1307
1413
  setAttachedFiles(mapped);
@@ -1313,34 +1419,53 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1313
1419
  delete f.status;
1314
1420
  delete f.uid;
1315
1421
  delete f.size;
1422
+ delete f.url;
1316
1423
  return f;
1317
1424
  });
1318
1425
  fileListRef.current = files;
1319
1426
  onChange(files);
1320
1427
  }, [attachedFiles]);
1321
1428
  const onErrorTip = common.useDebounce((errorMsg) => {
1322
- antd.message.error(errorMsg);
1429
+ message3.error(errorMsg);
1323
1430
  }, 300);
1431
+ const findConfigByFile = (file) => {
1432
+ return fileUploadConfig.find((cfg) => cfg.allowedFileTypes?.includes(common.getFileSuffixName(file.name).toLocaleUpperCase()));
1433
+ };
1324
1434
  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);
1435
+ for (const file of files) {
1436
+ const cfg = findConfigByFile(file);
1437
+ if (!cfg) {
1438
+ onErrorTip(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B\uFF1A${file.name} (${file.type})`);
1439
+ return Promise.reject(false);
1440
+ }
1441
+ if (common.isNumber(cfg.maxFileCount)) {
1442
+ const currentCount = attachedFiles.filter((f) => cfg.allowedFileTypes.includes(common.getFileSuffixName(f.name || "").toLocaleUpperCase())).length;
1443
+ if (currentCount + 1 > cfg.maxFileCount) {
1444
+ onErrorTip(`\u3010${file.name}\u3011\u6240\u5C5E\u7C7B\u578B\u6700\u591A\u53EA\u80FD\u4E0A\u4F20 ${cfg.maxFileCount} \u4E2A\u6587\u4EF6`);
1445
+ return Promise.reject(false);
1446
+ }
1447
+ }
1328
1448
  }
1329
1449
  };
1330
1450
  const onCustomRequest = async ({ file }) => {
1331
- if (fileSize && file.size > fileSize) {
1332
- antd.message.error(`${fileSizeTip}`);
1451
+ const cfg = findConfigByFile(file);
1452
+ if (!cfg) {
1453
+ onErrorTip(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B\uFF1A${file.name}`);
1454
+ return;
1455
+ }
1456
+ if (cfg.maxFileSize && file.size > cfg.maxFileSize * 1024 * 1024) {
1457
+ onErrorTip(`\u6587\u4EF6\u5927\u5C0F\u4E0D\u80FD\u8D85\u8FC7 ${cfg.maxFileSize} MB`);
1333
1458
  return;
1334
1459
  }
1335
1460
  setAttachedFiles([
1336
1461
  ...getAttachedFiles(),
1337
1462
  {
1338
- type: file.type,
1339
- name: file.name,
1340
1463
  uid: file.uid,
1341
1464
  status: "uploading",
1342
1465
  percent: 70,
1343
- size: file.size
1466
+ size: file.size,
1467
+ type: file.type,
1468
+ name: file.name
1344
1469
  }
1345
1470
  ]);
1346
1471
  try {
@@ -1352,14 +1477,11 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1352
1477
  formData.append(key, extraParams[key]);
1353
1478
  });
1354
1479
  }
1355
- const { data } = await uploadFile(formData);
1356
- if (!data?.url && data?.type === "image") {
1357
- data.url = await getBase64(file);
1358
- }
1480
+ const { data } = await fileUpload(formData);
1359
1481
  setAttachedFiles(
1360
1482
  getAttachedFiles().map((f) => {
1361
1483
  if (f.uid === file.uid) {
1362
- return { ...data, uid: data.id, status: "done", size: f.size };
1484
+ return { ...data, uid: data.content, url: data.content, status: "done", size: f.size };
1363
1485
  } else {
1364
1486
  return f;
1365
1487
  }
@@ -1388,12 +1510,12 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1388
1510
  const files = getAttachedFiles();
1389
1511
  const uploadingFiles = files.filter((file) => file.status === "uploading");
1390
1512
  if (uploadingFiles.length > 0) {
1391
- antd.message.error("\u8BF7\u7B49\u5F85\u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210");
1513
+ onErrorTip("\u8BF7\u7B49\u5F85\u6240\u6709\u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210");
1392
1514
  return false;
1393
1515
  }
1394
1516
  const errorFiles = files.filter((file) => file.status === "error");
1395
1517
  if (errorFiles.length > 0) {
1396
- antd.message.error("\u8BF7\u68C0\u67E5\u4E0A\u4F20\u5931\u8D25\u7684\u6587\u4EF6");
1518
+ onErrorTip("\u8BF7\u68C0\u67E5\u4E0A\u4F20\u5931\u8D25\u7684\u6587\u4EF6");
1397
1519
  return false;
1398
1520
  }
1399
1521
  return true;
@@ -1402,47 +1524,15 @@ var Attachments_default = react.forwardRef(({ maxCount, accept, fileSize, fileSi
1402
1524
  []
1403
1525
  );
1404
1526
  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]);
1527
+ const allTypes = fileUploadConfig.flatMap((cfg) => cfg.allowedFileTypes || []);
1528
+ return allTypes.length ? allTypes.join(",") : void 0;
1529
+ }, [fileUploadConfig]);
1439
1530
  return /* @__PURE__ */ jsxRuntime.jsx(
1440
1531
  x.Attachments,
1441
1532
  {
1442
- className: "nsAttachments",
1533
+ className: styles_module_default3.nsAttachments,
1443
1534
  accept: acceptStr,
1444
- multiple: !common.isNumber(maxCount) || maxCount > 1,
1445
- maxCount,
1535
+ multiple: true,
1446
1536
  customRequest: onCustomRequest,
1447
1537
  beforeUpload: (file, files) => onBeforeUpload(files),
1448
1538
  items: attachedFiles,
@@ -1472,11 +1562,11 @@ var ChatSender_default = react.forwardRef(
1472
1562
  extraFooter,
1473
1563
  extraFooterBelow,
1474
1564
  sendButtonProps,
1475
- fileUpload
1565
+ fileUpload: fileUpload2
1476
1566
  }, ref) => {
1477
1567
  const senderRef = react.useRef(null);
1478
1568
  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) }) });
1569
+ 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
1570
  const attachmentsRef = react.useRef();
1481
1571
  const senderHeader = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1482
1572
  /* @__PURE__ */ jsxRuntime.jsx(x.Sender.Header, { title: "\u9009\u62E9\u6587\u4EF6", open: headerOpen, onOpenChange: onHeaderOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1485,9 +1575,8 @@ var ChatSender_default = react.forwardRef(
1485
1575
  ref: attachmentsRef,
1486
1576
  fileList,
1487
1577
  onChange: onFileListChange,
1488
- accept: fileUpload?.allowedFileTypes,
1489
- maxCount: fileUpload?.maxFileCount,
1490
- extraParams: fileUpload?.extraParams
1578
+ fileUploadConfig: fileUpload2.config,
1579
+ extraParams: fileUpload2.params
1491
1580
  }
1492
1581
  ) }),
1493
1582
  extraHeader
@@ -1542,11 +1631,11 @@ var ChatSender_default = react.forwardRef(
1542
1631
  init_Context();
1543
1632
  var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = false }) => {
1544
1633
  const chatStore = useChatStore();
1545
- const agentState = valtio.useSnapshot(chatStore.agent);
1634
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1546
1635
  const conversationState = valtio.useSnapshot(chatStore.conversation);
1547
1636
  const chatMessage = react.useMemo(
1548
- () => conversationState.messages[conversationState.active.key] || {},
1549
- [conversationState.messages[conversationState.active.key]]
1637
+ () => conversationState.messages[conversationState.active.id] || {},
1638
+ [conversationState.messages[conversationState.active.id]]
1550
1639
  );
1551
1640
  const referenceHandle = (con) => {
1552
1641
  if (chatMessage?.loading) return;
@@ -1567,22 +1656,37 @@ var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = fals
1567
1656
  onFileListChange: chatStore.setFileList,
1568
1657
  onHeaderOpenChange: chatStore.setHeaderOpen,
1569
1658
  onSend: () => chatStore.sendMessage(),
1659
+ onCancel: chatStore.cancelReceive,
1570
1660
  onFocus: chatStore.config.hooks?.onSenderFocus,
1571
1661
  fileUpload: {
1572
- ...agentState.active?.parameters?.fileUpload,
1573
- extraParams: { agentId: agentState.active.id }
1662
+ config: receiverState.active.config?.fileUpload
1574
1663
  },
1575
1664
  extraFooter: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1576
- /* @__PURE__ */ jsxRuntime.jsx(
1665
+ receiverState.active.feature?.deepThink && /* @__PURE__ */ jsxRuntime.jsx(
1577
1666
  antd.Button,
1578
1667
  {
1579
1668
  size: "small",
1580
- color: agentState.params.thinkMode === "1" ? "primary" : "default",
1669
+ color: receiverState.params.thinkMode === "1" ? "primary" : "default",
1581
1670
  variant: "filled",
1582
- onClick: () => chatStore.setAgentParams({ thinkMode: agentState.params.thinkMode === "1" ? "2" : "1" }),
1671
+ onClick: () => chatStore.setReceiverParams({ thinkMode: receiverState.params.thinkMode === "1" ? "2" : "1" }),
1583
1672
  children: "\u6DF1\u5EA6\u601D\u8003"
1584
1673
  }
1585
1674
  ),
1675
+ receiverState.active.feature?.switchManual && /* @__PURE__ */ jsxRuntime.jsx(
1676
+ antd.Button,
1677
+ {
1678
+ size: "small",
1679
+ 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",
1680
+ shape: "round",
1681
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.UserSwitchOutlined, {}),
1682
+ color: chatMessage?.speakHuman ? "primary" : "default",
1683
+ variant: "filled",
1684
+ onClick: () => {
1685
+ chatStore.setSpeakHuman?.(!chatMessage?.speakHuman);
1686
+ },
1687
+ children: "\u5411\u4E13\u5BB6\u54A8\u8BE2"
1688
+ }
1689
+ ),
1586
1690
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: extraBtn })
1587
1691
  ] }),
1588
1692
  extraHeader: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1595,8 +1699,8 @@ var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = fals
1595
1699
  open: !!chatMessage?.references?.content?.name,
1596
1700
  onOpenChange: () => chatStore.setReferences(),
1597
1701
  classNames: {
1598
- header: styles_module_default.nsSenderReferenceHeaderTitle,
1599
- content: common.shouldRender(referencesBtn) ? "" : styles_module_default.nsSenderReferenceHeaderContent
1702
+ header: styles_module_default2.nsSenderReferenceHeaderTitle,
1703
+ content: common.shouldRender(referencesBtn) ? "" : styles_module_default2.nsSenderReferenceHeaderContent
1600
1704
  },
1601
1705
  children: /* @__PURE__ */ jsxRuntime.jsx(
1602
1706
  common.RenderWrapper,
@@ -1618,11 +1722,11 @@ var ChatSender_default2 = ({ placeholder, extraBtn = false, referencesBtn = fals
1618
1722
  init_Context();
1619
1723
  var ConversationListHeader_default = () => {
1620
1724
  const chatStore = useChatStore();
1621
- const agentState = valtio.useSnapshot(chatStore.agent);
1725
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1622
1726
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-24", children: [
1623
1727
  /* @__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 })
1728
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Avatar, { size: 36, src: receiverState.active.logo }),
1729
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles_module_default2.nsChatUserName, children: receiverState.active.name })
1626
1730
  ] }),
1627
1731
  /* @__PURE__ */ jsxRuntime.jsx(
1628
1732
  antd.Button,
@@ -1630,8 +1734,8 @@ var ConversationListHeader_default = () => {
1630
1734
  block: true,
1631
1735
  type: "primary",
1632
1736
  shape: "round",
1633
- onClick: () => chatStore.switchConversation(),
1634
- className: classNames6__default.default("m-t-16"),
1737
+ onClick: () => chatStore.createAgentConversation(),
1738
+ className: classNames7__default.default("m-t-16"),
1635
1739
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PlusOutlined, {}),
1636
1740
  children: "\u65B0\u5EFA\u4F1A\u8BDD"
1637
1741
  }
@@ -1639,7 +1743,7 @@ var ConversationListHeader_default = () => {
1639
1743
  ] });
1640
1744
  };
1641
1745
  var ConversationListPanel_default = ({ header }) => {
1642
- return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames6__default.default("height-full", styles_module_default.conversationListPanel), children: [
1746
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames7__default.default("height-full", styles_module_default2.conversationListPanel), children: [
1643
1747
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: header, DefaultComponent: ConversationListHeader_default }),
1644
1748
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", children: /* @__PURE__ */ jsxRuntime.jsx(ConversationList_default, {}) })
1645
1749
  ] });
@@ -1649,11 +1753,11 @@ var ConversationListPanel_default = ({ header }) => {
1649
1753
  init_Context();
1650
1754
  var SenderPromptsItems_default = () => {
1651
1755
  const chatStore = useChatStore();
1652
- const agentState = valtio.useSnapshot(chatStore.agent);
1756
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1653
1757
  const component = react.useMemo(
1654
- () => agentState.active.labels?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, wrap: true, children: [
1758
+ () => receiverState.active.config?.labels?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 4, className: "overflow-hidden", children: [
1655
1759
  /* @__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(
1760
+ receiverState.active.config.labels.map((question) => /* @__PURE__ */ jsxRuntime.jsx(
1657
1761
  antd.Popover,
1658
1762
  {
1659
1763
  content: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1661,67 +1765,71 @@ var SenderPromptsItems_default = () => {
1661
1765
  {
1662
1766
  itemLayout: "horizontal",
1663
1767
  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)" })
1768
+ className: styles_module_default2.senderList,
1769
+ dataSource: question.items,
1770
+ renderItem: (item) => /* @__PURE__ */ jsxRuntime.jsx(antd.List.Item, { onClick: () => chatStore.sendMessage(item.question), className: styles_module_default2.senderListItem, children: item.question }),
1771
+ 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
1772
  }
1669
1773
  ),
1670
1774
  title: /* @__PURE__ */ jsxRuntime.jsx(
1671
1775
  "div",
1672
1776
  {
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`
1777
+ className: classNames7__default.default(styles_module_default2.senderListTitle, "text-ellipsis"),
1778
+ children: `${receiverState.active.name}\u5F00\u59CB\u5173\u6CE8${question.name}\u5185\u5BB9\uFF01`
1675
1779
  }
1676
1780
  ),
1677
- children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "filled", children: question.labelName })
1781
+ children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "default", variant: "filled", children: question.name })
1678
1782
  },
1679
1783
  question.id
1680
1784
  ))
1681
1785
  ] }),
1682
- [agentState.active.labels]
1786
+ [receiverState.active.config?.labels]
1683
1787
  );
1684
1788
  return component;
1685
1789
  };
1686
1790
 
1687
1791
  // src/ui/layouts/styles.module.less
1688
- var styles_module_default3 = {
1792
+ var styles_module_default4 = {
1689
1793
  nsPreviewHeader: "styles_module_nsPreviewHeader",
1690
1794
  nsPreviewHeaderTitle: "styles_module_nsPreviewHeaderTitle",
1691
1795
  nsChatSenderHeader: "styles_module_nsChatSenderHeader",
1692
1796
  nsDisclaimerNotice: "styles_module_nsDisclaimerNotice",
1693
1797
  nsChatLayout: "styles_module_nsChatLayout"
1694
1798
  };
1695
- var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultAgent }, ref) => {
1799
+ var layouts_default = react.forwardRef(({ theme, params, userInfo, hooks, layout, config }, ref) => {
1696
1800
  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);
1801
+ common.useDeepEffect(() => {
1802
+ if (config?.conversationId) {
1803
+ chatStore.switchConversation(config.conversationId);
1804
+ return;
1805
+ }
1806
+ if (config?.receiverId && config?.receiverType === 3) {
1807
+ chatStore.switchAgentConversation(config.receiverId, config.conversationStrategy);
1701
1808
  }
1702
- }, []);
1809
+ }, [config]);
1703
1810
  react.useEffect(() => {
1704
- chatStore.setLayout(layout);
1705
- }, [layout]);
1811
+ chatStore.setUserInfo(userInfo);
1812
+ }, [userInfo]);
1813
+ react.useEffect(() => {
1814
+ chatStore.setLayout(layout, config?.receiverType);
1815
+ }, [layout, config?.receiverType]);
1706
1816
  react.useEffect(() => {
1707
1817
  chatStore.setConfigParams(params);
1708
1818
  }, [params]);
1709
1819
  react.useEffect(() => {
1710
1820
  chatStore.setHooks(hooks);
1711
1821
  }, [hooks]);
1712
- const agentState = valtio.useSnapshot(chatStore.agent);
1822
+ const receiverState = valtio.useSnapshot(chatStore.receiver);
1713
1823
  const configState = valtio.useSnapshot(chatStore.config);
1714
1824
  react.useImperativeHandle(
1715
1825
  ref,
1716
1826
  () => ({
1717
1827
  sendMessage: chatStore.sendMessage,
1718
- switchAgent: chatStore.switchAgent,
1828
+ switchAgentConversation: chatStore.switchAgentConversation,
1719
1829
  switchConversation: chatStore.switchConversation,
1720
1830
  setReferences: chatStore.setReferences,
1721
1831
  setMessage: chatStore.setContent,
1722
- setFiles: chatStore.setFileList,
1723
- setParams: chatStore.setConfigParams,
1724
- setLayout: chatStore.setLayout
1832
+ setFiles: chatStore.setFileList
1725
1833
  }),
1726
1834
  []
1727
1835
  );
@@ -1739,16 +1847,22 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1739
1847
  setSplitterSizes([0, "100%"]);
1740
1848
  }
1741
1849
  }, [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 }),
1850
+ common.useWebSocket({
1851
+ url: common.getWebSocketUrl(`/lolr/conversation/ws/subscribe?NS-TOKEN=${common.getToken()}`, common.isLocalhost() ? "192.168.6.23:9090" : ""),
1852
+ onMessage: chatStore.acceptMessage,
1853
+ clientHeartbeat: false,
1854
+ reconnectInterval: 1e4
1855
+ });
1856
+ 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: [
1857
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: ChatHeader_default }),
1744
1858
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { className: "full-scroll", children: [
1745
1859
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.leftPanel, DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}) }),
1746
1860
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.conversationList, DefaultComponent: ConversationListPanel_default }),
1747
1861
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Splitter, { className: "flex-1", onResize: setSplitterSizes, children: [
1748
1862
  /* @__PURE__ */ jsxRuntime.jsx(antd.Splitter.Panel, { collapsible: false, min: 600, size: sizes[0], children: hasPreView && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1749
1863
  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 }),
1864
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", gap: 16, className: styles_module_default4.nsPreviewHeader, children: [
1865
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default4.nsPreviewHeaderTitle, children: configState.preview.file.fileName }),
1752
1866
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "center", align: "center", children: [
1753
1867
  /* @__PURE__ */ jsxRuntime.jsx(
1754
1868
  antd.Button,
@@ -1793,23 +1907,17 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1793
1907
  }
1794
1908
  )
1795
1909
  ] }) }),
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
- ) }),
1910
+ /* @__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: [
1911
+ /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: ChatHeader_default }),
1912
+ /* @__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: [
1913
+ 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 }) }),
1806
1914
  /* @__PURE__ */ jsxRuntime.jsx(
1807
1915
  common.RenderWrapper,
1808
1916
  {
1809
1917
  control: configState.layout.senderHeader,
1810
- DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default3.nsChatSenderHeader, children: [
1918
+ DefaultComponent: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles_module_default4.nsChatSenderHeader, children: [
1811
1919
  "\u6211\u662F ",
1812
- agentState.active.name
1920
+ receiverState.active.name
1813
1921
  ] })
1814
1922
  }
1815
1923
  ),
@@ -1826,7 +1934,7 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1826
1934
  common.RenderWrapper,
1827
1935
  {
1828
1936
  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" })
1937
+ 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
1938
  }
1831
1939
  )
1832
1940
  ] }),
@@ -1838,6 +1946,6 @@ var layouts_default = react.forwardRef(({ theme, params, hooks, layout, defaultA
1838
1946
  ] }) }) }) });
1839
1947
  });
1840
1948
 
1841
- exports.AgentChat = layouts_default;
1949
+ exports.ChatCopilot = layouts_default;
1842
1950
  //# sourceMappingURL=index.cjs.js.map
1843
1951
  //# sourceMappingURL=index.cjs.js.map