@zero-library/chat-agent 2.0.10 → 2.1.1

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