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