paul-ai-assistant 1.0.6 → 1.0.7

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.
@@ -9,7 +9,7 @@ var AigcTipsRender = function AigcTipsRender(props) {
9
9
  var _ctx$meta;
10
10
  var ctx = props.ctx,
11
11
  _props$showAigcTips = props.showAigcTips,
12
- showAigcTips = _props$showAigcTips === void 0 ? true : _props$showAigcTips;
12
+ showAigcTips = _props$showAigcTips === void 0 ? false : _props$showAigcTips;
13
13
  var _ref = (ctx === null || ctx === void 0 || (_ctx$meta = ctx.meta) === null || _ctx$meta === void 0 ? void 0 : _ctx$meta.originData) || {},
14
14
  dataInfo = _ref.dataInfo;
15
15
  var headerTips = useMemo(function () {
@@ -4,14 +4,14 @@ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
4
4
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
5
5
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
6
6
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
7
- var _excluded = ["children", "bizId", "bizDomain", "locateAfterSingleMessageUpdate", "dataSource", "interruptLlmMessageScroll", "toolConfig", "placeholder", "messageCardWidth", "enableWsConnectCallback", "onSend", "assistantChat", "log", "logTrace", "messagesMaxLength", "mode", "activeToken", "onStopMessage", "imConnectCallback", "chatTitle", "isAssistant", "isThirdEmbed", "getApiHost"],
7
+ var _excluded = ["children", "bizId", "bizDomain", "locateAfterSingleMessageUpdate", "dataSource", "interruptLlmMessageScroll", "toolConfig", "placeholder", "messageCardWidth", "enableWsConnectCallback", "onSend", "assistantChat", "log", "logTrace", "messagesMaxLength", "mode", "activeToken", "onStopMessage", "imConnectCallback", "chatTitle", "isAssistant", "isThirdEmbed", "getApiHost", "subjectId", "autoConnect", "autoSendMessage", "onConnectionReady", "onSendSuccess", "onSendError"],
8
8
  _excluded2 = ["chatType", "onSuccessCallback"];
9
9
  import React, { createContext, useEffect, useRef, useState } from 'react';
10
10
  import { event } from "../utils/event";
11
11
  import { getWorkId } from "../utils/helpers";
12
12
  import { FEATURE_MODE_TYPE_KEY } from "../components/ModelSelect/const";
13
13
  import { ASSIST_CHAT_EVENT } from "../constants/assistChatEvent";
14
- import { CHAT_TYPE, ChatTypeEnum, COPILOT_TOOL_TYPE_ENUM, initPlaceholder } from "../constants/common";
14
+ import { CHAT_TYPE, ChatTypeEnum, COPILOT_TOOL_TYPE_ENUM, initPlaceholder, REQUEST_SUCCESS_CODE } from "../constants/common";
15
15
  import { LOG_TRACE_TYPE_ENUMS } from "../constants/logTrace";
16
16
  import { ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS, disconnectAssistantWs, startAssistantWs } from "../utils/apushAssistant";
17
17
  import { triggerPlugin } from "../utils/clientPlugin";
@@ -21,17 +21,53 @@ import { AesCustomLogEventEnum, setAesCustomEvent } from "../utils/log";
21
21
  import { updateMessageList, updateMessageValue, updateSingleMessage } from "./utils/messages";
22
22
  import { clickSendMessage, sendMessageRequest, stopMessage, successCallback } from "./utils/send";
23
23
  import { clearContext, initTools, searchTools } from "./utils/tool";
24
+ import { getConversationConnection } from "../service/conversation";
25
+ import { useAutoSend } from "../hooks/useAutoSend";
26
+
27
+ // ======================================= URL 参数工具函数 =======================================
28
+ var SUBJECT_ID_URL_PARAM = 'subjectId';
29
+
30
+ /**
31
+ * 从 URL 中读取 subjectId 参数
32
+ */
33
+ var getSubjectIdFromUrl = function getSubjectIdFromUrl() {
34
+ if (typeof window === 'undefined') return null;
35
+ var urlParams = new URLSearchParams(window.location.search);
36
+ return urlParams.get(SUBJECT_ID_URL_PARAM);
37
+ };
38
+
39
+ /**
40
+ * 将 subjectId 写入 URL(使用 history.pushState 产生浏览历史)
41
+ * 只有当 URL 中的 subjectId 与传入的不同时才更新
42
+ */
43
+ var updateUrlWithSubjectId = function updateUrlWithSubjectId(subjectId) {
44
+ if (typeof window === 'undefined') return;
45
+
46
+ // 获取当前 URL 中的 subjectId
47
+ var currentSubjectId = getSubjectIdFromUrl();
48
+ var newSubjectId = String(subjectId);
49
+
50
+ // 如果 subjectId 没有变化,不更新 URL
51
+ if (currentSubjectId === newSubjectId) {
52
+ return;
53
+ }
54
+ var url = new URL(window.location.href);
55
+ url.searchParams.set(SUBJECT_ID_URL_PARAM, newSubjectId);
56
+ window.history.pushState({
57
+ subjectId: newSubjectId
58
+ }, '', url.toString());
59
+ };
24
60
  export var AssistantChatContext = /*#__PURE__*/createContext({
25
61
  bizId: '',
26
- bizDomain: 'CSE',
62
+ bizDomain: 'CHAT',
27
63
  messagesLoading: true
28
64
  });
29
65
  var AssistantChatProvider = function AssistantChatProvider() {
30
66
  var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
31
67
  var children = props.children,
32
- bizId = props.bizId,
68
+ propBizId = props.bizId,
33
69
  _props$bizDomain = props.bizDomain,
34
- bizDomain = _props$bizDomain === void 0 ? 'CSE' : _props$bizDomain,
70
+ bizDomain = _props$bizDomain === void 0 ? 'CHAT' : _props$bizDomain,
35
71
  _props$locateAfterSin = props.locateAfterSingleMessageUpdate,
36
72
  locateAfterSingleMessageUpdate = _props$locateAfterSin === void 0 ? true : _props$locateAfterSin,
37
73
  dataSource = props.dataSource,
@@ -45,7 +81,7 @@ var AssistantChatProvider = function AssistantChatProvider() {
45
81
  _props$enableWsConnec = props.enableWsConnectCallback,
46
82
  enableWsConnectCallback = _props$enableWsConnec === void 0 ? false : _props$enableWsConnec,
47
83
  onSend = props.onSend,
48
- assistantChat = props.assistantChat,
84
+ propAssistantChat = props.assistantChat,
49
85
  _props$log = props.log,
50
86
  log = _props$log === void 0 ? setAesCustomEvent : _props$log,
51
87
  logTrace = props.logTrace,
@@ -61,44 +97,63 @@ var AssistantChatProvider = function AssistantChatProvider() {
61
97
  isAssistant = _props$isAssistant === void 0 ? false : _props$isAssistant,
62
98
  isThirdEmbed = props.isThirdEmbed,
63
99
  getApiHost = props.getApiHost,
100
+ subjectId = props.subjectId,
101
+ _props$autoConnect = props.autoConnect,
102
+ autoConnect = _props$autoConnect === void 0 ? true : _props$autoConnect,
103
+ autoSendMessage = props.autoSendMessage,
104
+ onConnectionReady = props.onConnectionReady,
105
+ onSendSuccess = props.onSendSuccess,
106
+ onSendError = props.onSendError,
64
107
  otherProps = _objectWithoutProperties(props, _excluded);
108
+
109
+ // 内部维护的 bizId,支持自动获取会话时使用
110
+ var _useState = useState(propBizId),
111
+ _useState2 = _slicedToArray(_useState, 2),
112
+ internalBizId = _useState2[0],
113
+ setInternalBizId = _useState2[1];
114
+ // 实际使用的 bizId:优先使用外部传入的,其次使用内部状态
115
+ var bizId = propBizId || internalBizId;
116
+ // 标记是否已自动发送过消息
117
+ var autoSendDoneRef = useRef(false);
118
+ // 标记是否正在获取会话连接
119
+ var isConnectingRef = useRef(false);
65
120
  // 是否受控数据
66
121
  var hasDefaultDataSource = dataSource && Array.isArray(dataSource);
67
122
  // 消息流
68
- var _useState = useState([]),
69
- _useState2 = _slicedToArray(_useState, 2),
70
- messages = _useState2[0],
71
- setMessageList = _useState2[1];
72
- var _useState3 = useState(true),
123
+ var _useState3 = useState([]),
73
124
  _useState4 = _slicedToArray(_useState3, 2),
74
- messagesLoading = _useState4[0],
75
- setMessagesLoading = _useState4[1];
125
+ messages = _useState4[0],
126
+ setMessageList = _useState4[1];
127
+ var _useState5 = useState(true),
128
+ _useState6 = _slicedToArray(_useState5, 2),
129
+ messagesLoading = _useState6[0],
130
+ setMessagesLoading = _useState6[1];
76
131
 
77
132
  // 工具展示List
78
- var _useState5 = useState([]),
79
- _useState6 = _slicedToArray(_useState5, 2),
80
- toolShowList = _useState6[0],
81
- setToolShowList = _useState6[1];
82
- var _useState7 = useState(false),
133
+ var _useState7 = useState([]),
83
134
  _useState8 = _slicedToArray(_useState7, 2),
84
- showAddTag = _useState8[0],
85
- setShowAddTag = _useState8[1];
86
-
87
- // 分享模式相关状态
135
+ toolShowList = _useState8[0],
136
+ setToolShowList = _useState8[1];
88
137
  var _useState9 = useState(false),
89
138
  _useState10 = _slicedToArray(_useState9, 2),
90
- shareMode = _useState10[0],
91
- setShareMode = _useState10[1];
92
- var _useState11 = useState([]),
139
+ showAddTag = _useState10[0],
140
+ setShowAddTag = _useState10[1];
141
+
142
+ // 分享模式相关状态
143
+ var _useState11 = useState(false),
93
144
  _useState12 = _slicedToArray(_useState11, 2),
94
- selectedMessages = _useState12[0],
95
- setSelectedMessages = _useState12[1];
145
+ shareMode = _useState12[0],
146
+ setShareMode = _useState12[1];
147
+ var _useState13 = useState([]),
148
+ _useState14 = _slicedToArray(_useState13, 2),
149
+ selectedMessages = _useState14[0],
150
+ setSelectedMessages = _useState14[1];
96
151
 
97
152
  // WebSocket 连接状态
98
- var _useState13 = useState(null),
99
- _useState14 = _slicedToArray(_useState13, 2),
100
- wsConnectionStatus = _useState14[0],
101
- setWsConnectionStatus = _useState14[1];
153
+ var _useState15 = useState(null),
154
+ _useState16 = _slicedToArray(_useState15, 2),
155
+ wsConnectionStatus = _useState16[0],
156
+ setWsConnectionStatus = _useState16[1];
102
157
  var chatAppRef = useRef(null);
103
158
  var chatInputRef = useRef(null);
104
159
  var messageListRef = useRef([]);
@@ -108,22 +163,27 @@ var AssistantChatProvider = function AssistantChatProvider() {
108
163
  var textAreaRef = useRef(null);
109
164
  // 请求版本号,用于忽略过时的 API 响应
110
165
  var requestVersionRef = useRef(0);
166
+
167
+ // 存储最新的 getMessageList 函数引用,避免闭包陷阱
168
+ var getMessageListRef = useRef();
169
+ // 防抖定时器 ref
170
+ var getMessageListDebounceRef = useRef();
111
171
  var inputFormRef = useRef(null);
112
- var _useState15 = useState(null),
113
- _useState16 = _slicedToArray(_useState15, 2),
114
- inputFormSchema = _useState16[0],
115
- setInputFormSchema = _useState16[1];
172
+ var _useState17 = useState(null),
173
+ _useState18 = _slicedToArray(_useState17, 2),
174
+ inputFormSchema = _useState18[0],
175
+ setInputFormSchema = _useState18[1];
116
176
  // 当前消息id
117
177
  var currentUpdateMessageIdRef = useRef(null);
118
178
  // 当前消息id index
119
179
  var currentUpdateMessageIndexRef = useRef(-1);
120
- var _useState17 = useState({
180
+ var _useState19 = useState({
121
181
  thinkingMode: FEATURE_MODE_TYPE_KEY.AUTO,
122
182
  webSearchMode: FEATURE_MODE_TYPE_KEY.AUTO
123
183
  }),
124
- _useState18 = _slicedToArray(_useState17, 2),
125
- featureConfig = _useState18[0],
126
- setFeatureConfig = _useState18[1];
184
+ _useState20 = _slicedToArray(_useState19, 2),
185
+ featureConfig = _useState20[0],
186
+ setFeatureConfig = _useState20[1];
127
187
  useEffect(function () {
128
188
  if (hasDefaultDataSource) {
129
189
  var _chatAppRef$current;
@@ -140,6 +200,68 @@ var AssistantChatProvider = function AssistantChatProvider() {
140
200
  }
141
201
  }, [dataSource, hasDefaultDataSource]);
142
202
 
203
+ // ======================================= 开箱即用:自动获取会话连接 =======================================
204
+ /**
205
+ * 自动获取会话连接逻辑
206
+ * 当 autoConnect 为 true 且没有传入 bizId 时,自动调用 API 获取会话连接
207
+ * 只在 CHAT 场景下生效
208
+ *
209
+ * 优先级:propBizId > URL参数中的subjectId > props中的subjectId > 自动创建新会话
210
+ */
211
+ useEffect(function () {
212
+ // 只有在 CHAT 模式下才启用自动连接
213
+ var isChatMode = mode === ChatTypeEnum.Chat || bizDomain === 'CHAT';
214
+ // 检查是否需要自动连接:启用自动连接 && 没有外部传入的 bizId && 是 CHAT 模式 && 不在连接中
215
+ var shouldAutoConnect = autoConnect && !propBizId && isChatMode && !isConnectingRef.current;
216
+ if (shouldAutoConnect) {
217
+ isConnectingRef.current = true;
218
+
219
+ // 优先从 URL 读取 subjectId,其次使用 props 中的 subjectId
220
+ var urlSubjectId = getSubjectIdFromUrl();
221
+ var effectiveSubjectId = urlSubjectId || subjectId;
222
+ getConversationConnection({
223
+ bizDomain: 'CHAT',
224
+ subjectId: effectiveSubjectId
225
+ }).then(function (res) {
226
+ if ((res === null || res === void 0 ? void 0 : res.code) === REQUEST_SUCCESS_CODE) {
227
+ var connectionInfo = res.data;
228
+ // 更新内部 bizId
229
+ setInternalBizId(connectionInfo.subjectId);
230
+ // 将 subjectId 持久化到 URL
231
+ updateUrlWithSubjectId(connectionInfo.subjectId);
232
+ // 触发回调
233
+ onConnectionReady === null || onConnectionReady === void 0 || onConnectionReady(connectionInfo);
234
+ } else {
235
+ console.warn('自动获取会话连接失败:', res === null || res === void 0 ? void 0 : res.message);
236
+ }
237
+ }).catch(function (error) {
238
+ console.error('自动获取会话连接出错:', error);
239
+ }).finally(function () {
240
+ isConnectingRef.current = false;
241
+ });
242
+ }
243
+ }, [autoConnect, propBizId, subjectId, mode, bizDomain]);
244
+
245
+ // 当 propBizId 变化时,同步更新内部状态
246
+ useEffect(function () {
247
+ if (propBizId) {
248
+ setInternalBizId(propBizId);
249
+ }
250
+ }, [propBizId]);
251
+
252
+ // ======================================= 内置 onSend 逻辑 =======================================
253
+ /**
254
+ * 使用 useAutoSend Hook 获取有效的 onSend 方法
255
+ * 如果用户传入了 onSend,使用用户的;否则使用内置逻辑
256
+ */
257
+ var effectiveOnSend = useAutoSend({
258
+ bizId: bizId,
259
+ bizDomain: bizDomain,
260
+ onSend: onSend,
261
+ onSendSuccess: onSendSuccess,
262
+ onSendError: onSendError
263
+ });
264
+
143
265
  // ======================================= log埋点 =======================================
144
266
  /**
145
267
  * 辅助交互通用监控日志上报
@@ -169,27 +291,38 @@ var AssistantChatProvider = function AssistantChatProvider() {
169
291
  };
170
292
 
171
293
  // ======================================= 消息更新 =======================================
172
- // 拉取消息列表
294
+ // 拉取消息列表(带防抖机制)
173
295
  var getMessageList = function getMessageList() {
174
- var _chatInputRef$current;
175
296
  var isInit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
176
297
  var scroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
177
- updateMessageList({
178
- bizId: bizId,
179
- bizDomain: bizDomain,
180
- messagesMaxLength: messagesMaxLength,
181
- setMessagesLoading: setMessagesLoading,
182
- currentUpdateMessageIdRef: currentUpdateMessageIdRef,
183
- messageListRef: messageListRef,
184
- setMessageList: setMessageList,
185
- chatAppRef: chatAppRef,
186
- currentUpdateMessageIndexRef: currentUpdateMessageIndexRef,
187
- isInit: isInit,
188
- scroll: scroll,
189
- setSendMessageDisabled: chatInputRef === null || chatInputRef === void 0 || (_chatInputRef$current = chatInputRef.current) === null || _chatInputRef$current === void 0 ? void 0 : _chatInputRef$current.setSendMessageDisabled,
190
- requestVersionRef: requestVersionRef
191
- });
298
+ // 清除之前的定时器,实现防抖
299
+ if (getMessageListDebounceRef.current) {
300
+ clearTimeout(getMessageListDebounceRef.current);
301
+ }
302
+
303
+ // 使用 50ms 防抖,防止短时间内多次调用产生多个请求
304
+ getMessageListDebounceRef.current = setTimeout(function () {
305
+ var _chatInputRef$current;
306
+ updateMessageList({
307
+ bizId: bizId,
308
+ bizDomain: bizDomain,
309
+ messagesMaxLength: messagesMaxLength,
310
+ setMessagesLoading: setMessagesLoading,
311
+ currentUpdateMessageIdRef: currentUpdateMessageIdRef,
312
+ messageListRef: messageListRef,
313
+ setMessageList: setMessageList,
314
+ chatAppRef: chatAppRef,
315
+ currentUpdateMessageIndexRef: currentUpdateMessageIndexRef,
316
+ isInit: isInit,
317
+ scroll: scroll,
318
+ setSendMessageDisabled: chatInputRef === null || chatInputRef === void 0 || (_chatInputRef$current = chatInputRef.current) === null || _chatInputRef$current === void 0 ? void 0 : _chatInputRef$current.setSendMessageDisabled,
319
+ requestVersionRef: requestVersionRef
320
+ });
321
+ }, 50);
192
322
  };
323
+
324
+ // 更新 ref 为最新的 getMessageList 函数
325
+ getMessageListRef.current = getMessageList;
193
326
  var initMessageList = function initMessageList() {
194
327
  getMessageList === null || getMessageList === void 0 || getMessageList(true);
195
328
  };
@@ -237,6 +370,19 @@ var AssistantChatProvider = function AssistantChatProvider() {
237
370
  if (imConnectCallback && typeof imConnectCallback === 'function') {
238
371
  imConnectCallback();
239
372
  }
373
+ // 开箱即用:自动发送消息
374
+ if (autoSendMessage && !autoSendDoneRef.current) {
375
+ autoSendDoneRef.current = true;
376
+ // 延迟一下,确保消息列表已加载
377
+ setTimeout(function () {
378
+ effectiveOnSend === null || effectiveOnSend === void 0 || effectiveOnSend({
379
+ params: {
380
+ query: autoSendMessage
381
+ },
382
+ featureConfig: featureConfig
383
+ }, function () {});
384
+ }, 100);
385
+ }
240
386
  },
241
387
  log: log,
242
388
  // 连接状态变化回调
@@ -294,12 +440,12 @@ var AssistantChatProvider = function AssistantChatProvider() {
294
440
  };
295
441
  }, [bizId]);
296
442
  useEffect(function () {
297
- // 监听全部list
298
- var listenerGetMessageList = function listenerGetMessageList(x) {
299
- var _logTrace$closeTrace;
443
+ // 监听全部list - 使用 ref 调用最新的 getMessageList 函数,避免闭包陷阱
444
+ var listenerGetMessageList = function listenerGetMessageList() {
445
+ var _logTrace$closeTrace, _getMessageListRef$cu;
300
446
  logTrace === null || logTrace === void 0 || (_logTrace$closeTrace = logTrace.closeTrace) === null || _logTrace$closeTrace === void 0 || _logTrace$closeTrace.call(logTrace, LOG_TRACE_TYPE_ENUMS.LLM_GET_MESSAGE_LIET_APUSH, window.currentMessageSendTimestamp);
301
447
  window.currentMessageSendTimestamp = undefined;
302
- getMessageList();
448
+ (_getMessageListRef$cu = getMessageListRef.current) === null || _getMessageListRef$cu === void 0 || _getMessageListRef$cu.call(getMessageListRef);
303
449
  };
304
450
  // 监听单条数据
305
451
  var listenerGetSingleMessage = function listenerGetSingleMessage(argJson) {
@@ -343,22 +489,26 @@ var AssistantChatProvider = function AssistantChatProvider() {
343
489
  chatInputRef === null || chatInputRef === void 0 || (_chatInputRef$current9 = chatInputRef.current) === null || _chatInputRef$current9 === void 0 || (_chatInputRef$current10 = _chatInputRef$current9.setSendMessageDisabled) === null || _chatInputRef$current10 === void 0 || _chatInputRef$current10.call(_chatInputRef$current9, false);
344
490
  }
345
491
  };
346
- if (!hasDefaultDataSource) {
347
- // 消息受控,不再监听消息列表刷新
492
+
493
+ // 保存当前 hasDefaultDataSource 值用于 cleanup,确保清理时使用相同的条件
494
+ var shouldListen = !hasDefaultDataSource;
495
+ if (shouldListen) {
496
+ // 消息非受控,监听消息列表刷新
348
497
  event.on(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_GET_MESSAGE_LIST, listenerGetMessageList);
349
498
  event.on(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_GET_MESSAGE, listenerGetSingleMessage);
350
499
  }
351
500
  event.on(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_LLM_STREAM_MESSAGE, updateStreamMessage);
352
501
  event.on(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_LLM_TRACE_MESSAGE, updateTraceMessage);
353
502
  return function () {
354
- if (!hasDefaultDataSource) {
503
+ if (shouldListen) {
355
504
  event.off(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_GET_MESSAGE_LIST, listenerGetMessageList);
356
505
  event.off(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_GET_MESSAGE, listenerGetSingleMessage);
357
506
  }
358
507
  event.off(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_LLM_STREAM_MESSAGE, updateStreamMessage);
359
508
  event.off(ASSISTANT_APUSH_MESSAGE_TYPE_ENUMS.COPILOT_LLM_TRACE_MESSAGE, updateTraceMessage);
360
509
  };
361
- }, [bizId]);
510
+ }, [bizId, hasDefaultDataSource]); // 添加 hasDefaultDataSource 依赖,确保条件变化时正确清理和重新注册 listener
511
+
362
512
  useEffect(function () {
363
513
  var updateInputValue = function updateInputValue(_value) {
364
514
  var _chatInputRef$current11, _chatInputRef$current12;
@@ -395,7 +545,7 @@ var AssistantChatProvider = function AssistantChatProvider() {
395
545
  chatType: chatType
396
546
  }, otherSendProps);
397
547
  sendMessageRequest({
398
- onSend: onSend,
548
+ onSend: effectiveOnSend,
399
549
  sendInfoQuery: sendInfoQuery,
400
550
  onSuccessCallback: onSuccessCallback
401
551
  // setSendMessageDisabled: chatInputRef?.current?.setSendMessageDisabled,
@@ -720,9 +870,12 @@ var AssistantChatProvider = function AssistantChatProvider() {
720
870
  placeholder: placeholder,
721
871
  messageCardWidth: messageCardWidth,
722
872
  enableWsConnectCallback: enableWsConnectCallback,
723
- onSend: onSend,
724
- assistantChat: assistantChat,
873
+ // 使用有效的 onSend(可能是用户传入的,也可能是内置的)
874
+ onSend: effectiveOnSend,
875
+ assistantChat: propAssistantChat,
725
876
  isAssistant: isAssistant,
877
+ // WebSocket 连接状态
878
+ wsConnectionStatus: wsConnectionStatus,
726
879
  textAreaRef: textAreaRef,
727
880
  messages: messages,
728
881
  setMessageList: setMessageList,
@@ -0,0 +1 @@
1
+ export { useAutoSend } from "./useAutoSend";
@@ -0,0 +1,95 @@
1
+ import { useCallback, useRef, useEffect } from 'react';
2
+ import { assistantChat } from "../service/conversation";
3
+ import { getAssistantWsStatus, reconnectAssistantWs } from "../utils/apushAssistant";
4
+ import { REQUEST_SUCCESS_CODE } from "../constants/common";
5
+ /**
6
+ * 内置自动发送消息逻辑的 Hook
7
+ * 如果用户传入了 onSend,直接返回用户的 onSend
8
+ * 否则返回内置的发送逻辑
9
+ */
10
+ export function useAutoSend(props) {
11
+ var bizId = props.bizId,
12
+ _props$bizDomain = props.bizDomain,
13
+ bizDomain = _props$bizDomain === void 0 ? 'CHAT' : _props$bizDomain,
14
+ userOnSend = props.onSend,
15
+ onSendSuccess = props.onSendSuccess,
16
+ onSendError = props.onSendError;
17
+ var pendingSendRef = useRef(null);
18
+
19
+ // 监听 WebSocket 连接状态,处理待发送消息
20
+ useEffect(function () {
21
+ if (pendingSendRef.current) {
22
+ var _getAssistantWsStatus;
23
+ var status = (getAssistantWsStatus === null || getAssistantWsStatus === void 0 || (_getAssistantWsStatus = getAssistantWsStatus()) === null || _getAssistantWsStatus === void 0 ? void 0 : _getAssistantWsStatus.status) || 'disconnected';
24
+ if (status === 'connected') {
25
+ var pendingSend = pendingSendRef.current;
26
+ pendingSendRef.current = null;
27
+ pendingSend();
28
+ }
29
+ }
30
+ }, [bizId]);
31
+
32
+ // 内置 onSend 逻辑
33
+ var internalOnSend = useCallback(function (data, onSuccessCallback) {
34
+ var _getAssistantWsStatus2;
35
+ var _ref = (data === null || data === void 0 ? void 0 : data.params) || {},
36
+ query = _ref.query;
37
+ if (!bizId) {
38
+ console.warn('useAutoSend: bizId is required for sending message');
39
+ onSendError === null || onSendError === void 0 || onSendError(new Error('bizId is required'));
40
+ return;
41
+ }
42
+ var doSend = function doSend() {
43
+ var _data$params;
44
+ assistantChat({
45
+ subjectId: String(bizId),
46
+ content: query,
47
+ featureConfig: (data === null || data === void 0 ? void 0 : data.featureConfig) || {},
48
+ attachments: (data === null || data === void 0 || (_data$params = data.params) === null || _data$params === void 0 ? void 0 : _data$params.attachments) || []
49
+ }).then(function (res) {
50
+ if ((res === null || res === void 0 ? void 0 : res.code) === REQUEST_SUCCESS_CODE) {
51
+ onSuccessCallback === null || onSuccessCallback === void 0 || onSuccessCallback(res);
52
+ onSendSuccess === null || onSendSuccess === void 0 || onSendSuccess(res);
53
+ } else {
54
+ onSendError === null || onSendError === void 0 || onSendError(res);
55
+ }
56
+ }).catch(function (error) {
57
+ console.error('useAutoSend: send message failed', error);
58
+ onSendError === null || onSendError === void 0 || onSendError(error);
59
+ });
60
+ };
61
+
62
+ // 检查 WebSocket 连接状态
63
+ var status = (getAssistantWsStatus === null || getAssistantWsStatus === void 0 || (_getAssistantWsStatus2 = getAssistantWsStatus()) === null || _getAssistantWsStatus2 === void 0 ? void 0 : _getAssistantWsStatus2.status) || 'disconnected';
64
+ if (status === 'connected') {
65
+ doSend();
66
+ } else {
67
+ // 保存待发送消息
68
+ pendingSendRef.current = doSend;
69
+
70
+ // 如果连接断开,触发重连
71
+ if (status === 'disconnected') {
72
+ reconnectAssistantWs === null || reconnectAssistantWs === void 0 || reconnectAssistantWs({
73
+ bizId: String(bizId),
74
+ bizDomain: bizDomain
75
+ });
76
+ }
77
+
78
+ // 设置超时,避免无限等待
79
+ setTimeout(function () {
80
+ if (pendingSendRef.current === doSend) {
81
+ pendingSendRef.current = null;
82
+ // 超时后直接尝试发送
83
+ doSend();
84
+ }
85
+ }, 5000);
86
+ }
87
+ }, [bizId, bizDomain, onSendSuccess, onSendError]);
88
+
89
+ // 如果用户传入了 onSend,直接返回用户的
90
+ if (userOnSend) {
91
+ return userOnSend;
92
+ }
93
+ return internalOnSend;
94
+ }
95
+ export default useAutoSend;
package/es/index.js CHANGED
@@ -25,6 +25,9 @@ import { ASSIST_CHAT_EVENT } from "./constants/assistChatEvent";
25
25
  import { BIZ_DOMAIN_TYPE } from "./constants/common";
26
26
  import ErrorBoundary from "./ErrorBoundary";
27
27
  import { parseLlmComponentUrl } from "./utils/parseUrl";
28
+ // 开箱即用相关导出
29
+ import { getConversationConnection, assistantChat } from "./service/conversation";
30
+ import { useAutoSend } from "./hooks/useAutoSend";
28
31
  import "./index.scss";
29
32
 
30
33
  // 导出大模型卡片组件
@@ -60,4 +63,8 @@ registerAssistChatForm,
60
63
  // 表单组件
61
64
  PaulButtonGroupProps, SelectBlurry, ArrayInput,
62
65
  // utils
63
- parseLlmComponentUrl, ShareContent };
66
+ parseLlmComponentUrl, ShareContent,
67
+ // 开箱即用相关
68
+ getConversationConnection, assistantChat, useAutoSend };
69
+
70
+ // 导出开箱即用相关类型
@@ -0,0 +1,74 @@
1
+ import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
+ import { customRequest } from "../utils/request";
4
+
5
+ /**
6
+ * 会话连接信息
7
+ */
8
+
9
+ /**
10
+ * 获取会话连接 API 响应
11
+ */
12
+
13
+ /**
14
+ * 获取会话连接信息
15
+ * 用于自动创建或获取现有会话
16
+ * @param params 请求参数
17
+ * @returns Promise<IConversationConnectionResponse>
18
+ */
19
+ export function getConversationConnection(_x) {
20
+ return _getConversationConnection.apply(this, arguments);
21
+ }
22
+
23
+ /**
24
+ * 发送聊天消息
25
+ * @param params 消息参数
26
+ * @returns Promise<any>
27
+ */
28
+ function _getConversationConnection() {
29
+ _getConversationConnection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(params) {
30
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
31
+ while (1) switch (_context.prev = _context.next) {
32
+ case 0:
33
+ return _context.abrupt("return", customRequest({
34
+ method: 'GET',
35
+ url: '/cognipilot/api/conversation/connection',
36
+ query: {
37
+ bizDomain: params.bizDomain || 'CHAT',
38
+ subjectId: params.subjectId
39
+ }
40
+ }));
41
+ case 1:
42
+ case "end":
43
+ return _context.stop();
44
+ }
45
+ }, _callee);
46
+ }));
47
+ return _getConversationConnection.apply(this, arguments);
48
+ }
49
+ export function assistantChat(_x2) {
50
+ return _assistantChat.apply(this, arguments);
51
+ }
52
+ function _assistantChat() {
53
+ _assistantChat = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(params) {
54
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
55
+ while (1) switch (_context2.prev = _context2.next) {
56
+ case 0:
57
+ return _context2.abrupt("return", customRequest({
58
+ method: 'POST',
59
+ url: '/cognipilot/api/assistant/chat',
60
+ query: {
61
+ subjectId: params.subjectId,
62
+ content: params.content,
63
+ featureConfig: params.featureConfig || {},
64
+ attachments: params.attachments || []
65
+ }
66
+ }));
67
+ case 1:
68
+ case "end":
69
+ return _context2.stop();
70
+ }
71
+ }, _callee2);
72
+ }));
73
+ return _assistantChat.apply(this, arguments);
74
+ }
@@ -0,0 +1 @@
1
+ export { getConversationConnection, assistantChat } from "./conversation";
@@ -51,29 +51,38 @@ var msgCallback = function msgCallback(v) {
51
51
  return;
52
52
  }
53
53
 
54
- // 检查 ticketId 是否匹配
54
+ // 检查 ticketId 或 subjectId 是否匹配
55
+ // STREAM 消息使用 subjectId,其他消息使用 ticketId
55
56
  var ticketId = argJson === null || argJson === void 0 ? void 0 : argJson.ticketId;
56
- var isMatch = ticketId === bizId;
57
+ var subjectId = argJson === null || argJson === void 0 ? void 0 : argJson.subjectId;
58
+ var isMatch = ticketId === bizId || subjectId === bizId;
57
59
  if (isMatch) {
58
60
  event.emit(msgType, argJson);
59
61
  logger.debug('消息已分发', {
60
62
  msgType: msgType,
61
- ticketId: ticketId
63
+ ticketId: ticketId,
64
+ subjectId: subjectId
62
65
  });
63
66
  } else {
64
67
  // 消息被过滤,记录调试日志
65
- logger.debug('消息 ticketId 不匹配,已过滤', {
68
+ logger.debug('消息 ticketId/subjectId 不匹配,已过滤', {
66
69
  expected: bizId,
67
- received: ticketId,
70
+ receivedTicketId: ticketId,
71
+ receivedSubjectId: subjectId,
68
72
  msgType: msgType
69
73
  });
70
74
  }
71
75
  };
72
- var callback = function callback(msgBody, bizId) {
76
+ var callback = function callback(message, bizId) {
73
77
  try {
78
+ // message 是完整的 WebSocket 消息对象,真正的消息体在 message.msgBody 中
79
+ var msgBody = (message === null || message === void 0 ? void 0 : message.msgBody) || message;
74
80
  var _ref3 = msgBody || {},
75
- version = _ref3.version,
76
- msgDetail = _ref3.msgDetail;
81
+ msgVersion = _ref3.msgVersion,
82
+ msgDetail = _ref3.msgDetail,
83
+ msgType = _ref3.msgType;
84
+ // 兼容旧版本的 version 字段
85
+ var version = msgVersion || (msgBody === null || msgBody === void 0 ? void 0 : msgBody.version);
77
86
  if (version === '1.0.0') {
78
87
  var _msgDetail$, _msgDetail$2;
79
88
  if (msgDetail !== null && msgDetail !== void 0 && (_msgDetail$ = msgDetail[0]) !== null && _msgDetail$ !== void 0 && _msgDetail$.arg && msgDetail !== null && msgDetail !== void 0 && (_msgDetail$2 = msgDetail[0]) !== null && _msgDetail$2 !== void 0 && _msgDetail$2.app) {
@@ -94,8 +103,8 @@ var callback = function callback(msgBody, bizId) {
94
103
  } else if (version === '2.0.0' || !version) {
95
104
  // version 不传默认为 2.0.0
96
105
  msgCallback({
97
- msgType: msgBody === null || msgBody === void 0 ? void 0 : msgBody.msgType,
98
- arg: msgBody === null || msgBody === void 0 ? void 0 : msgBody.msgDetail,
106
+ msgType: msgType,
107
+ arg: msgDetail,
99
108
  bizId: bizId
100
109
  });
101
110
  }
@@ -241,11 +250,11 @@ export var startAssistantWs = function startAssistantWs(wsProps) {
241
250
  });
242
251
  }
243
252
  };
253
+ console.log(appId, userId, '=====');
244
254
  var im = new IM(_objectSpread({
245
255
  url: url,
246
256
  appKey: "".concat(appId, ",").concat(userId),
247
257
  // appKey: `${appId},1000`,
248
-
249
258
  commonParams: {
250
259
  appId: appId,
251
260
  userId: userId
package/es/utils/im.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
2
  import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
4
3
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
5
4
  import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
@@ -205,36 +204,46 @@ var IM = /*#__PURE__*/function () {
205
204
  return connect;
206
205
  }()
207
206
  /**
208
- * 构建 WebSocket URL
207
+ * 解析 JWT token 的 payload
209
208
  */
210
209
  )
211
210
  }, {
212
- key: "buildUrl",
213
- value: function buildUrl(token) {
214
- var url = new URL(this.url);
215
-
216
- // 添加通用参数
217
- if (this.commonParams) {
218
- Object.entries(this.commonParams).forEach(function (_ref) {
219
- var _ref2 = _slicedToArray(_ref, 2),
220
- key = _ref2[0],
221
- value = _ref2[1];
222
- if (value !== undefined && value !== null) {
223
- url.searchParams.set(key, String(value));
224
- }
225
- });
211
+ key: "parseJwtPayload",
212
+ value: function parseJwtPayload(token) {
213
+ try {
214
+ var parts = token.split('.');
215
+ if (parts.length !== 3) {
216
+ return null;
217
+ }
218
+ // Base64Url 解码
219
+ var payload = parts[1].replace(/-/g, '+').replace(/_/g, '/');
220
+ var decoded = atob(payload);
221
+ return JSON.parse(decoded);
222
+ } catch (e) {
223
+ logger.error('JWT 解析失败', e);
224
+ return null;
226
225
  }
226
+ }
227
227
 
228
- // 添加 appKey
229
- if (this.appKey) {
230
- url.searchParams.set('appKey', this.appKey);
231
- }
228
+ /**
229
+ * 构建 WebSocket URL
230
+ * 格式:wss://domain/paulWebPush/ws?param={bizDomain},{userId},{token}
231
+ * 其中 userId 从 token 的 payload 中获取
232
+ */
233
+ }, {
234
+ key: "buildUrl",
235
+ value: function buildUrl(token) {
236
+ var _this$commonParams;
237
+ var bizDomain = ((_this$commonParams = this.commonParams) === null || _this$commonParams === void 0 ? void 0 : _this$commonParams.appId) || '';
232
238
 
233
- // 添加 token
239
+ // token 中解析 userId
240
+ var userId = '';
234
241
  if (token) {
235
- url.searchParams.set('token', token);
242
+ var payload = this.parseJwtPayload(token);
243
+ userId = (payload === null || payload === void 0 ? void 0 : payload.userId) || '';
236
244
  }
237
- return url.toString();
245
+ var param = "".concat(bizDomain, ",").concat(userId, ",").concat(token || '');
246
+ return "".concat(this.url, "?param=").concat(param);
238
247
  }
239
248
 
240
249
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paul-ai-assistant",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Paul AI 智能辅助组件",
5
5
  "keywords": [
6
6
  "Magic Workbench",
@@ -39,6 +39,7 @@
39
39
  "prettier": "prettier --write \"src/**/*.{js,jsx,tsx,ts,less,scss,md,json}\" --end-of-line auto",
40
40
  "prepublish": "npm run build:docs",
41
41
  "publish:beta": "npm run build && tnpm publish",
42
+ "publish:npm": "npm publish --registry=https://registry.npmjs.org --access=public",
42
43
  "publish:prod": "npm run build && tnpm publish",
43
44
  "start": "dumi dev",
44
45
  "test": "jest",