@glodon-aiot/chat-app-sdk 0.0.15 → 0.0.16
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/es/index.esm.js +1102 -267
- package/libs/cn/index.js +7 -7
- package/package.json +1 -1
package/es/index.esm.js
CHANGED
|
@@ -267864,6 +267864,43 @@ class PreSendLocalMessageFactory {
|
|
|
267864
267864
|
}
|
|
267865
267865
|
}
|
|
267866
267866
|
|
|
267867
|
+
;// CONCATENATED MODULE: ../../../../../common/temp/default/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isEqual.js
|
|
267868
|
+
|
|
267869
|
+
|
|
267870
|
+
/**
|
|
267871
|
+
* Performs a deep comparison between two values to determine if they are
|
|
267872
|
+
* equivalent.
|
|
267873
|
+
*
|
|
267874
|
+
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
|
267875
|
+
* date objects, error objects, maps, numbers, `Object` objects, regexes,
|
|
267876
|
+
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
|
267877
|
+
* by their own, not inherited, enumerable properties. Functions and DOM
|
|
267878
|
+
* nodes are compared by strict equality, i.e. `===`.
|
|
267879
|
+
*
|
|
267880
|
+
* @static
|
|
267881
|
+
* @memberOf _
|
|
267882
|
+
* @since 0.1.0
|
|
267883
|
+
* @category Lang
|
|
267884
|
+
* @param {*} value The value to compare.
|
|
267885
|
+
* @param {*} other The other value to compare.
|
|
267886
|
+
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
267887
|
+
* @example
|
|
267888
|
+
*
|
|
267889
|
+
* var object = { 'a': 1 };
|
|
267890
|
+
* var other = { 'a': 1 };
|
|
267891
|
+
*
|
|
267892
|
+
* _.isEqual(object, other);
|
|
267893
|
+
* // => true
|
|
267894
|
+
*
|
|
267895
|
+
* object === other;
|
|
267896
|
+
* // => false
|
|
267897
|
+
*/
|
|
267898
|
+
function lodash_es_isEqual_isEqual(value, other) {
|
|
267899
|
+
return _baseIsEqual(value, other);
|
|
267900
|
+
}
|
|
267901
|
+
|
|
267902
|
+
/* ESM default export */ const lodash_es_isEqual = (lodash_es_isEqual_isEqual);
|
|
267903
|
+
|
|
267867
267904
|
;// CONCATENATED MODULE: ../../../../../common/temp/default/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseLodash.js
|
|
267868
267905
|
/**
|
|
267869
267906
|
* The function whose prototype chain sequence wrappers inherit from.
|
|
@@ -268366,10 +268403,126 @@ var flow = _createFlow();
|
|
|
268366
268403
|
|
|
268367
268404
|
class StreamBufferHelper {
|
|
268368
268405
|
/**
|
|
268406
|
+
* 合并两个 JSON 对象(深度合并)
|
|
268407
|
+
* - 如果两个值都是对象,递归合并
|
|
268408
|
+
* - 如果两个值都是字符串,追加字符串
|
|
268409
|
+
* - 如果两个值都是数组,合并数组(按索引合并)
|
|
268410
|
+
* - 否则使用 curr 的值(覆盖)
|
|
268411
|
+
*/ mergeJsonObjects(prev, curr) {
|
|
268412
|
+
const merged = {
|
|
268413
|
+
...prev
|
|
268414
|
+
};
|
|
268415
|
+
for(const key in curr){
|
|
268416
|
+
if (Object.prototype.hasOwnProperty.call(curr, key)) {
|
|
268417
|
+
const prevValue = prev[key];
|
|
268418
|
+
const currValue = curr[key];
|
|
268419
|
+
// 如果两个值都是对象,递归合并
|
|
268420
|
+
if (typeof prevValue === 'object' && prevValue !== null && !Array.isArray(prevValue) && typeof currValue === 'object' && currValue !== null && !Array.isArray(currValue)) {
|
|
268421
|
+
merged[key] = this.mergeJsonObjects(prevValue, currValue);
|
|
268422
|
+
} else if (typeof prevValue === 'string' && typeof currValue === 'string') {
|
|
268423
|
+
// 如果两个值都是字符串,追加字符串
|
|
268424
|
+
merged[key] = prevValue + currValue;
|
|
268425
|
+
} else if (Array.isArray(prevValue) && Array.isArray(currValue)) {
|
|
268426
|
+
// 如果两个值都是数组,按索引合并
|
|
268427
|
+
const mergedArray = [
|
|
268428
|
+
...prevValue
|
|
268429
|
+
];
|
|
268430
|
+
for(let i = 0; i < currValue.length; i++){
|
|
268431
|
+
const currItem = currValue[i];
|
|
268432
|
+
if (i < mergedArray.length) {
|
|
268433
|
+
// 如果索引已存在,尝试合并
|
|
268434
|
+
const prevItem = mergedArray[i];
|
|
268435
|
+
if (typeof prevItem === 'object' && prevItem !== null && !Array.isArray(prevItem) && typeof currItem === 'object' && currItem !== null && !Array.isArray(currItem)) {
|
|
268436
|
+
mergedArray[i] = this.mergeJsonObjects(prevItem, currItem);
|
|
268437
|
+
} else {
|
|
268438
|
+
mergedArray[i] = currItem;
|
|
268439
|
+
}
|
|
268440
|
+
} else {
|
|
268441
|
+
// 如果索引超出范围,追加新元素
|
|
268442
|
+
mergedArray.push(currItem);
|
|
268443
|
+
}
|
|
268444
|
+
}
|
|
268445
|
+
merged[key] = mergedArray;
|
|
268446
|
+
} else {
|
|
268447
|
+
// 否则使用 curr 的值(覆盖)
|
|
268448
|
+
merged[key] = currValue;
|
|
268449
|
+
}
|
|
268450
|
+
}
|
|
268451
|
+
}
|
|
268452
|
+
return merged;
|
|
268453
|
+
}
|
|
268454
|
+
/**
|
|
268369
268455
|
* Added Chunk message cache
|
|
268370
268456
|
*/ pushChunk(chunk) {
|
|
268371
268457
|
this.streamChunkBuffer.push(chunk);
|
|
268372
268458
|
}
|
|
268459
|
+
/**
|
|
268460
|
+
* Merge item_list arrays by index, handling JSON items specially
|
|
268461
|
+
*/ mergeItemList(prevItemList, currItemList) {
|
|
268462
|
+
const mergedItemList = [
|
|
268463
|
+
...prevItemList
|
|
268464
|
+
];
|
|
268465
|
+
for(let i = 0; i < currItemList.length; i++){
|
|
268466
|
+
const currItem = currItemList[i];
|
|
268467
|
+
if (i < mergedItemList.length) {
|
|
268468
|
+
const prevItem = mergedItemList[i];
|
|
268469
|
+
// Special handling: if both items are JSON items, merge their json fields
|
|
268470
|
+
if (typeof prevItem === 'object' && prevItem !== null && typeof currItem === 'object' && currItem !== null && 'type' in prevItem && 'type' in currItem && prevItem.type === types_ContentType.Json && currItem.type === types_ContentType.Json && 'json' in prevItem && 'json' in currItem) {
|
|
268471
|
+
const prevJson = prevItem.json;
|
|
268472
|
+
const currJson = currItem.json;
|
|
268473
|
+
// If both json fields are arrays, merge arrays by index
|
|
268474
|
+
if (Array.isArray(prevJson) && Array.isArray(currJson)) {
|
|
268475
|
+
const prevJsonArray = prevJson;
|
|
268476
|
+
const currJsonArray = currJson;
|
|
268477
|
+
const mergedJsonArray = [
|
|
268478
|
+
...prevJsonArray
|
|
268479
|
+
];
|
|
268480
|
+
for(let j = 0; j < currJsonArray.length; j++){
|
|
268481
|
+
if (j < mergedJsonArray.length) {
|
|
268482
|
+
mergedJsonArray[j] = currJsonArray[j];
|
|
268483
|
+
} else {
|
|
268484
|
+
mergedJsonArray.push(currJsonArray[j]);
|
|
268485
|
+
}
|
|
268486
|
+
}
|
|
268487
|
+
mergedItemList[i] = {
|
|
268488
|
+
...currItem,
|
|
268489
|
+
json: mergedJsonArray
|
|
268490
|
+
};
|
|
268491
|
+
} else if (typeof prevJson === 'object' && prevJson !== null && !Array.isArray(prevJson) && typeof currJson === 'object' && currJson !== null && !Array.isArray(currJson)) {
|
|
268492
|
+
// If both json fields are objects, deep merge them
|
|
268493
|
+
const mergedJson = this.mergeJsonObjects(prevJson, currJson);
|
|
268494
|
+
mergedItemList[i] = {
|
|
268495
|
+
...currItem,
|
|
268496
|
+
json: mergedJson
|
|
268497
|
+
};
|
|
268498
|
+
} else if (!lodash_es_isEqual(prevItem, currItem)) {
|
|
268499
|
+
mergedItemList[i] = currItem;
|
|
268500
|
+
}
|
|
268501
|
+
} else if (!lodash_es_isEqual(prevItem, currItem)) {
|
|
268502
|
+
mergedItemList[i] = currItem;
|
|
268503
|
+
}
|
|
268504
|
+
} else {
|
|
268505
|
+
mergedItemList.push(currItem);
|
|
268506
|
+
}
|
|
268507
|
+
}
|
|
268508
|
+
return mergedItemList;
|
|
268509
|
+
}
|
|
268510
|
+
/**
|
|
268511
|
+
* Merge refer_items arrays by index
|
|
268512
|
+
*/ mergeReferItems(prevReferItems, currReferItems) {
|
|
268513
|
+
const mergedReferItems = [
|
|
268514
|
+
...prevReferItems
|
|
268515
|
+
];
|
|
268516
|
+
for(let i = 0; i < currReferItems.length; i++){
|
|
268517
|
+
const currReferItem = currReferItems[i];
|
|
268518
|
+
if (i < mergedReferItems.length) {
|
|
268519
|
+
mergedReferItems[i] = currReferItem;
|
|
268520
|
+
} else {
|
|
268521
|
+
mergedReferItems.push(currReferItem);
|
|
268522
|
+
}
|
|
268523
|
+
}
|
|
268524
|
+
return mergedReferItems;
|
|
268525
|
+
}
|
|
268373
268526
|
concatContentAndUpdateMessage(message) {
|
|
268374
268527
|
const previousIndex = this.streamMessageBuffer.findIndex((item)=>item.message_id === message.message_id);
|
|
268375
268528
|
// new
|
|
@@ -268379,27 +268532,45 @@ class StreamBufferHelper {
|
|
|
268379
268532
|
}
|
|
268380
268533
|
// update
|
|
268381
268534
|
const previousMessage = this.streamMessageBuffer.at(previousIndex);
|
|
268535
|
+
// 如果是 completed 消息(is_finish = true),直接替换,不合并
|
|
268536
|
+
if (message.is_finish) {
|
|
268537
|
+
this.streamMessageBuffer[previousIndex] = message;
|
|
268538
|
+
return;
|
|
268539
|
+
}
|
|
268382
268540
|
// For Mix type (object_string), merge item_list arrays instead of string concatenation
|
|
268541
|
+
// Support streaming messages: when receiving message.delta data with object_string content,
|
|
268542
|
+
// merge it with previous data of the same message using append rule
|
|
268543
|
+
// IMPORTANT: Current content may contain the full accumulated array, so we need to compare
|
|
268544
|
+
// and only add new items that don't exist in the previous content
|
|
268383
268545
|
if (message.content_type === types_ContentType.Mix) {
|
|
268384
268546
|
try {
|
|
268385
|
-
var _prevContent_value, _currContent_value;
|
|
268547
|
+
var _prevContent_value, _currContent_value, _prevContent_value1, _currContent_value1;
|
|
268386
268548
|
const prevContent = safeJSONParse((previousMessage === null || previousMessage === void 0 ? void 0 : previousMessage.content) || '{}', {
|
|
268387
|
-
item_list: []
|
|
268549
|
+
item_list: [],
|
|
268550
|
+
refer_items: []
|
|
268388
268551
|
});
|
|
268389
268552
|
const currContent = safeJSONParse(message.content, {
|
|
268390
|
-
item_list: []
|
|
268553
|
+
item_list: [],
|
|
268554
|
+
refer_items: []
|
|
268391
268555
|
});
|
|
268556
|
+
const prevItemList = ((_prevContent_value = prevContent.value) === null || _prevContent_value === void 0 ? void 0 : _prevContent_value.item_list) || [];
|
|
268557
|
+
const currItemList = ((_currContent_value = currContent.value) === null || _currContent_value === void 0 ? void 0 : _currContent_value.item_list) || [];
|
|
268558
|
+
const prevReferItems = ((_prevContent_value1 = prevContent.value) === null || _prevContent_value1 === void 0 ? void 0 : _prevContent_value1.refer_items) || [];
|
|
268559
|
+
const currReferItems = ((_currContent_value1 = currContent.value) === null || _currContent_value1 === void 0 ? void 0 : _currContent_value1.refer_items) || [];
|
|
268560
|
+
// Merge item_list by index: update items at the same index, keep previous items if not updated
|
|
268561
|
+
// For arrays, merge by index position: update existing items, keep others unchanged
|
|
268562
|
+
// Special handling: if both prevItem and currItem are JSON items with array json fields, merge the arrays
|
|
268563
|
+
const mergedItemList = this.mergeItemList(prevItemList, currItemList);
|
|
268564
|
+
const mergedReferItems = this.mergeReferItems(prevReferItems, currReferItems);
|
|
268392
268565
|
const mergedContent = {
|
|
268393
|
-
item_list:
|
|
268394
|
-
|
|
268395
|
-
...((_currContent_value = currContent.value) === null || _currContent_value === void 0 ? void 0 : _currContent_value.item_list) || []
|
|
268396
|
-
],
|
|
268397
|
-
refer_items: []
|
|
268566
|
+
item_list: mergedItemList,
|
|
268567
|
+
refer_items: mergedReferItems
|
|
268398
268568
|
};
|
|
268399
268569
|
message.content = JSON.stringify(mergedContent);
|
|
268400
268570
|
message.content_obj = mergedContent;
|
|
268401
268571
|
} catch (e) {
|
|
268402
268572
|
// Fallback to string concatenation if parsing fails
|
|
268573
|
+
// Error is intentionally ignored as we fallback to string concatenation
|
|
268403
268574
|
message.content = ((previousMessage === null || previousMessage === void 0 ? void 0 : previousMessage.content) || '') + message.content;
|
|
268404
268575
|
message.content_obj = message.content;
|
|
268405
268576
|
}
|
|
@@ -268510,7 +268681,8 @@ class ChunkProcessor {
|
|
|
268510
268681
|
const { message } = chunk;
|
|
268511
268682
|
// Find all corresponding replies
|
|
268512
268683
|
const replyMessages = this.getReplyMessagesByReplyId(message.reply_id);
|
|
268513
|
-
// Find if there is a verbose message, and identify the end of the answer,
|
|
268684
|
+
// Find if there is a verbose message, and identify the end of the answer,
|
|
268685
|
+
// and filter out the finish of the interrupt scene
|
|
268514
268686
|
const finalAnswerVerboseMessage = replyMessages.find((replyMessage)=>{
|
|
268515
268687
|
const { type, content } = replyMessage;
|
|
268516
268688
|
if (type !== 'verbose') {
|
|
@@ -268521,7 +268693,9 @@ class ChunkProcessor {
|
|
|
268521
268693
|
return false;
|
|
268522
268694
|
}
|
|
268523
268695
|
const { value: verboseContentData } = safeJSONParse(verboseContent.data, null);
|
|
268524
|
-
// At present, there may be a finish package in a group.
|
|
268696
|
+
// At present, there may be a finish package in a group.
|
|
268697
|
+
// If you need to filter out the interrupt scene through finish_reason,
|
|
268698
|
+
// you will get the finish that answers all the ends.
|
|
268525
268699
|
return verboseContent.msg_type === types_VerboseMsgType.GENERATE_ANSWER_FINISH && (verboseContentData === null || verboseContentData === void 0 ? void 0 : verboseContentData.finish_reason) !== types_FinishReasonType.INTERRUPT;
|
|
268526
268700
|
});
|
|
268527
268701
|
return Boolean(finalAnswerVerboseMessage);
|
|
@@ -269345,6 +269519,14 @@ class HttpChunk extends CustomEventEmitter {
|
|
|
269345
269519
|
}
|
|
269346
269520
|
await fetchStream(channelFetchInfo.url, {
|
|
269347
269521
|
onStart: (response)=>{
|
|
269522
|
+
// 如果状态码是错误状态码(>= HTTP_BAD_REQUEST),尝试读取响应体以获取错误信息
|
|
269523
|
+
const HTTP_BAD_REQUEST = 400;
|
|
269524
|
+
if (response.status >= HTTP_BAD_REQUEST) {
|
|
269525
|
+
const cloneResponse = response.clone();
|
|
269526
|
+
cloneResponse.text().catch(()=>{
|
|
269527
|
+
// 忽略读取错误
|
|
269528
|
+
});
|
|
269529
|
+
}
|
|
269348
269530
|
fetchDataHelper.setLogID(response.headers.get('x-tt-logid'));
|
|
269349
269531
|
return Promise.resolve();
|
|
269350
269532
|
},
|
|
@@ -269392,7 +269574,8 @@ class HttpChunk extends CustomEventEmitter {
|
|
|
269392
269574
|
streamParser: (onGetMessageStreamParser === null || onGetMessageStreamParser === void 0 ? void 0 : onGetMessageStreamParser(value)) || utils_streamParser,
|
|
269393
269575
|
dataClump: fetchDataHelper,
|
|
269394
269576
|
body: channelFetchInfo.body,
|
|
269395
|
-
headers
|
|
269577
|
+
// 将 headers 数组转换为 Headers 对象,因为 fetch API 需要 Headers 对象或普通对象
|
|
269578
|
+
headers: new Headers(channelFetchInfo.headers),
|
|
269396
269579
|
method: channelFetchInfo.method,
|
|
269397
269580
|
signal: fetchDataHelper.abortSignal.signal,
|
|
269398
269581
|
totalFetchTimeout: fetchDataHelper.totalFetchTimeout,
|
|
@@ -269418,7 +269601,8 @@ class HttpChunk extends CustomEventEmitter {
|
|
|
269418
269601
|
}
|
|
269419
269602
|
this.customEmit(http_chunk_events_HttpChunkEvents.READ_STREAM_ERROR, errorInfo);
|
|
269420
269603
|
return;
|
|
269421
|
-
// TODO: The following should be the logic to re-pull the message.
|
|
269604
|
+
// TODO: The following should be the logic to re-pull the message.
|
|
269605
|
+
// The server level did not have time to do it in this issue.
|
|
269422
269606
|
// if (dataClump.retryCounter.matchMaxRetryAttempts()) {
|
|
269423
269607
|
// this.customOnError?.(errorInfo);
|
|
269424
269608
|
// //give up trying and try again
|
|
@@ -271827,43 +272011,6 @@ function isError_isError(value) {
|
|
|
271827
272011
|
|
|
271828
272012
|
/* ESM default export */ const lodash_es_isError = (isError_isError);
|
|
271829
272013
|
|
|
271830
|
-
;// CONCATENATED MODULE: ../../../../../common/temp/default/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isEqual.js
|
|
271831
|
-
|
|
271832
|
-
|
|
271833
|
-
/**
|
|
271834
|
-
* Performs a deep comparison between two values to determine if they are
|
|
271835
|
-
* equivalent.
|
|
271836
|
-
*
|
|
271837
|
-
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
|
271838
|
-
* date objects, error objects, maps, numbers, `Object` objects, regexes,
|
|
271839
|
-
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
|
271840
|
-
* by their own, not inherited, enumerable properties. Functions and DOM
|
|
271841
|
-
* nodes are compared by strict equality, i.e. `===`.
|
|
271842
|
-
*
|
|
271843
|
-
* @static
|
|
271844
|
-
* @memberOf _
|
|
271845
|
-
* @since 0.1.0
|
|
271846
|
-
* @category Lang
|
|
271847
|
-
* @param {*} value The value to compare.
|
|
271848
|
-
* @param {*} other The other value to compare.
|
|
271849
|
-
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
271850
|
-
* @example
|
|
271851
|
-
*
|
|
271852
|
-
* var object = { 'a': 1 };
|
|
271853
|
-
* var other = { 'a': 1 };
|
|
271854
|
-
*
|
|
271855
|
-
* _.isEqual(object, other);
|
|
271856
|
-
* // => true
|
|
271857
|
-
*
|
|
271858
|
-
* object === other;
|
|
271859
|
-
* // => false
|
|
271860
|
-
*/
|
|
271861
|
-
function lodash_es_isEqual_isEqual(value, other) {
|
|
271862
|
-
return _baseIsEqual(value, other);
|
|
271863
|
-
}
|
|
271864
|
-
|
|
271865
|
-
/* ESM default export */ const lodash_es_isEqual = (lodash_es_isEqual_isEqual);
|
|
271866
|
-
|
|
271867
272014
|
;// CONCATENATED MODULE: ../../../../../common/temp/default/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/head.js
|
|
271868
272015
|
/**
|
|
271869
272016
|
* Gets the first element of `array`.
|
|
@@ -297547,6 +297694,9 @@ const JsonItemList = (param)=>{
|
|
|
297547
297694
|
}
|
|
297548
297695
|
return /*#__PURE__*/ (0,jsx_runtime.jsx)(jsx_runtime.Fragment, {
|
|
297549
297696
|
children: jsonItemList.map((item, idx)=>{
|
|
297697
|
+
// Use a stable key based on item content and index to avoid React reusing components incorrectly
|
|
297698
|
+
// This ensures that when items are updated, React correctly updates the component instead of reusing it
|
|
297699
|
+
const itemKey = `json-${message.message_id}-${idx}-${JSON.stringify(item.json).slice(0, 50)}`;
|
|
297550
297700
|
if (JsonItem) {
|
|
297551
297701
|
return /*#__PURE__*/ (0,jsx_runtime.jsx)("div", {
|
|
297552
297702
|
// className={typeSafeMessageBoxInnerVariants({
|
|
@@ -297563,7 +297713,7 @@ const JsonItemList = (param)=>{
|
|
|
297563
297713
|
schemaVersion: item.schema_version,
|
|
297564
297714
|
message: message
|
|
297565
297715
|
})
|
|
297566
|
-
},
|
|
297716
|
+
}, itemKey);
|
|
297567
297717
|
}
|
|
297568
297718
|
// Default fallback: use built-in JSON viewer
|
|
297569
297719
|
return /*#__PURE__*/ (0,jsx_runtime.jsx)("div", {
|
|
@@ -297574,7 +297724,7 @@ const JsonItemList = (param)=>{
|
|
|
297574
297724
|
data: item.json,
|
|
297575
297725
|
schemaVersion: item.schema_version
|
|
297576
297726
|
})
|
|
297577
|
-
},
|
|
297727
|
+
}, itemKey);
|
|
297578
297728
|
})
|
|
297579
297729
|
});
|
|
297580
297730
|
};
|
|
@@ -407437,6 +407587,8 @@ const usePaginationRequest = (param)=>{
|
|
|
407437
407587
|
const [currentPage, setCurrentPage] = (0,react.useState)(initialPageNum);
|
|
407438
407588
|
const [allData, setAllData] = (0,react.useState)([]);
|
|
407439
407589
|
const [hasMore, setHasMore] = (0,react.useState)(true);
|
|
407590
|
+
// 使用 ref 跟踪是否已经自动加载过,避免重复请求
|
|
407591
|
+
const hasAutoLoadedRef = (0,react.useRef)(false);
|
|
407440
407592
|
const { loading, error, run } = es_useRequest(async (pageNum)=>{
|
|
407441
407593
|
const targetPage = pageNum ?? currentPage;
|
|
407442
407594
|
const params = {
|
|
@@ -407526,8 +407678,10 @@ const usePaginationRequest = (param)=>{
|
|
|
407526
407678
|
});
|
|
407527
407679
|
}, []);
|
|
407528
407680
|
// 组件挂载时自动加载第一页
|
|
407681
|
+
// 修复:使用 ref 跟踪是否已加载,避免重复请求
|
|
407529
407682
|
(0,react.useEffect)(()=>{
|
|
407530
|
-
if (autoLoad) {
|
|
407683
|
+
if (autoLoad && !hasAutoLoadedRef.current) {
|
|
407684
|
+
hasAutoLoadedRef.current = true;
|
|
407531
407685
|
run(initialPageNum);
|
|
407532
407686
|
}
|
|
407533
407687
|
}, [
|
|
@@ -407551,7 +407705,7 @@ const usePaginationRequest = (param)=>{
|
|
|
407551
407705
|
};
|
|
407552
407706
|
|
|
407553
407707
|
;// CONCATENATED MODULE: ../open-chat/src/components/studio-open-chat/hooks/use-conversation-list.ts
|
|
407554
|
-
/*
|
|
407708
|
+
/* eslint-disable max-lines -- This file handles complex conversation list synchronization logic that requires many lines */ /*
|
|
407555
407709
|
* Copyright 2025 coze-dev Authors
|
|
407556
407710
|
*
|
|
407557
407711
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -407581,7 +407735,7 @@ const usePaginationRequest = (param)=>{
|
|
|
407581
407735
|
|
|
407582
407736
|
|
|
407583
407737
|
|
|
407584
|
-
// eslint-disable-next-line @coze-arch/max-line-per-function
|
|
407738
|
+
// eslint-disable-next-line @coze-arch/max-line-per-function -- This hook handles complex conversation list management logic that requires many lines
|
|
407585
407739
|
const useConversationList = (conversationListParams)=>{
|
|
407586
407740
|
const { pageSize = 20, initialPageNum = 1, order = 'updated_at' } = conversationListParams ?? {};
|
|
407587
407741
|
const { chatConfig: { bot_id: botId, appInfo, type: chatType, auth: { connectorId } = {} } } = context_useChatAppProps();
|
|
@@ -407601,15 +407755,29 @@ const useConversationList = (conversationListParams)=>{
|
|
|
407601
407755
|
// 使用 ref 来跟踪是否正在同步,避免循环更新
|
|
407602
407756
|
const isSyncingRef = (0,react.useRef)(false);
|
|
407603
407757
|
const lastStoreIdsRef = (0,react.useRef)('');
|
|
407758
|
+
// 使用 ref 原子性地跟踪 App 模式的加载状态,防止竞态条件
|
|
407759
|
+
const appModeLoadingRef = (0,react.useRef)(false);
|
|
407604
407760
|
// App 模式:使用基于 before_updated_at 和 limit 的加载逻辑
|
|
407605
407761
|
const [appModeData, setAppModeData] = (0,react.useState)([]);
|
|
407606
407762
|
const [appModeLoading, setAppModeLoading] = (0,react.useState)(false);
|
|
407607
407763
|
const [appModeHasMore, setAppModeHasMore] = (0,react.useState)(true);
|
|
407608
407764
|
const [beforeUpdatedAt, setBeforeUpdatedAt] = (0,react.useState)(undefined);
|
|
407765
|
+
// 同步 appModeLoading 状态到 ref
|
|
407766
|
+
(0,react.useEffect)(()=>{
|
|
407767
|
+
appModeLoadingRef.current = appModeLoading;
|
|
407768
|
+
}, [
|
|
407769
|
+
appModeLoading
|
|
407770
|
+
]);
|
|
407609
407771
|
const loadAppModeConversations = (0,react.useCallback)(async (beforeTimestamp)=>{
|
|
407610
|
-
if (!cozeApiSdk || !hasValidId || !isAppType
|
|
407772
|
+
if (!cozeApiSdk || !hasValidId || !isAppType) {
|
|
407773
|
+
return;
|
|
407774
|
+
}
|
|
407775
|
+
// 原子性检查:如果已经在加载,直接返回
|
|
407776
|
+
if (appModeLoadingRef.current) {
|
|
407611
407777
|
return;
|
|
407612
407778
|
}
|
|
407779
|
+
// 原子性设置:立即设置 ref,防止并发调用
|
|
407780
|
+
appModeLoadingRef.current = true;
|
|
407613
407781
|
setAppModeLoading(true);
|
|
407614
407782
|
try {
|
|
407615
407783
|
var _res_data, _res_data1;
|
|
@@ -407674,6 +407842,8 @@ const useConversationList = (conversationListParams)=>{
|
|
|
407674
407842
|
console.error(e);
|
|
407675
407843
|
setAppModeHasMore(false);
|
|
407676
407844
|
} finally{
|
|
407845
|
+
// 原子性重置:先重置 ref,再更新状态
|
|
407846
|
+
appModeLoadingRef.current = false;
|
|
407677
407847
|
setAppModeLoading(false);
|
|
407678
407848
|
}
|
|
407679
407849
|
}, [
|
|
@@ -407787,18 +407957,36 @@ const useConversationList = (conversationListParams)=>{
|
|
|
407787
407957
|
// 同步 finalData 到 store(只在本地数据源变化时更新 store,避免循环)
|
|
407788
407958
|
// 注意:这个 useEffect 只在从服务器加载数据时触发,不会在 store 同步到本地数据源时触发
|
|
407789
407959
|
(0,react.useEffect)(()=>{
|
|
407790
|
-
|
|
407960
|
+
// 如果正在同步,跳过,避免循环更新
|
|
407961
|
+
if (isSyncingRef.current) {
|
|
407962
|
+
return;
|
|
407963
|
+
}
|
|
407964
|
+
if (finalData && finalData.length > 0) {
|
|
407791
407965
|
// 比较数据是否真的变化了,避免不必要的更新
|
|
407792
407966
|
const currentIds = conversations.map((c)=>c.id).sort().join(',');
|
|
407793
407967
|
const newIds = finalData.map((c)=>c.id).sort().join(',');
|
|
407968
|
+
// 只有在 ID 列表真的发生变化时才更新 store
|
|
407969
|
+
// 这样可以避免因为对象引用变化导致的重复更新
|
|
407794
407970
|
if (currentIds !== newIds) {
|
|
407795
|
-
//
|
|
407796
|
-
//
|
|
407797
|
-
|
|
407798
|
-
|
|
407799
|
-
|
|
407800
|
-
|
|
407801
|
-
|
|
407971
|
+
// 检查是否是store新增了会话(store的ID数量增加了)
|
|
407972
|
+
// 如果是store新增,不应该在这里更新store,应该让监听store的useEffect处理
|
|
407973
|
+
const storeCount = conversations.length;
|
|
407974
|
+
const finalDataCount = finalData.length;
|
|
407975
|
+
const isStoreNewer = storeCount > finalDataCount;
|
|
407976
|
+
// 只有在finalData比store新(从服务器加载了新数据)时才更新store
|
|
407977
|
+
// 如果store比finalData新(store新增了会话),不应该更新store
|
|
407978
|
+
if (!isStoreNewer) {
|
|
407979
|
+
// 只有在本地数据源是从服务器加载的新数据时才更新 store
|
|
407980
|
+
// 如果是因为 store 同步导致的 finalData 变化,不应该再次更新 store
|
|
407981
|
+
isSyncingRef.current = true;
|
|
407982
|
+
updateConversations(finalData, 'replace');
|
|
407983
|
+
// 使用 requestAnimationFrame 确保在下一个事件循环中重置标志
|
|
407984
|
+
requestAnimationFrame(()=>{
|
|
407985
|
+
setTimeout(()=>{
|
|
407986
|
+
isSyncingRef.current = false;
|
|
407987
|
+
}, 0);
|
|
407988
|
+
});
|
|
407989
|
+
}
|
|
407802
407990
|
}
|
|
407803
407991
|
}
|
|
407804
407992
|
}, [
|
|
@@ -407806,99 +407994,182 @@ const useConversationList = (conversationListParams)=>{
|
|
|
407806
407994
|
updateConversations,
|
|
407807
407995
|
conversations
|
|
407808
407996
|
]);
|
|
407997
|
+
// 检查会话是否有更新的辅助函数
|
|
407998
|
+
const checkConversationUpdates = (0,react.useCallback)((storeConversations, localConversations)=>{
|
|
407999
|
+
const localMap = new Map(localConversations.map((c)=>[
|
|
408000
|
+
c.id,
|
|
408001
|
+
c
|
|
408002
|
+
]));
|
|
408003
|
+
return storeConversations.some((storeConv)=>{
|
|
408004
|
+
const localConv = localMap.get(storeConv.id);
|
|
408005
|
+
if (!localConv) {
|
|
408006
|
+
return false;
|
|
408007
|
+
}
|
|
408008
|
+
const storeConvWithTitle = storeConv;
|
|
408009
|
+
const localConvWithTitle = localConv;
|
|
408010
|
+
return storeConvWithTitle.title !== localConvWithTitle.title || storeConv.name !== localConv.name || storeConv.updated_at !== localConv.updated_at;
|
|
408011
|
+
});
|
|
408012
|
+
}, []);
|
|
408013
|
+
// 同步 App 模式更新的辅助函数
|
|
408014
|
+
const syncAppModeUpdates = (0,react.useCallback)(()=>{
|
|
408015
|
+
isSyncingRef.current = true;
|
|
408016
|
+
setAppModeData((prev)=>{
|
|
408017
|
+
const prevMap = new Map(prev.map((c)=>[
|
|
408018
|
+
c.id,
|
|
408019
|
+
c
|
|
408020
|
+
]));
|
|
408021
|
+
return conversations.map((storeConv)=>{
|
|
408022
|
+
const prevConv = prevMap.get(storeConv.id);
|
|
408023
|
+
return prevConv ? {
|
|
408024
|
+
...prevConv,
|
|
408025
|
+
...storeConv
|
|
408026
|
+
} : storeConv;
|
|
408027
|
+
});
|
|
408028
|
+
});
|
|
408029
|
+
requestAnimationFrame(()=>{
|
|
408030
|
+
setTimeout(()=>{
|
|
408031
|
+
isSyncingRef.current = false;
|
|
408032
|
+
}, 0);
|
|
408033
|
+
});
|
|
408034
|
+
}, [
|
|
408035
|
+
conversations
|
|
408036
|
+
]);
|
|
408037
|
+
// 同步 Bot 模式更新的辅助函数
|
|
408038
|
+
const syncBotModeUpdates = (0,react.useCallback)(()=>{
|
|
408039
|
+
isSyncingRef.current = true;
|
|
408040
|
+
const localMap = new Map(data.map((c)=>[
|
|
408041
|
+
c.id,
|
|
408042
|
+
c
|
|
408043
|
+
]));
|
|
408044
|
+
const updatedConversations = conversations.filter((storeConv)=>localMap.has(storeConv.id)).map((storeConv)=>{
|
|
408045
|
+
const localConv = localMap.get(storeConv.id);
|
|
408046
|
+
return localConv ? {
|
|
408047
|
+
...localConv,
|
|
408048
|
+
...storeConv
|
|
408049
|
+
} : storeConv;
|
|
408050
|
+
});
|
|
408051
|
+
updatedConversations.forEach((conv)=>{
|
|
408052
|
+
removeBotModeItem((c)=>c.id === conv.id);
|
|
408053
|
+
});
|
|
408054
|
+
updatedConversations.reverse().forEach((conv)=>{
|
|
408055
|
+
addBotModeItem(conv, 'start');
|
|
408056
|
+
});
|
|
408057
|
+
requestAnimationFrame(()=>{
|
|
408058
|
+
setTimeout(()=>{
|
|
408059
|
+
isSyncingRef.current = false;
|
|
408060
|
+
}, 0);
|
|
408061
|
+
});
|
|
408062
|
+
}, [
|
|
408063
|
+
conversations,
|
|
408064
|
+
data,
|
|
408065
|
+
removeBotModeItem,
|
|
408066
|
+
addBotModeItem
|
|
408067
|
+
]);
|
|
408068
|
+
// 处理删除的辅助函数
|
|
408069
|
+
const handleDeletions = (0,react.useCallback)((storeIds, localIds)=>{
|
|
408070
|
+
const deletedIds = Array.from(localIds).filter((id)=>!storeIds.has(id));
|
|
408071
|
+
if (deletedIds.length === 0) {
|
|
408072
|
+
return;
|
|
408073
|
+
}
|
|
408074
|
+
isSyncingRef.current = true;
|
|
408075
|
+
if (isAppType) {
|
|
408076
|
+
setAppModeData((prev)=>prev.filter((c)=>!deletedIds.includes(c.id)));
|
|
408077
|
+
} else {
|
|
408078
|
+
removeBotModeItem((c)=>deletedIds.includes(c.id));
|
|
408079
|
+
}
|
|
408080
|
+
requestAnimationFrame(()=>{
|
|
408081
|
+
setTimeout(()=>{
|
|
408082
|
+
isSyncingRef.current = false;
|
|
408083
|
+
}, 0);
|
|
408084
|
+
});
|
|
408085
|
+
}, [
|
|
408086
|
+
isAppType,
|
|
408087
|
+
removeBotModeItem
|
|
408088
|
+
]);
|
|
408089
|
+
// 处理新增会话的辅助函数
|
|
408090
|
+
const handleNewConversations = (0,react.useCallback)((newConversations)=>{
|
|
408091
|
+
if (newConversations.length === 0) {
|
|
408092
|
+
return;
|
|
408093
|
+
}
|
|
408094
|
+
isSyncingRef.current = true;
|
|
408095
|
+
try {
|
|
408096
|
+
if (isAppType) {
|
|
408097
|
+
setAppModeData((prev)=>[
|
|
408098
|
+
...newConversations,
|
|
408099
|
+
...prev
|
|
408100
|
+
]);
|
|
408101
|
+
} else {
|
|
408102
|
+
newConversations.forEach((conv)=>{
|
|
408103
|
+
addBotModeItem(conv, 'start');
|
|
408104
|
+
});
|
|
408105
|
+
}
|
|
408106
|
+
} finally{
|
|
408107
|
+
requestAnimationFrame(()=>{
|
|
408108
|
+
setTimeout(()=>{
|
|
408109
|
+
isSyncingRef.current = false;
|
|
408110
|
+
}, 50);
|
|
408111
|
+
});
|
|
408112
|
+
}
|
|
408113
|
+
}, [
|
|
408114
|
+
isAppType,
|
|
408115
|
+
addBotModeItem
|
|
408116
|
+
]);
|
|
407809
408117
|
// 监听 store 的 conversations 变化,同步更新本地数据源
|
|
407810
408118
|
// 只在 store 有新增会话时才同步,避免循环更新
|
|
407811
408119
|
(0,react.useEffect)(()=>{
|
|
408120
|
+
if (isSyncingRef.current) {
|
|
408121
|
+
return;
|
|
408122
|
+
}
|
|
407812
408123
|
const currentStoreIds = conversations.map((c)=>c.id).sort().join(',');
|
|
407813
|
-
|
|
407814
|
-
|
|
408124
|
+
const localConversations = isAppType ? appModeData : data;
|
|
408125
|
+
const hasUpdates = checkConversationUpdates(conversations, localConversations);
|
|
408126
|
+
if (currentStoreIds === lastStoreIdsRef.current && currentStoreIds !== '' && !hasUpdates) {
|
|
408127
|
+
return;
|
|
408128
|
+
}
|
|
408129
|
+
if (hasUpdates && (currentStoreIds === lastStoreIdsRef.current && currentStoreIds !== '' || lastStoreIdsRef.current === '' && currentStoreIds !== '')) {
|
|
408130
|
+
if (isAppType) {
|
|
408131
|
+
syncAppModeUpdates();
|
|
408132
|
+
} else {
|
|
408133
|
+
syncBotModeUpdates();
|
|
408134
|
+
}
|
|
408135
|
+
lastStoreIdsRef.current = currentStoreIds;
|
|
407815
408136
|
return;
|
|
407816
408137
|
}
|
|
407817
|
-
// 检查是否有新增(store 的数量增加了)
|
|
407818
408138
|
const storeCount = conversations.length;
|
|
407819
|
-
const lastStoreCount = lastStoreIdsRef.current.split(',').filter(Boolean).length;
|
|
408139
|
+
const lastStoreCount = lastStoreIdsRef.current ? lastStoreIdsRef.current.split(',').filter(Boolean).length : 0;
|
|
407820
408140
|
const hasNewConversations = storeCount > lastStoreCount;
|
|
407821
408141
|
const hasDeletedConversations = storeCount < lastStoreCount;
|
|
407822
|
-
// 更新 ref
|
|
407823
408142
|
lastStoreIdsRef.current = currentStoreIds;
|
|
407824
|
-
// 如果有删除,同步到本地数据源
|
|
407825
408143
|
if (hasDeletedConversations) {
|
|
407826
|
-
|
|
407827
|
-
|
|
407828
|
-
|
|
407829
|
-
}
|
|
407830
|
-
if (isAppType) {
|
|
407831
|
-
const storeIds = new Set(conversations.map((c)=>c.id));
|
|
407832
|
-
const localIds = new Set(appModeData.map((c)=>c.id));
|
|
407833
|
-
const deletedIds = Array.from(localIds).filter((id)=>!storeIds.has(id));
|
|
407834
|
-
if (deletedIds.length > 0) {
|
|
407835
|
-
isSyncingRef.current = true;
|
|
407836
|
-
setAppModeData((prev)=>prev.filter((c)=>!deletedIds.includes(c.id)));
|
|
407837
|
-
setTimeout(()=>{
|
|
407838
|
-
isSyncingRef.current = false;
|
|
407839
|
-
}, 0);
|
|
407840
|
-
}
|
|
407841
|
-
} else {
|
|
407842
|
-
const storeIds = new Set(conversations.map((c)=>c.id));
|
|
407843
|
-
const localIds = new Set(data.map((c)=>c.id));
|
|
407844
|
-
const deletedIds = Array.from(localIds).filter((id)=>!storeIds.has(id));
|
|
407845
|
-
if (deletedIds.length > 0) {
|
|
407846
|
-
isSyncingRef.current = true;
|
|
407847
|
-
removeBotModeItem((c)=>deletedIds.includes(c.id));
|
|
407848
|
-
setTimeout(()=>{
|
|
407849
|
-
isSyncingRef.current = false;
|
|
407850
|
-
}, 0);
|
|
407851
|
-
}
|
|
407852
|
-
}
|
|
408144
|
+
const storeIds = new Set(conversations.map((c)=>c.id));
|
|
408145
|
+
const localIds = new Set(localConversations.map((c)=>c.id));
|
|
408146
|
+
handleDeletions(storeIds, localIds);
|
|
407853
408147
|
return;
|
|
407854
408148
|
}
|
|
407855
|
-
// 只在有新增会话时才同步,避免其他变化导致的循环
|
|
407856
408149
|
if (!hasNewConversations && storeCount === lastStoreCount) {
|
|
407857
|
-
|
|
407858
|
-
|
|
407859
|
-
|
|
407860
|
-
|
|
407861
|
-
|
|
407862
|
-
|
|
407863
|
-
try {
|
|
407864
|
-
if (isAppType) {
|
|
407865
|
-
// App 模式:检查 store 中是否有新会话不在本地数据源中
|
|
407866
|
-
const localIds = new Set(appModeData.map((c)=>c.id));
|
|
407867
|
-
// 找出 store 中有但本地没有的会话(新添加的)
|
|
407868
|
-
const newConversations = conversations.filter((c)=>!localIds.has(c.id));
|
|
407869
|
-
if (newConversations.length > 0) {
|
|
407870
|
-
// 将新会话添加到本地数据源的开头(最新的会话应该在前面)
|
|
407871
|
-
setAppModeData((prev)=>[
|
|
407872
|
-
...newConversations,
|
|
407873
|
-
...prev
|
|
407874
|
-
]);
|
|
407875
|
-
}
|
|
407876
|
-
} else {
|
|
407877
|
-
// Bot 模式:检查 store 中是否有新会话不在本地数据源中
|
|
407878
|
-
const localIds = new Set(data.map((c)=>c.id));
|
|
407879
|
-
// 找出 store 中有但本地没有的会话(新添加的)
|
|
407880
|
-
const newConversations = conversations.filter((c)=>!localIds.has(c.id));
|
|
407881
|
-
if (newConversations.length > 0) {
|
|
407882
|
-
// 将新会话添加到本地数据源的开头(最新的会话应该在前面)
|
|
407883
|
-
newConversations.forEach((conv)=>{
|
|
407884
|
-
addBotModeItem(conv, 'start');
|
|
407885
|
-
});
|
|
408150
|
+
const hasLocalUpdates = checkConversationUpdates(conversations, localConversations);
|
|
408151
|
+
if (hasLocalUpdates) {
|
|
408152
|
+
if (isAppType) {
|
|
408153
|
+
syncAppModeUpdates();
|
|
408154
|
+
} else {
|
|
408155
|
+
syncBotModeUpdates();
|
|
407886
408156
|
}
|
|
407887
408157
|
}
|
|
407888
|
-
|
|
407889
|
-
// 使用 setTimeout 确保状态更新完成后再重置标志
|
|
407890
|
-
// 延迟时间稍微长一点,确保第一个 useEffect 不会触发
|
|
407891
|
-
setTimeout(()=>{
|
|
407892
|
-
isSyncingRef.current = false;
|
|
407893
|
-
}, 100);
|
|
408158
|
+
return;
|
|
407894
408159
|
}
|
|
408160
|
+
const localIds = new Set(localConversations.map((c)=>c.id));
|
|
408161
|
+
const newConversations = conversations.filter((c)=>!localIds.has(c.id));
|
|
408162
|
+
handleNewConversations(newConversations);
|
|
407895
408163
|
}, [
|
|
407896
408164
|
conversations,
|
|
407897
408165
|
isAppType,
|
|
407898
408166
|
appModeData,
|
|
407899
408167
|
data,
|
|
407900
|
-
|
|
407901
|
-
|
|
408168
|
+
checkConversationUpdates,
|
|
408169
|
+
syncAppModeUpdates,
|
|
408170
|
+
syncBotModeUpdates,
|
|
408171
|
+
handleDeletions,
|
|
408172
|
+
handleNewConversations
|
|
407902
408173
|
]);
|
|
407903
408174
|
(0,react.useEffect)(()=>{
|
|
407904
408175
|
if (!currentConversationInfo) {
|
|
@@ -407935,7 +408206,7 @@ const useConversationList = (conversationListParams)=>{
|
|
|
407935
408206
|
updateCurrentConversationInfo
|
|
407936
408207
|
]);
|
|
407937
408208
|
return {
|
|
407938
|
-
conversations,
|
|
408209
|
+
conversations: finalData,
|
|
407939
408210
|
loading: finalLoading,
|
|
407940
408211
|
hasMore: finalHasMore,
|
|
407941
408212
|
loadMore: finalLoadMore,
|
|
@@ -408046,12 +408317,12 @@ const isUUID = (str)=>{
|
|
|
408046
408317
|
};
|
|
408047
408318
|
/**
|
|
408048
408319
|
* 获取会话显示名称
|
|
408049
|
-
* 优先级:title
|
|
408320
|
+
* 优先级:title(如果不是UUID)> name(如果不是UUID)> 新创建的会话
|
|
408050
408321
|
* @param item 会话项
|
|
408051
408322
|
* @returns 显示名称
|
|
408052
408323
|
*/ const getConversationDisplayName = (item)=>{
|
|
408053
|
-
// 优先使用title
|
|
408054
|
-
if (item.title) {
|
|
408324
|
+
// 优先使用title,但需要检查是否是UUID
|
|
408325
|
+
if (item.title && !isUUID(item.title)) {
|
|
408055
408326
|
return item.title;
|
|
408056
408327
|
}
|
|
408057
408328
|
// 如果name存在且不是UUID格式,使用name
|
|
@@ -408059,7 +408330,7 @@ const isUUID = (str)=>{
|
|
|
408059
408330
|
return item.name;
|
|
408060
408331
|
}
|
|
408061
408332
|
// 否则显示"新创建的会话"
|
|
408062
|
-
return intl_i18n.t('web_sdk_conversation_default_name');
|
|
408333
|
+
return intl_i18n.t('web_sdk_conversation_default_name', {}, '新创建的会话');
|
|
408063
408334
|
};
|
|
408064
408335
|
|
|
408065
408336
|
;// CONCATENATED MODULE: ../open-chat/src/components/conversation-list-sider/conversation-item/mobile/operate/index.tsx
|
|
@@ -408555,6 +408826,16 @@ const ConversationList = /*#__PURE__*/ (0,react.forwardRef)(// eslint-disable-ne
|
|
|
408555
408826
|
]);
|
|
408556
408827
|
const listContainerRef = (0,react.useRef)(null);
|
|
408557
408828
|
const loadMoreRef = (0,react.useRef)(null);
|
|
408829
|
+
// 使用 ref 存储 loadMore 函数,避免 useEffect 依赖项变化导致 observer 重新创建
|
|
408830
|
+
const loadMoreRefFn = (0,react.useRef)(loadMore);
|
|
408831
|
+
// 使用 ref 跟踪是否正在加载,防止重复调用
|
|
408832
|
+
const isLoadingRef = (0,react.useRef)(false);
|
|
408833
|
+
// 更新 loadMoreRefFn 当 loadMore 变化时
|
|
408834
|
+
(0,react.useEffect)(()=>{
|
|
408835
|
+
loadMoreRefFn.current = loadMore;
|
|
408836
|
+
}, [
|
|
408837
|
+
loadMore
|
|
408838
|
+
]);
|
|
408558
408839
|
const handleCreateConversation = ()=>{
|
|
408559
408840
|
if (!currentConversationInfo) {
|
|
408560
408841
|
return Promise.resolve();
|
|
@@ -408696,11 +408977,21 @@ const ConversationList = /*#__PURE__*/ (0,react.forwardRef)(// eslint-disable-ne
|
|
|
408696
408977
|
handleCreateConversation,
|
|
408697
408978
|
handleDeleteConversation
|
|
408698
408979
|
}));
|
|
408980
|
+
// 同步 loading 状态到 ref
|
|
408981
|
+
(0,react.useEffect)(()=>{
|
|
408982
|
+
isLoadingRef.current = loading;
|
|
408983
|
+
}, [
|
|
408984
|
+
loading
|
|
408985
|
+
]);
|
|
408699
408986
|
(0,react.useEffect)(()=>{
|
|
408700
408987
|
const observer = new IntersectionObserver((entries)=>{
|
|
408701
408988
|
const [entry] = entries;
|
|
408702
|
-
|
|
408703
|
-
|
|
408989
|
+
// 使用 ref 中的最新值,避免闭包问题
|
|
408990
|
+
// 注意:loadMore 函数内部已经有原子性检查,这里只需要检查基本条件
|
|
408991
|
+
if (entry.isIntersecting && hasMore && !isLoadingRef.current) {
|
|
408992
|
+
// 使用 ref 中的最新函数
|
|
408993
|
+
// loadMore 函数内部已经有原子性检查,可以安全地多次调用
|
|
408994
|
+
loadMoreRefFn.current();
|
|
408704
408995
|
}
|
|
408705
408996
|
}, {
|
|
408706
408997
|
root: listContainerRef.current,
|
|
@@ -408711,15 +409002,12 @@ const ConversationList = /*#__PURE__*/ (0,react.forwardRef)(// eslint-disable-ne
|
|
|
408711
409002
|
observer.observe(loadMoreRef.current);
|
|
408712
409003
|
}
|
|
408713
409004
|
return ()=>{
|
|
408714
|
-
|
|
408715
|
-
|
|
408716
|
-
}
|
|
409005
|
+
// 确保完全断开 observer 连接,防止旧的 observer 继续工作
|
|
409006
|
+
observer.disconnect();
|
|
408717
409007
|
};
|
|
408718
409008
|
}, [
|
|
408719
|
-
hasMore
|
|
408720
|
-
|
|
408721
|
-
loadMore
|
|
408722
|
-
]);
|
|
409009
|
+
hasMore
|
|
409010
|
+
]); // 只依赖 hasMore,不依赖 loading 和 loadMore
|
|
408723
409011
|
return /*#__PURE__*/ (0,jsx_runtime.jsxs)("div", {
|
|
408724
409012
|
className: conversation_list_sider_conversation_list_index_module.conversations,
|
|
408725
409013
|
style: {
|
|
@@ -409219,6 +409507,13 @@ const storageUtil = {
|
|
|
409219
409507
|
|
|
409220
409508
|
|
|
409221
409509
|
|
|
409510
|
+
|
|
409511
|
+
|
|
409512
|
+
|
|
409513
|
+
|
|
409514
|
+
|
|
409515
|
+
|
|
409516
|
+
|
|
409222
409517
|
const getDefaultUserInfo = (userInfo)=>{
|
|
409223
409518
|
if (userInfo === null || userInfo === void 0 ? void 0 : userInfo.id) {
|
|
409224
409519
|
return userInfo;
|
|
@@ -409230,6 +409525,7 @@ const getDefaultUserInfo = (userInfo)=>{
|
|
|
409230
409525
|
url: ''
|
|
409231
409526
|
};
|
|
409232
409527
|
};
|
|
409528
|
+
// eslint-disable-next-line @coze-arch/max-line-per-function -- Store creation function contains comprehensive state management logic
|
|
409233
409529
|
const createChatStore = (chatConfig, userInfo)=>{
|
|
409234
409530
|
var _chatConfig_auth, _chatConfig_auth1;
|
|
409235
409531
|
const isNeedToken = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth = chatConfig.auth) === null || _chatConfig_auth === void 0 ? void 0 : _chatConfig_auth.type) === client_AuthType.TOKEN;
|
|
@@ -409413,20 +409709,28 @@ const createChatStore = (chatConfig, userInfo)=>{
|
|
|
409413
409709
|
]));
|
|
409414
409710
|
s.conversations = conversations.map((newConv)=>{
|
|
409415
409711
|
const existingConv = existingConversationsMap.get(newConv.id);
|
|
409416
|
-
|
|
409712
|
+
const existingConvWithTitle = existingConv;
|
|
409713
|
+
if (existingConvWithTitle === null || existingConvWithTitle === void 0 ? void 0 : existingConvWithTitle.title) {
|
|
409417
409714
|
// 如果store中已有该会话且有title,保留title
|
|
409418
|
-
return {
|
|
409419
|
-
...newConv
|
|
409420
|
-
|
|
409421
|
-
|
|
409715
|
+
return Object.assign({
|
|
409716
|
+
...newConv
|
|
409717
|
+
}, {
|
|
409718
|
+
title: existingConvWithTitle.title
|
|
409719
|
+
});
|
|
409422
409720
|
}
|
|
409423
409721
|
return newConv;
|
|
409424
409722
|
});
|
|
409425
409723
|
} else if (operate === 'add') {
|
|
409426
|
-
|
|
409427
|
-
|
|
409428
|
-
|
|
409429
|
-
|
|
409724
|
+
// 修复:添加去重逻辑,避免重复添加相同的会话
|
|
409725
|
+
const existingIds = new Set(s.conversations.map((c)=>c.id));
|
|
409726
|
+
const newConversations = conversations.filter((c)=>c.id && !existingIds.has(c.id));
|
|
409727
|
+
if (newConversations.length > 0) {
|
|
409728
|
+
// 将新会话添加到列表开头(最新的会话应该在前面)
|
|
409729
|
+
s.conversations = [
|
|
409730
|
+
...newConversations,
|
|
409731
|
+
...s.conversations
|
|
409732
|
+
];
|
|
409733
|
+
}
|
|
409430
409734
|
} else if (operate === 'remove') {
|
|
409431
409735
|
conversations.forEach((conversation)=>{
|
|
409432
409736
|
const index = s.conversations.findIndex((c)=>c.id === conversation.id);
|
|
@@ -417060,6 +417364,7 @@ const convertShortcutData = (shortcutCommands, botInfo)=>//@ts-expect-error: 不
|
|
|
417060
417364
|
|
|
417061
417365
|
|
|
417062
417366
|
|
|
417367
|
+
|
|
417063
417368
|
const microSeconds = 1000;
|
|
417064
417369
|
/**
|
|
417065
417370
|
* 从URL中提取文件名
|
|
@@ -417098,6 +417403,55 @@ const microSeconds = 1000;
|
|
|
417098
417403
|
};
|
|
417099
417404
|
// 消息转换成 Coze的消息,主要用于消息接收后,在页面显示。
|
|
417100
417405
|
class MessageConverseToCoze {
|
|
417406
|
+
/**
|
|
417407
|
+
* 合并两个 JSON 对象(深度合并)
|
|
417408
|
+
* - 如果两个值都是对象,递归合并
|
|
417409
|
+
* - 如果两个值都是字符串,追加字符串
|
|
417410
|
+
* - 如果两个值都是数组,合并数组(按索引合并)
|
|
417411
|
+
* - 否则使用 curr 的值(覆盖)
|
|
417412
|
+
*/ mergeJsonObjects(prev, curr) {
|
|
417413
|
+
const merged = {
|
|
417414
|
+
...prev
|
|
417415
|
+
};
|
|
417416
|
+
for(const key in curr){
|
|
417417
|
+
if (Object.prototype.hasOwnProperty.call(curr, key)) {
|
|
417418
|
+
const prevValue = prev[key];
|
|
417419
|
+
const currValue = curr[key];
|
|
417420
|
+
// 如果两个值都是对象,递归合并
|
|
417421
|
+
if (typeof prevValue === 'object' && prevValue !== null && !Array.isArray(prevValue) && typeof currValue === 'object' && currValue !== null && !Array.isArray(currValue)) {
|
|
417422
|
+
merged[key] = this.mergeJsonObjects(prevValue, currValue);
|
|
417423
|
+
} else if (typeof prevValue === 'string' && typeof currValue === 'string') {
|
|
417424
|
+
// 如果两个值都是字符串,追加字符串
|
|
417425
|
+
merged[key] = prevValue + currValue;
|
|
417426
|
+
} else if (Array.isArray(prevValue) && Array.isArray(currValue)) {
|
|
417427
|
+
// 如果两个值都是数组,按索引合并
|
|
417428
|
+
const mergedArray = [
|
|
417429
|
+
...prevValue
|
|
417430
|
+
];
|
|
417431
|
+
for(let i = 0; i < currValue.length; i++){
|
|
417432
|
+
const currItem = currValue[i];
|
|
417433
|
+
if (i < mergedArray.length) {
|
|
417434
|
+
// 如果索引已存在,尝试合并
|
|
417435
|
+
const prevItem = mergedArray[i];
|
|
417436
|
+
if (typeof prevItem === 'object' && prevItem !== null && !Array.isArray(prevItem) && typeof currItem === 'object' && currItem !== null && !Array.isArray(currItem)) {
|
|
417437
|
+
mergedArray[i] = this.mergeJsonObjects(prevItem, currItem);
|
|
417438
|
+
} else {
|
|
417439
|
+
mergedArray[i] = currItem;
|
|
417440
|
+
}
|
|
417441
|
+
} else {
|
|
417442
|
+
// 如果索引超出范围,追加新元素
|
|
417443
|
+
mergedArray.push(currItem);
|
|
417444
|
+
}
|
|
417445
|
+
}
|
|
417446
|
+
merged[key] = mergedArray;
|
|
417447
|
+
} else {
|
|
417448
|
+
// 否则使用 curr 的值(覆盖)
|
|
417449
|
+
merged[key] = currValue;
|
|
417450
|
+
}
|
|
417451
|
+
}
|
|
417452
|
+
}
|
|
417453
|
+
return merged;
|
|
417454
|
+
}
|
|
417101
417455
|
convertMessageListResponse(res) {
|
|
417102
417456
|
let botId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : '';
|
|
417103
417457
|
const { data: messageList = [], has_more: hasMore, first_id: firstId, last_id: lastId } = res;
|
|
@@ -417116,7 +417470,11 @@ class MessageConverseToCoze {
|
|
|
417116
417470
|
const { content_type, content } = this.convertContent(message.content_type, message.content) || {};
|
|
417117
417471
|
const isQuestion = message.type === 'question';
|
|
417118
417472
|
const replyId = message.chat_id || `--custom-replyId--${index_browser_nanoid()}`;
|
|
417119
|
-
|
|
417473
|
+
// 对于流式的 object_string 消息,使用 message.id 作为 message_id
|
|
417474
|
+
// 这样可以确保不同 id 的消息不会被合并
|
|
417475
|
+
const isStreamingObjectString = message.content_type === 'object_string' && message.type === 'answer';
|
|
417476
|
+
const messageId = isQuestion ? replyId : isStreamingObjectString ? message.id || `--custom-messageId-${index_browser_nanoid()}` // 对于流式 object_string,使用 message.id 作为 message_id
|
|
417477
|
+
: message.id || `--custom-messageId-${index_browser_nanoid()}`; // 无messageId,输出一个默认的
|
|
417120
417478
|
const senderId = isQuestion ? '' : message.bot_id || botId;
|
|
417121
417479
|
if (!content_type || !messageId || !replyId) {
|
|
417122
417480
|
return {};
|
|
@@ -417207,12 +417565,30 @@ class MessageConverseToCoze {
|
|
|
417207
417565
|
}
|
|
417208
417566
|
}
|
|
417209
417567
|
convertMixContent(content) {
|
|
417210
|
-
|
|
417211
|
-
|
|
417568
|
+
// 先尝试解析 JSON 字符串为数组
|
|
417569
|
+
// 对于流式 object_string 消息,content 可能是 JSON 数组字符串,需要先解析
|
|
417570
|
+
let parsedContent;
|
|
417571
|
+
try {
|
|
417572
|
+
const trimmedContent = content.trim();
|
|
417573
|
+
// 尝试解析为 JSON 数组
|
|
417574
|
+
const parsed = JSON.parse(trimmedContent);
|
|
417575
|
+
if (Array.isArray(parsed)) {
|
|
417576
|
+
parsedContent = parsed;
|
|
417577
|
+
} else {
|
|
417578
|
+
// 如果不是数组,尝试作为单个对象解析
|
|
417579
|
+
parsedContent = [
|
|
417580
|
+
parsed
|
|
417581
|
+
];
|
|
417582
|
+
}
|
|
417583
|
+
} catch (e) {
|
|
417584
|
+
// 解析失败,尝试使用 catchParse(可能是不完整的 JSON)
|
|
417585
|
+
parsedContent = catchParse(content);
|
|
417586
|
+
}
|
|
417587
|
+
if (!parsedContent) {
|
|
417212
417588
|
return;
|
|
417213
417589
|
}
|
|
417214
|
-
console.log('convertMixContent
|
|
417215
|
-
const itemList =
|
|
417590
|
+
console.log('convertMixContent parsedContent', parsedContent);
|
|
417591
|
+
const itemList = parsedContent === null || parsedContent === void 0 ? void 0 : parsedContent.map((item)=>{
|
|
417216
417592
|
switch(item.type){
|
|
417217
417593
|
case 'text':
|
|
417218
417594
|
{
|
|
@@ -417281,9 +417657,52 @@ class MessageConverseToCoze {
|
|
|
417281
417657
|
}
|
|
417282
417658
|
}
|
|
417283
417659
|
}).filter((item)=>!!item);
|
|
417660
|
+
// 合并所有 JSON item 为一个 item
|
|
417661
|
+
// 如果 item_list 中有多个 JSON item,将它们合并为一个 JSON item
|
|
417662
|
+
const jsonItems = itemList.filter((item)=>item.type === types_ContentType.Json);
|
|
417663
|
+
const nonJsonItems = itemList.filter((item)=>item.type !== types_ContentType.Json);
|
|
417664
|
+
let mergedJsonItem;
|
|
417665
|
+
if (jsonItems.length > 0) {
|
|
417666
|
+
// 如果只有一个 JSON item,直接使用它
|
|
417667
|
+
if (jsonItems.length === 1) {
|
|
417668
|
+
mergedJsonItem = jsonItems[0];
|
|
417669
|
+
} else {
|
|
417670
|
+
// 如果有多个 JSON item,合并它们的 json 字段
|
|
417671
|
+
// 如果所有 json 字段都是对象,深度合并它们;否则合并为数组
|
|
417672
|
+
const jsonValues = jsonItems.map((item)=>item.json);
|
|
417673
|
+
const allAreObjects = jsonValues.every((json)=>typeof json === 'object' && json !== null && !Array.isArray(json));
|
|
417674
|
+
let mergedJson;
|
|
417675
|
+
if (allAreObjects) {
|
|
417676
|
+
// 深度合并所有对象
|
|
417677
|
+
mergedJson = jsonValues.reduce((acc, curr)=>{
|
|
417678
|
+
if (typeof acc === 'object' && acc !== null && !Array.isArray(acc) && typeof curr === 'object' && curr !== null && !Array.isArray(curr)) {
|
|
417679
|
+
return this.mergeJsonObjects(acc, curr);
|
|
417680
|
+
}
|
|
417681
|
+
return curr;
|
|
417682
|
+
}, jsonValues[0]);
|
|
417683
|
+
} else {
|
|
417684
|
+
// 如果有一个不是对象,合并为数组
|
|
417685
|
+
mergedJson = jsonValues.length === 1 ? jsonValues[0] : jsonValues;
|
|
417686
|
+
}
|
|
417687
|
+
// 使用第一个 JSON item 的 schema_version
|
|
417688
|
+
const schemaVersion = jsonItems[0].schema_version;
|
|
417689
|
+
mergedJsonItem = {
|
|
417690
|
+
type: types_ContentType.Json,
|
|
417691
|
+
json: mergedJson,
|
|
417692
|
+
schema_version: schemaVersion
|
|
417693
|
+
};
|
|
417694
|
+
}
|
|
417695
|
+
}
|
|
417696
|
+
// 合并所有 item:非 JSON item + 合并后的 JSON item
|
|
417697
|
+
const finalItemList = [
|
|
417698
|
+
...nonJsonItems
|
|
417699
|
+
];
|
|
417700
|
+
if (mergedJsonItem) {
|
|
417701
|
+
finalItemList.push(mergedJsonItem);
|
|
417702
|
+
}
|
|
417284
417703
|
const contentResult = {
|
|
417285
|
-
item_list:
|
|
417286
|
-
refer_items:
|
|
417704
|
+
item_list: finalItemList.filter((item)=>!item.is_refer),
|
|
417705
|
+
refer_items: finalItemList.filter((item)=>item.is_refer)
|
|
417287
417706
|
};
|
|
417288
417707
|
return JSON.stringify(contentResult);
|
|
417289
417708
|
}
|
|
@@ -417551,11 +417970,19 @@ const useRequestInit = ()=>{
|
|
|
417551
417970
|
const updateShortcuts = context_useChatAppStore((s)=>s.updateShortcuts);
|
|
417552
417971
|
const setIsStartBotVoiceCall = context_useChatAppStore((s)=>s.setIsStartBotVoiceCall);
|
|
417553
417972
|
const updateBackgroundInfo = context_useChatAppStore((s)=>s.updateBackgroundInfo);
|
|
417554
|
-
const {
|
|
417555
|
-
|
|
417556
|
-
updateCurrentConversationInfo: s.updateCurrentConversationInfo,
|
|
417557
|
-
conversations: s.conversations
|
|
417973
|
+
const { updateCurrentConversationInfo } = context_useChatAppStore(shallow_useShallow((s)=>({
|
|
417974
|
+
updateCurrentConversationInfo: s.updateCurrentConversationInfo
|
|
417558
417975
|
})));
|
|
417976
|
+
// 使用 ref 来存储最新的 currentConversationInfo 和 conversations
|
|
417977
|
+
// 这样可以避免将它们放在依赖数组中,从而避免 title/name 更新时触发重新初始化
|
|
417978
|
+
const currentConversationInfoRef = (0,react.useRef)();
|
|
417979
|
+
const conversationsRef = (0,react.useRef)([]);
|
|
417980
|
+
// 通过 hook 获取值并更新 ref
|
|
417981
|
+
context_useChatAppStore(shallow_useShallow((s)=>{
|
|
417982
|
+
currentConversationInfoRef.current = s.currentConversationInfo;
|
|
417983
|
+
conversationsRef.current = s.conversations;
|
|
417984
|
+
return null; // 不返回任何值,只用于同步 ref
|
|
417985
|
+
}));
|
|
417559
417986
|
const getMessageListByPairs = useGetMessageListByPairs();
|
|
417560
417987
|
const connectorId = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth = chatConfig.auth) === null || _chatConfig_auth === void 0 ? void 0 : _chatConfig_auth.connectorId) || '';
|
|
417561
417988
|
const { bot_id: botId = '', type: chatType, appInfo } = chatConfig;
|
|
@@ -417603,6 +418030,9 @@ const useRequestInit = ()=>{
|
|
|
417603
418030
|
const actualSectionId = requestDataConversationInfo.lastSectionId || '';
|
|
417604
418031
|
// 如果从 openRequestInit 返回了 conversationName,使用它
|
|
417605
418032
|
const actualConversationName = conversationName || '';
|
|
418033
|
+
// 从 ref 中获取最新的 currentConversationInfo 和 conversations
|
|
418034
|
+
const currentConversationInfo = currentConversationInfoRef.current;
|
|
418035
|
+
const conversations = conversationsRef.current;
|
|
417606
418036
|
if (actualConversationId) {
|
|
417607
418037
|
// 检查 currentConversationInfo 是否与实际的 conversationId 一致
|
|
417608
418038
|
// 如果 currentConversationInfo.id 为空字符串,说明是从空会话创建的,此时不应该更新
|
|
@@ -417650,14 +418080,21 @@ const useRequestInit = ()=>{
|
|
|
417650
418080
|
});
|
|
417651
418081
|
}
|
|
417652
418082
|
} else {
|
|
417653
|
-
// 如果 conversationId
|
|
418083
|
+
// 如果 conversationId 一致,只更新 sectionId(如果有变化)
|
|
418084
|
+
// 不更新 name,因为 name 会通过 conversation.update 事件自动更新
|
|
418085
|
+
// 这样可以避免 title/name 更新时触发重新初始化
|
|
417654
418086
|
const updates = {};
|
|
417655
418087
|
if (currentConversationInfo.last_section_id !== actualSectionId && actualSectionId) {
|
|
417656
418088
|
updates.last_section_id = actualSectionId;
|
|
417657
418089
|
}
|
|
417658
|
-
|
|
417659
|
-
|
|
417660
|
-
|
|
418090
|
+
// 移除 name 的更新,因为 name 会通过 conversation.update 事件自动更新
|
|
418091
|
+
// 这样可以避免 title/name 更新时触发重新初始化
|
|
418092
|
+
// if (
|
|
418093
|
+
// actualConversationName &&
|
|
418094
|
+
// currentConversationInfo.name !== actualConversationName
|
|
418095
|
+
// ) {
|
|
418096
|
+
// updates.name = actualConversationName;
|
|
418097
|
+
// }
|
|
417661
418098
|
if (Object.keys(updates).length > 0) {
|
|
417662
418099
|
updateCurrentConversationInfo({
|
|
417663
418100
|
...currentConversationInfo,
|
|
@@ -417711,8 +418148,8 @@ const useRequestInit = ()=>{
|
|
|
417711
418148
|
onDefaultHistoryClear,
|
|
417712
418149
|
chatType,
|
|
417713
418150
|
appInfo,
|
|
417714
|
-
currentConversationInfo
|
|
417715
|
-
|
|
418151
|
+
// 不再依赖 currentConversationInfo 和 conversations
|
|
418152
|
+
// 在函数内部通过 getState() 获取最新值,避免 title/name 更新时触发重新初始化
|
|
417716
418153
|
updateCurrentConversationInfo,
|
|
417717
418154
|
userInfo,
|
|
417718
418155
|
openRequestInit
|
|
@@ -418056,7 +418493,27 @@ class MessageConverterToSdk {
|
|
|
418056
418493
|
const contentType = messageBody.content_type;
|
|
418057
418494
|
const content = messageBody.query;
|
|
418058
418495
|
const shortcutCommand = messageBody.shortcut_command;
|
|
418059
|
-
|
|
418496
|
+
// API 要求 parameters 是 string 类型,如果传入的是对象,需要转换为 JSON 字符串
|
|
418497
|
+
// 如果 parameters 是对象,需要递归序列化所有嵌套对象(包括 SETTING 等字段)
|
|
418498
|
+
let parametersString;
|
|
418499
|
+
if (parameters) {
|
|
418500
|
+
if (typeof parameters === 'string') {
|
|
418501
|
+
// 如果已经是字符串,尝试解析并重新序列化,确保内部对象(如 SETTING)也被序列化
|
|
418502
|
+
try {
|
|
418503
|
+
const parsed = JSON.parse(parameters);
|
|
418504
|
+
parametersString = JSON.stringify(parsed);
|
|
418505
|
+
} catch {
|
|
418506
|
+
// 如果解析失败,说明不是有效的 JSON 字符串,直接使用原值
|
|
418507
|
+
parametersString = parameters;
|
|
418508
|
+
}
|
|
418509
|
+
} else if (typeof parameters === 'object') {
|
|
418510
|
+
// 如果是对象,直接序列化(JSON.stringify 会递归序列化所有嵌套对象)
|
|
418511
|
+
parametersString = JSON.stringify(parameters);
|
|
418512
|
+
} else {
|
|
418513
|
+
parametersString = String(parameters);
|
|
418514
|
+
}
|
|
418515
|
+
}
|
|
418516
|
+
const requestBody = {
|
|
418060
418517
|
bot_id: messageBody.bot_id,
|
|
418061
418518
|
user_id: userInfo === null || userInfo === void 0 ? void 0 : userInfo.id,
|
|
418062
418519
|
stream: true,
|
|
@@ -418064,10 +418521,11 @@ class MessageConverterToSdk {
|
|
|
418064
418521
|
additional_messages: [
|
|
418065
418522
|
this.convertRequestMessage(contentType, content)
|
|
418066
418523
|
],
|
|
418067
|
-
parameters,
|
|
418524
|
+
parameters: parametersString,
|
|
418068
418525
|
shortcut_command: this.convertShortcuts(shortcuts || [], shortcutCommand),
|
|
418069
418526
|
enable_card: true
|
|
418070
|
-
}
|
|
418527
|
+
};
|
|
418528
|
+
return JSON.stringify(requestBody);
|
|
418071
418529
|
}
|
|
418072
418530
|
// 替换 chat请求中的 message部分
|
|
418073
418531
|
convertRequestMessage(contentType, content) {
|
|
@@ -419730,7 +420188,7 @@ const src_timeoutPromise = (ms)=>new Promise((resolve)=>{
|
|
|
419730
420188
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
419731
420189
|
* See the License for the specific language governing permissions and
|
|
419732
420190
|
* limitations under the License.
|
|
419733
|
-
*/ function message_parser_define_property(obj, key, value) {
|
|
420191
|
+
*/ /* eslint-disable max-lines */ function message_parser_define_property(obj, key, value) {
|
|
419734
420192
|
if (key in obj) {
|
|
419735
420193
|
Object.defineProperty(obj, key, {
|
|
419736
420194
|
value: value,
|
|
@@ -419752,6 +420210,7 @@ const src_timeoutPromise = (ms)=>new Promise((resolve)=>{
|
|
|
419752
420210
|
|
|
419753
420211
|
|
|
419754
420212
|
|
|
420213
|
+
|
|
419755
420214
|
// 消息解析,主要用于从服务端获取到消息后,解析成coze能适配的数据结构
|
|
419756
420215
|
var message_parser_ChunkEvent = /*#__PURE__*/ (/* unused pure expression or super */ null && (function(ChunkEvent) {
|
|
419757
420216
|
ChunkEvent["ERROR"] = "error";
|
|
@@ -419776,7 +420235,8 @@ class MessageParser {
|
|
|
419776
420235
|
}
|
|
419777
420236
|
case "conversation.message.delta":
|
|
419778
420237
|
{
|
|
419779
|
-
|
|
420238
|
+
// conversation.message.delta 不应该累积和合并,应该直接使用新内容
|
|
420239
|
+
const message = this.createMessage(data, false, false);
|
|
419780
420240
|
if (!message) {
|
|
419781
420241
|
return;
|
|
419782
420242
|
}
|
|
@@ -419784,7 +420244,8 @@ class MessageParser {
|
|
|
419784
420244
|
}
|
|
419785
420245
|
case "conversation.message.completed":
|
|
419786
420246
|
{
|
|
419787
|
-
|
|
420247
|
+
// conversation.message.completed 不应该累积和合并,应该直接使用新内容
|
|
420248
|
+
const messageResult = this.createMessage(data, true, false);
|
|
419788
420249
|
// 清理流式 JSON 累积内容
|
|
419789
420250
|
if (messageResult && typeof messageResult === 'object' && 'data' in messageResult) {
|
|
419790
420251
|
const messageData = messageResult.data;
|
|
@@ -419795,6 +420256,8 @@ class MessageParser {
|
|
|
419795
420256
|
if (contentKey) {
|
|
419796
420257
|
this.streamingJsonContent.delete(contentKey);
|
|
419797
420258
|
this.lastValidJsonContent.delete(contentKey);
|
|
420259
|
+
this.lastReturnedParsedContent.delete(contentKey);
|
|
420260
|
+
this.lastReturnedAccumulatedContent.delete(contentKey);
|
|
419798
420261
|
}
|
|
419799
420262
|
}
|
|
419800
420263
|
}
|
|
@@ -419841,7 +420304,7 @@ class MessageParser {
|
|
|
419841
420304
|
}
|
|
419842
420305
|
}
|
|
419843
420306
|
createMessage(data) {
|
|
419844
|
-
let isComplete = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
|
|
420307
|
+
let isComplete = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false, shouldAccumulate = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : true;
|
|
419845
420308
|
const dataValue = catchParse(data);
|
|
419846
420309
|
if (!dataValue) {
|
|
419847
420310
|
return;
|
|
@@ -419852,31 +420315,124 @@ class MessageParser {
|
|
|
419852
420315
|
// 处理流式 JSON:当 content_type 是 object_string 且 type 是 answer 时
|
|
419853
420316
|
const isStreamingJson = dataValue.content_type === 'object_string' && dataValue.type === 'answer';
|
|
419854
420317
|
if (isStreamingJson && dataValue.content) {
|
|
419855
|
-
//
|
|
419856
|
-
|
|
420318
|
+
// 对于流式 object_string 消息,使用 id 作为 key 来累积内容
|
|
420319
|
+
// 这样可以确保不同 id 的消息不会被合并
|
|
420320
|
+
// 但是,只有 shouldAccumulate 为 true 时才累积(conversation.chat.* 事件)
|
|
420321
|
+
// conversation.message.delta 不应该累积,应该直接使用新内容
|
|
420322
|
+
const contentKey = dataValue.id || '';
|
|
419857
420323
|
if (contentKey) {
|
|
419858
|
-
|
|
419859
|
-
|
|
419860
|
-
|
|
419861
|
-
|
|
419862
|
-
|
|
419863
|
-
|
|
419864
|
-
if (parsedContent !== null) {
|
|
419865
|
-
// 如果解析成功,使用解析后的内容,并保存为最后一次有效内容
|
|
419866
|
-
dataValue.content = parsedContent;
|
|
419867
|
-
this.lastValidJsonContent.set(contentKey, parsedContent);
|
|
420324
|
+
let newContent;
|
|
420325
|
+
if (shouldAccumulate) {
|
|
420326
|
+
// 累积流式 JSON 内容(conversation.chat.* 事件)
|
|
420327
|
+
const accumulatedContent = this.streamingJsonContent.get(contentKey) || '';
|
|
420328
|
+
newContent = accumulatedContent + dataValue.content;
|
|
420329
|
+
this.streamingJsonContent.set(contentKey, newContent);
|
|
419868
420330
|
} else {
|
|
419869
|
-
//
|
|
419870
|
-
|
|
419871
|
-
|
|
419872
|
-
|
|
419873
|
-
|
|
419874
|
-
|
|
419875
|
-
|
|
419876
|
-
|
|
419877
|
-
|
|
419878
|
-
|
|
420331
|
+
// 不累积,直接使用新内容(conversation.message.delta 事件)
|
|
420332
|
+
newContent = dataValue.content;
|
|
420333
|
+
}
|
|
420334
|
+
// 对于流式数组,我们需要传递完整的累积内容,而不是部分解析的内容
|
|
420335
|
+
// 检查数组是否完整(以 ] 结尾)
|
|
420336
|
+
const trimmedContent = newContent.trim();
|
|
420337
|
+
const isArrayComplete = trimmedContent.startsWith('[') && trimmedContent.endsWith(']');
|
|
420338
|
+
if (isArrayComplete) {
|
|
420339
|
+
// 数组完整,尝试解析完整的数组
|
|
420340
|
+
try {
|
|
420341
|
+
const parsed = JSON.parse(trimmedContent);
|
|
420342
|
+
if (Array.isArray(parsed)) {
|
|
420343
|
+
// 解析成功
|
|
420344
|
+
// 如果是 completed 消息,直接使用新的内容,不合并
|
|
420345
|
+
// 如果是 delta 消息,合并数组中元素的 json 字段
|
|
420346
|
+
let mergedArray = parsed;
|
|
420347
|
+
if (!isComplete && shouldAccumulate) {
|
|
420348
|
+
// 只对 delta 消息且 shouldAccumulate 为 true 时进行合并
|
|
420349
|
+
// 获取上一次解析的内容
|
|
420350
|
+
const lastValidContent = this.lastValidJsonContent.get(contentKey);
|
|
420351
|
+
if (lastValidContent) {
|
|
420352
|
+
try {
|
|
420353
|
+
const lastParsed = JSON.parse(lastValidContent);
|
|
420354
|
+
if (Array.isArray(lastParsed) && lastParsed.length > 0 && parsed.length > 0) {
|
|
420355
|
+
// 合并第一个元素的 json 字段
|
|
420356
|
+
const lastFirstItem = lastParsed[0];
|
|
420357
|
+
const currFirstItem = parsed[0];
|
|
420358
|
+
if (typeof lastFirstItem === 'object' && lastFirstItem !== null && typeof currFirstItem === 'object' && currFirstItem !== null && 'json' in lastFirstItem && 'json' in currFirstItem && typeof lastFirstItem.json === 'object' && lastFirstItem.json !== null && typeof currFirstItem.json === 'object' && currFirstItem.json !== null) {
|
|
420359
|
+
// 合并 json 字段(深度合并对象)
|
|
420360
|
+
const mergedJson = this.mergeJsonObjects(lastFirstItem.json, currFirstItem.json);
|
|
420361
|
+
// 创建合并后的第一个元素
|
|
420362
|
+
mergedArray = [
|
|
420363
|
+
{
|
|
420364
|
+
...currFirstItem,
|
|
420365
|
+
json: mergedJson
|
|
420366
|
+
},
|
|
420367
|
+
...parsed.slice(1)
|
|
420368
|
+
];
|
|
420369
|
+
}
|
|
420370
|
+
}
|
|
420371
|
+
} catch (parseError) {
|
|
420372
|
+
// 解析上一次内容失败,使用当前解析的内容
|
|
420373
|
+
// Error is intentionally ignored as we fallback to current parsed content
|
|
420374
|
+
void parseError;
|
|
420375
|
+
}
|
|
420376
|
+
}
|
|
420377
|
+
} else {
|
|
420378
|
+
// completed 消息:直接使用新的内容,不合并
|
|
420379
|
+
}
|
|
420380
|
+
const parsedContent = JSON.stringify(mergedArray);
|
|
420381
|
+
dataValue.content = parsedContent;
|
|
420382
|
+
this.lastValidJsonContent.set(contentKey, parsedContent);
|
|
420383
|
+
} else {
|
|
420384
|
+
// 不是数组,使用原始内容
|
|
420385
|
+
dataValue.content = newContent;
|
|
420386
|
+
}
|
|
420387
|
+
} catch (e) {
|
|
420388
|
+
// 解析失败,可能是多个数组拼接(如 [{...}][{...}]),尝试合并
|
|
420389
|
+
const mergedArray = this.mergeStreamingArrays(trimmedContent);
|
|
420390
|
+
if (mergedArray !== null) {
|
|
420391
|
+
// 如果是 completed 消息,直接使用新的内容,不合并
|
|
420392
|
+
// 如果是 delta 消息,合并数组中元素的 json 字段
|
|
420393
|
+
let finalMergedArray = mergedArray;
|
|
420394
|
+
if (!isComplete && shouldAccumulate) {
|
|
420395
|
+
// 只对 delta 消息且 shouldAccumulate 为 true 时进行合并
|
|
420396
|
+
const lastValidContent = this.lastValidJsonContent.get(contentKey);
|
|
420397
|
+
if (lastValidContent) {
|
|
420398
|
+
try {
|
|
420399
|
+
const lastParsed = JSON.parse(lastValidContent);
|
|
420400
|
+
if (Array.isArray(lastParsed) && lastParsed.length > 0 && mergedArray.length > 0) {
|
|
420401
|
+
// 合并第一个元素的 json 字段
|
|
420402
|
+
const lastFirstItem = lastParsed[0];
|
|
420403
|
+
const currFirstItem = mergedArray[0];
|
|
420404
|
+
if (typeof lastFirstItem === 'object' && lastFirstItem !== null && typeof currFirstItem === 'object' && currFirstItem !== null && 'json' in lastFirstItem && 'json' in currFirstItem && typeof lastFirstItem.json === 'object' && lastFirstItem.json !== null && typeof currFirstItem.json === 'object' && currFirstItem.json !== null) {
|
|
420405
|
+
// 合并 json 字段(深度合并对象)
|
|
420406
|
+
const mergedJson = this.mergeJsonObjects(lastFirstItem.json, currFirstItem.json);
|
|
420407
|
+
// 创建合并后的第一个元素
|
|
420408
|
+
finalMergedArray = [
|
|
420409
|
+
{
|
|
420410
|
+
...currFirstItem,
|
|
420411
|
+
json: mergedJson
|
|
420412
|
+
},
|
|
420413
|
+
...mergedArray.slice(1)
|
|
420414
|
+
];
|
|
420415
|
+
}
|
|
420416
|
+
}
|
|
420417
|
+
} catch (parseError) {
|
|
420418
|
+
// 解析上一次内容失败,使用当前合并的数组
|
|
420419
|
+
// Error is intentionally ignored as we fallback to current merged array
|
|
420420
|
+
void parseError;
|
|
420421
|
+
}
|
|
420422
|
+
}
|
|
420423
|
+
}
|
|
420424
|
+
const parsedContent = JSON.stringify(finalMergedArray);
|
|
420425
|
+
dataValue.content = parsedContent;
|
|
420426
|
+
this.lastValidJsonContent.set(contentKey, parsedContent);
|
|
420427
|
+
} else {
|
|
420428
|
+
// 合并失败,使用原始内容
|
|
420429
|
+
dataValue.content = newContent;
|
|
420430
|
+
}
|
|
419879
420431
|
}
|
|
420432
|
+
} else {
|
|
420433
|
+
// 数组不完整,使用累积的原始内容
|
|
420434
|
+
// convertMixContent 会尝试解析部分数组,如果失败会返回 undefined
|
|
420435
|
+
dataValue.content = newContent;
|
|
419880
420436
|
}
|
|
419881
420437
|
}
|
|
419882
420438
|
}
|
|
@@ -419887,7 +420443,8 @@ class MessageParser {
|
|
|
419887
420443
|
// 对于流式 JSON,如果 convertMixContent 返回 undefined(JSON 不完整),
|
|
419888
420444
|
// 且没有上一次成功解析的内容,不返回消息,避免重复渲染
|
|
419889
420445
|
if (isStreamingJson && !isComplete && message.content_type === types_ContentType.Mix && (!message.content || message.content === 'undefined')) {
|
|
419890
|
-
|
|
420446
|
+
// 对于流式 object_string 消息,使用 id 作为 key
|
|
420447
|
+
const contentKey = dataValue.id || '';
|
|
419891
420448
|
const lastValidContent = contentKey ? this.lastValidJsonContent.get(contentKey) : undefined;
|
|
419892
420449
|
// 如果没有上一次成功解析的内容,不返回消息
|
|
419893
420450
|
if (!lastValidContent) {
|
|
@@ -419896,15 +420453,30 @@ class MessageParser {
|
|
|
419896
420453
|
// 如果有上一次成功解析的内容,使用它
|
|
419897
420454
|
message.content = lastValidContent;
|
|
419898
420455
|
}
|
|
420456
|
+
// 对于流式 object_string 消息,检查内容是否真正变化
|
|
420457
|
+
// 如果内容没有变化,且不是完成消息,则不返回消息,避免重复渲染
|
|
420458
|
+
if (isStreamingJson && !isComplete && message.message_id) {
|
|
420459
|
+
// 对于流式 object_string 消息,使用 id 作为 key
|
|
420460
|
+
const contentKey = dataValue.id || '';
|
|
420461
|
+
if (contentKey) {
|
|
420462
|
+
// 比较转换后的 message.content(这是最终传递给 UI 的内容)
|
|
420463
|
+
const currentMessageContent = message.content || '';
|
|
420464
|
+
const lastReturnedMessageContent = this.lastReturnedParsedContent.get(contentKey) || '';
|
|
420465
|
+
// 如果转换后的内容没有变化,不返回消息
|
|
420466
|
+
if (currentMessageContent && lastReturnedMessageContent && currentMessageContent === lastReturnedMessageContent) {
|
|
420467
|
+
// 内容没有变化,不返回消息
|
|
420468
|
+
return;
|
|
420469
|
+
}
|
|
420470
|
+
// 更新上一次返回的转换后的内容
|
|
420471
|
+
if (currentMessageContent) {
|
|
420472
|
+
this.lastReturnedParsedContent.set(contentKey, currentMessageContent);
|
|
420473
|
+
}
|
|
420474
|
+
}
|
|
420475
|
+
}
|
|
419899
420476
|
if (isComplete && message.content_type === types_ContentType.Text && message.type === 'answer') {
|
|
419900
420477
|
message.content = '';
|
|
419901
|
-
} else if (isComplete && message.content_type === types_ContentType.Mix && message.type === 'answer') {
|
|
419902
|
-
message.content = JSON.stringify({
|
|
419903
|
-
item_list: []
|
|
419904
|
-
});
|
|
419905
420478
|
}
|
|
419906
420479
|
message.section_id = message.section_id || this.sectionId;
|
|
419907
|
-
console.log('createMessage message', message);
|
|
419908
420480
|
return {
|
|
419909
420481
|
event: 'message',
|
|
419910
420482
|
data: {
|
|
@@ -419920,6 +420492,127 @@ class MessageParser {
|
|
|
419920
420492
|
};
|
|
419921
420493
|
}
|
|
419922
420494
|
/**
|
|
420495
|
+
* 合并两个 JSON 对象(深度合并)
|
|
420496
|
+
* - 如果两个值都是对象,递归合并
|
|
420497
|
+
* - 如果两个值都是字符串,追加字符串
|
|
420498
|
+
* - 如果两个值都是数组,合并数组(按索引合并)
|
|
420499
|
+
* - 否则使用 curr 的值(覆盖)
|
|
420500
|
+
*/ mergeJsonObjects(prev, curr) {
|
|
420501
|
+
const merged = {
|
|
420502
|
+
...prev
|
|
420503
|
+
};
|
|
420504
|
+
for(const key in curr){
|
|
420505
|
+
if (Object.prototype.hasOwnProperty.call(curr, key)) {
|
|
420506
|
+
const prevValue = prev[key];
|
|
420507
|
+
const currValue = curr[key];
|
|
420508
|
+
// 如果两个值都是对象,递归合并
|
|
420509
|
+
if (typeof prevValue === 'object' && prevValue !== null && !Array.isArray(prevValue) && typeof currValue === 'object' && currValue !== null && !Array.isArray(currValue)) {
|
|
420510
|
+
merged[key] = this.mergeJsonObjects(prevValue, currValue);
|
|
420511
|
+
} else if (typeof prevValue === 'string' && typeof currValue === 'string') {
|
|
420512
|
+
// 如果两个值都是字符串,追加字符串
|
|
420513
|
+
merged[key] = prevValue + currValue;
|
|
420514
|
+
} else if (Array.isArray(prevValue) && Array.isArray(currValue)) {
|
|
420515
|
+
// 如果两个值都是数组,按索引合并
|
|
420516
|
+
const mergedArray = [
|
|
420517
|
+
...prevValue
|
|
420518
|
+
];
|
|
420519
|
+
for(let i = 0; i < currValue.length; i++){
|
|
420520
|
+
const currItem = currValue[i];
|
|
420521
|
+
if (i < mergedArray.length) {
|
|
420522
|
+
// 如果索引已存在,尝试合并
|
|
420523
|
+
const prevItem = mergedArray[i];
|
|
420524
|
+
if (typeof prevItem === 'object' && prevItem !== null && !Array.isArray(prevItem) && typeof currItem === 'object' && currItem !== null && !Array.isArray(currItem)) {
|
|
420525
|
+
mergedArray[i] = this.mergeJsonObjects(prevItem, currItem);
|
|
420526
|
+
} else {
|
|
420527
|
+
mergedArray[i] = currItem;
|
|
420528
|
+
}
|
|
420529
|
+
} else {
|
|
420530
|
+
// 如果索引超出范围,追加新元素
|
|
420531
|
+
mergedArray.push(currItem);
|
|
420532
|
+
}
|
|
420533
|
+
}
|
|
420534
|
+
merged[key] = mergedArray;
|
|
420535
|
+
} else {
|
|
420536
|
+
// 否则使用 curr 的值(覆盖)
|
|
420537
|
+
merged[key] = currValue;
|
|
420538
|
+
}
|
|
420539
|
+
}
|
|
420540
|
+
}
|
|
420541
|
+
return merged;
|
|
420542
|
+
}
|
|
420543
|
+
/**
|
|
420544
|
+
* 合并多个流式数组(如 [{...}][{...}] 合并为 [{...},{...}])
|
|
420545
|
+
* 返回合并后的数组,如果无法合并则返回 null
|
|
420546
|
+
*/ mergeStreamingArrays(content) {
|
|
420547
|
+
if (!content || !content.trim().startsWith('[')) {
|
|
420548
|
+
return null;
|
|
420549
|
+
}
|
|
420550
|
+
const trimmed = content.trim();
|
|
420551
|
+
const arrays = [];
|
|
420552
|
+
let currentIndex = 0;
|
|
420553
|
+
while(currentIndex < trimmed.length){
|
|
420554
|
+
// 跳过空白字符
|
|
420555
|
+
while(currentIndex < trimmed.length && /\s/.test(trimmed[currentIndex])){
|
|
420556
|
+
currentIndex++;
|
|
420557
|
+
}
|
|
420558
|
+
if (currentIndex >= trimmed.length || trimmed[currentIndex] !== '[') {
|
|
420559
|
+
break;
|
|
420560
|
+
}
|
|
420561
|
+
// 找到完整的数组
|
|
420562
|
+
let bracketCount = 0;
|
|
420563
|
+
let inString = false;
|
|
420564
|
+
let escapeNext = false;
|
|
420565
|
+
let arrayEndIndex = -1;
|
|
420566
|
+
for(let i = currentIndex; i < trimmed.length; i++){
|
|
420567
|
+
const char = trimmed[i];
|
|
420568
|
+
if (escapeNext) {
|
|
420569
|
+
escapeNext = false;
|
|
420570
|
+
continue;
|
|
420571
|
+
}
|
|
420572
|
+
if (char === '\\') {
|
|
420573
|
+
escapeNext = true;
|
|
420574
|
+
continue;
|
|
420575
|
+
}
|
|
420576
|
+
if (char === '"') {
|
|
420577
|
+
inString = !inString;
|
|
420578
|
+
continue;
|
|
420579
|
+
}
|
|
420580
|
+
if (inString) {
|
|
420581
|
+
continue;
|
|
420582
|
+
}
|
|
420583
|
+
if (char === '[') {
|
|
420584
|
+
bracketCount++;
|
|
420585
|
+
} else if (char === ']') {
|
|
420586
|
+
bracketCount--;
|
|
420587
|
+
if (bracketCount === 0) {
|
|
420588
|
+
arrayEndIndex = i;
|
|
420589
|
+
break;
|
|
420590
|
+
}
|
|
420591
|
+
}
|
|
420592
|
+
}
|
|
420593
|
+
if (arrayEndIndex > currentIndex) {
|
|
420594
|
+
try {
|
|
420595
|
+
const arrayStr = trimmed.substring(currentIndex, arrayEndIndex + 1);
|
|
420596
|
+
const parsed = JSON.parse(arrayStr);
|
|
420597
|
+
if (Array.isArray(parsed)) {
|
|
420598
|
+
arrays.push(...parsed);
|
|
420599
|
+
} else {
|
|
420600
|
+
arrays.push(parsed);
|
|
420601
|
+
}
|
|
420602
|
+
currentIndex = arrayEndIndex + 1;
|
|
420603
|
+
} catch (parseError) {
|
|
420604
|
+
// 解析失败,停止合并
|
|
420605
|
+
// Error is intentionally ignored as we break the loop
|
|
420606
|
+
void parseError;
|
|
420607
|
+
break;
|
|
420608
|
+
}
|
|
420609
|
+
} else {
|
|
420610
|
+
break;
|
|
420611
|
+
}
|
|
420612
|
+
}
|
|
420613
|
+
return arrays.length > 0 ? arrays : null;
|
|
420614
|
+
}
|
|
420615
|
+
/**
|
|
419923
420616
|
* 尝试解析流式 JSON 内容
|
|
419924
420617
|
* 如果 JSON 不完整,返回 null;如果解析成功,返回完整的 JSON 字符串
|
|
419925
420618
|
*/ tryParseStreamingJson(content) {
|
|
@@ -420133,6 +420826,10 @@ class MessageParser {
|
|
|
420133
420826
|
message_parser_define_property(this, "streamingJsonContent", new Map());
|
|
420134
420827
|
// 用于存储上一次成功解析的完整 JSON 内容,避免重复渲染
|
|
420135
420828
|
message_parser_define_property(this, "lastValidJsonContent", new Map());
|
|
420829
|
+
// 用于存储上一次返回的解析后的 JSON 内容,用于检测内容是否真正变化
|
|
420830
|
+
message_parser_define_property(this, "lastReturnedParsedContent", new Map());
|
|
420831
|
+
// 用于存储上一次返回的原始累积内容,用于检测 JSON 不完整时内容是否变化
|
|
420832
|
+
message_parser_define_property(this, "lastReturnedAccumulatedContent", new Map());
|
|
420136
420833
|
this.conversationId = requestMessageRawBody.conversation_id;
|
|
420137
420834
|
this.localMessageId = requestMessageRawBody.local_message_id;
|
|
420138
420835
|
this.sendMessageContent = requestMessageRawBody.query;
|
|
@@ -420217,6 +420914,7 @@ class MessageParser {
|
|
|
420217
420914
|
const updateCurrentConversationInfoFn = refUpdateCurrentConversationInfo.current;
|
|
420218
420915
|
const { title } = updates;
|
|
420219
420916
|
if (title !== undefined) {
|
|
420917
|
+
var _refPendingConversationInfo_current;
|
|
420220
420918
|
// 更新会话列表中的会话名称
|
|
420221
420919
|
// 注意:PC 端和 Mobile 端都优先使用 title,如果没有 title 则使用 name
|
|
420222
420920
|
// 对于 App 模式,需要同时更新 name 和 title
|
|
@@ -420229,30 +420927,70 @@ class MessageParser {
|
|
|
420229
420927
|
title,
|
|
420230
420928
|
updated_at: Math.floor(updated_at / 1000)
|
|
420231
420929
|
};
|
|
420232
|
-
updateConversationsFn
|
|
420233
|
-
|
|
420234
|
-
|
|
420930
|
+
if (updateConversationsFn) {
|
|
420931
|
+
updateConversationsFn([
|
|
420932
|
+
updatedConversationObj
|
|
420933
|
+
], 'update');
|
|
420934
|
+
}
|
|
420235
420935
|
// 如果当前会话是被更新的会话,同时更新 currentConversationInfo
|
|
420236
420936
|
// 修复:无论ref是否是最新的,都更新currentConversationInfo,确保header能显示title
|
|
420237
420937
|
// updateCurrentConversationInfo函数会合并字段,所以即使ref不是最新的,title也会被正确设置
|
|
420238
420938
|
// 从conversations列表中查找对应的会话,如果找到说明这个会话存在,可能是当前会话
|
|
420239
420939
|
const conversationsList = refConversations.current;
|
|
420240
420940
|
const foundConversation = conversationsList.find((c)=>c.id === conversation_id);
|
|
420941
|
+
// 检查是否是当前会话或待处理的会话
|
|
420942
|
+
// 1. 如果 refCurrentConversationInfo.current.id 匹配,说明是当前会话
|
|
420943
|
+
// 2. 如果 refPendingConversationInfo.current.conversationId 匹配,说明是新创建的会话,但 currentConversationInfo 还没有更新
|
|
420944
|
+
const isCurrentConversation = (currentConversation === null || currentConversation === void 0 ? void 0 : currentConversation.id) === conversation_id;
|
|
420945
|
+
const isPendingConversation = ((_refPendingConversationInfo_current = refPendingConversationInfo.current) === null || _refPendingConversationInfo_current === void 0 ? void 0 : _refPendingConversationInfo_current.conversationId) === conversation_id;
|
|
420241
420946
|
// 如果ref中的id匹配,或者找到了对应的会话,就更新title
|
|
420242
420947
|
// 这样可以确保即使ref不是最新的,也能正确更新title
|
|
420243
|
-
|
|
420948
|
+
// 注意:只有当 conversation_id 与当前会话的 id 匹配时才更新 currentConversationInfo
|
|
420949
|
+
// 这样可以避免在更新其他会话的 title 时触发当前会话的重新初始化
|
|
420950
|
+
if (isCurrentConversation || isPendingConversation) {
|
|
420244
420951
|
// 优先使用ref中的currentConversationInfo,保留其所有字段
|
|
420245
|
-
//
|
|
420246
|
-
|
|
420247
|
-
|
|
420248
|
-
|
|
420249
|
-
|
|
420250
|
-
|
|
420251
|
-
|
|
420252
|
-
|
|
420253
|
-
|
|
420254
|
-
|
|
420255
|
-
|
|
420952
|
+
// 只更新 title 和 name,不改变其他字段,避免触发不必要的重新初始化
|
|
420953
|
+
if (currentConversation) {
|
|
420954
|
+
// 只有当 title 或 name 真的发生变化时才更新,避免创建不必要的对象引用
|
|
420955
|
+
if (currentConversation.title !== title || currentConversation.name !== title) {
|
|
420956
|
+
updateCurrentConversationInfoFn({
|
|
420957
|
+
...currentConversation,
|
|
420958
|
+
name: title,
|
|
420959
|
+
title,
|
|
420960
|
+
updated_at: Math.floor(updated_at / 1000)
|
|
420961
|
+
});
|
|
420962
|
+
}
|
|
420963
|
+
} else if (foundConversation) {
|
|
420964
|
+
// 如果 currentConversation 不存在但找到了会话,使用找到的会话信息
|
|
420965
|
+
// 注意:foundConversation 是 Conversation 类型,不包含 conversationListVisible 和 isLargeWidth
|
|
420966
|
+
// 这些字段只在 currentConversationInfo 中存在,所以使用默认值
|
|
420967
|
+
updateCurrentConversationInfoFn({
|
|
420968
|
+
...foundConversation,
|
|
420969
|
+
name: title,
|
|
420970
|
+
title,
|
|
420971
|
+
updated_at: Math.floor(updated_at / 1000),
|
|
420972
|
+
// 使用默认值,因为 foundConversation 不包含这些字段
|
|
420973
|
+
conversationListVisible: false,
|
|
420974
|
+
isLargeWidth: false
|
|
420975
|
+
});
|
|
420976
|
+
} else if (isPendingConversation && refPendingConversationInfo.current) {
|
|
420977
|
+
// 如果是待处理的会话,但 currentConversation 和 foundConversation 都不存在
|
|
420978
|
+
// 使用 refPendingConversationInfo 中的信息创建新的 currentConversationInfo
|
|
420979
|
+
const pendingInfo = refPendingConversationInfo.current;
|
|
420980
|
+
// 从 refCurrentConversationInfo 获取保留的字段(如果存在)
|
|
420981
|
+
const existingInfo = refCurrentConversationInfo.current;
|
|
420982
|
+
updateCurrentConversationInfoFn({
|
|
420983
|
+
id: pendingInfo.conversationId,
|
|
420984
|
+
last_section_id: pendingInfo.sectionId,
|
|
420985
|
+
name: title,
|
|
420986
|
+
title,
|
|
420987
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
420988
|
+
updated_at: Math.floor(updated_at / 1000),
|
|
420989
|
+
meta_data: {},
|
|
420990
|
+
conversationListVisible: (existingInfo === null || existingInfo === void 0 ? void 0 : existingInfo.conversationListVisible) ?? false,
|
|
420991
|
+
isLargeWidth: (existingInfo === null || existingInfo === void 0 ? void 0 : existingInfo.isLargeWidth) ?? false
|
|
420992
|
+
});
|
|
420993
|
+
}
|
|
420256
420994
|
}
|
|
420257
420995
|
}
|
|
420258
420996
|
};
|
|
@@ -420346,12 +421084,28 @@ class MessageParser {
|
|
|
420346
421084
|
conversationName: conversationResult.conversationName
|
|
420347
421085
|
});
|
|
420348
421086
|
}
|
|
420349
|
-
//
|
|
420350
|
-
//
|
|
420351
|
-
//
|
|
420352
|
-
//
|
|
421087
|
+
// 选中新创建的会话:先更新 currentConversationInfo,确保会话被选中
|
|
421088
|
+
// 不立即调用 updateCurrentConversationInfo,避免触发组件卸载
|
|
421089
|
+
// 将在消息流完成(DONE 事件)时更新 currentConversationInfo
|
|
421090
|
+
// 这样可以避免触发 useRequestInit 的依赖变化,防止重新初始化
|
|
421091
|
+
// 会话列表中的新会话已经通过 updateConversations 添加,可以正常显示
|
|
421092
|
+
console.log('onBeforeSendMessage: Conversation created, will update currentConversationInfo after stream completes', {
|
|
421093
|
+
conversationId: conversationResult.conversationId
|
|
421094
|
+
});
|
|
421095
|
+
// 确保 pendingInfo 被设置,以便在 DONE 事件时更新
|
|
421096
|
+
if (refPendingConversationInfo) {
|
|
421097
|
+
refPendingConversationInfo.current = {
|
|
421098
|
+
conversationId: conversationResult.conversationId,
|
|
421099
|
+
sectionId: conversationResult.sectionId || ''
|
|
421100
|
+
};
|
|
421101
|
+
}
|
|
421102
|
+
// 注意:不在这里调用 setConversationId,因为它会触发额外的 updateConversations 调用
|
|
421103
|
+
// 这会导致 useConversationList 的同步逻辑被触发,设置 isSyncing = true
|
|
421104
|
+
// 当真正的 store 更新发生时,isSyncing 仍然是 true,导致 useEffect 被跳过
|
|
421105
|
+
// setConversationId 会在消息流完成时被调用(在 onGetMessageStreamParser 的 DONE 事件中)
|
|
421106
|
+
// 更新 messageBody 中的 conversation_id
|
|
420353
421107
|
messageBody.conversation_id = conversationId;
|
|
420354
|
-
console.log('onBeforeSendMessage: Conversation created,
|
|
421108
|
+
console.log('onBeforeSendMessage: Conversation created and selected, ready to send message', {
|
|
420355
421109
|
conversationId,
|
|
420356
421110
|
pendingInfo: refPendingConversationInfo.current
|
|
420357
421111
|
});
|
|
@@ -420367,7 +421121,7 @@ class MessageParser {
|
|
|
420367
421121
|
throw new Error('conversationId is required for sending message');
|
|
420368
421122
|
}
|
|
420369
421123
|
// 使用计算后的 API URL
|
|
420370
|
-
const url = `${finalApiUrl}/
|
|
421124
|
+
const url = `${finalApiUrl}/v1/workflows/chat?conversation_id=${conversationId}`;
|
|
420371
421125
|
// 根据 chatType 选择正确的 parameters 来源
|
|
420372
421126
|
// App 模式使用 appInfo.parameters,Bot 模式使用 botInfo.parameters
|
|
420373
421127
|
const parameters = ((_refChatConfig_current = refChatConfig.current) === null || _refChatConfig_current === void 0 ? void 0 : _refChatConfig_current.type) === client_ChatType.APP ? (_refChatConfig_current_appInfo = refChatConfig.current.appInfo) === null || _refChatConfig_current_appInfo === void 0 ? void 0 : _refChatConfig_current_appInfo.parameters : (_refChatConfig_current_botInfo = refChatConfig.current.botInfo) === null || _refChatConfig_current_botInfo === void 0 ? void 0 : _refChatConfig_current_botInfo.parameters;
|
|
@@ -420512,6 +421266,8 @@ class MessageParser {
|
|
|
420512
421266
|
// 使用 setTimeout 确保在消息发送流程完全完成后更新状态
|
|
420513
421267
|
setTimeout(()=>{
|
|
420514
421268
|
if (refUpdateCurrentConversationInfo.current) {
|
|
421269
|
+
// 保留当前的 conversationListVisible 和 isLargeWidth,避免会话列表被收起
|
|
421270
|
+
const currentInfo = refCurrentConversationInfo.current;
|
|
420515
421271
|
refUpdateCurrentConversationInfo.current({
|
|
420516
421272
|
id: pendingInfo.conversationId,
|
|
420517
421273
|
last_section_id: pendingInfo.sectionId,
|
|
@@ -420520,8 +421276,10 @@ class MessageParser {
|
|
|
420520
421276
|
created_at: Math.floor(Date.now() / 1000),
|
|
420521
421277
|
updated_at: Math.floor(Date.now() / 1000),
|
|
420522
421278
|
meta_data: {},
|
|
420523
|
-
conversationListVisible
|
|
420524
|
-
|
|
421279
|
+
// 保留当前的 conversationListVisible,避免会话列表被收起
|
|
421280
|
+
conversationListVisible: (currentInfo === null || currentInfo === void 0 ? void 0 : currentInfo.conversationListVisible) ?? false,
|
|
421281
|
+
// 保留当前的 isLargeWidth
|
|
421282
|
+
isLargeWidth: (currentInfo === null || currentInfo === void 0 ? void 0 : currentInfo.isLargeWidth) ?? false
|
|
420525
421283
|
});
|
|
420526
421284
|
}
|
|
420527
421285
|
if (refChatFunc === null || refChatFunc === void 0 ? void 0 : refChatFunc.current) {
|
|
@@ -423643,36 +424401,89 @@ const ChatProviderFuncComp = /*#__PURE__*/ (0,react.forwardRef)((param, ref)=>{
|
|
|
423643
424401
|
// 监听 currentConversationInfo 的变化,同步更新 chat-area 的 conversationId 和 sectionId
|
|
423644
424402
|
// 这样当切换会话时,可以避免出现"上下文已清除"提示
|
|
423645
424403
|
// 注意:必须在消息加载之前更新 sectionId,否则会触发上下文分隔线
|
|
424404
|
+
// 使用 ref 来存储上一次的 id 和 last_section_id,避免 title/name 更新时触发重新初始化
|
|
424405
|
+
const prevConversationIdRef = (0,react.useRef)(undefined);
|
|
424406
|
+
const prevSectionIdRef = (0,react.useRef)(undefined);
|
|
424407
|
+
// 使用 useMemo 来稳定 id 和 last_section_id 的值,避免对象引用变化导致 useEffect 触发
|
|
424408
|
+
const stableConversationId = (0,react.useMemo)(()=>currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.id, [
|
|
424409
|
+
currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.id
|
|
424410
|
+
]);
|
|
424411
|
+
const stableLastSectionId = (0,react.useMemo)(()=>currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.last_section_id, [
|
|
424412
|
+
currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.last_section_id
|
|
424413
|
+
]);
|
|
424414
|
+
// 更新 sectionId 的辅助函数
|
|
424415
|
+
const updateSectionIdIfNeeded = useMemoizedFn((targetSectionId, currentSectionId)=>{
|
|
424416
|
+
if (targetSectionId && targetSectionId !== currentSectionId) {
|
|
424417
|
+
const { setLatestSectionId } = useSectionIdStore.getState();
|
|
424418
|
+
setLatestSectionId(targetSectionId);
|
|
424419
|
+
}
|
|
424420
|
+
});
|
|
424421
|
+
// 检查是否需要更新的辅助函数
|
|
424422
|
+
const shouldSkipUpdate = useMemoizedFn((currentId, currentSectionId, refs)=>{
|
|
424423
|
+
const isFirstRun = refs.prevIdRef.current === undefined && refs.prevSectionIdRef.current === undefined;
|
|
424424
|
+
const hasIdChanged = !isFirstRun && currentId !== refs.prevIdRef.current;
|
|
424425
|
+
const hasSectionIdChanged = !isFirstRun && currentSectionId !== refs.prevSectionIdRef.current;
|
|
424426
|
+
if (!isFirstRun && !hasIdChanged && !hasSectionIdChanged) {
|
|
424427
|
+
refs.prevIdRef.current = currentId;
|
|
424428
|
+
refs.prevSectionIdRef.current = currentSectionId;
|
|
424429
|
+
return true;
|
|
424430
|
+
}
|
|
424431
|
+
refs.prevIdRef.current = currentId;
|
|
424432
|
+
refs.prevSectionIdRef.current = currentSectionId;
|
|
424433
|
+
return false;
|
|
424434
|
+
});
|
|
424435
|
+
// 更新 conversationId 的辅助函数
|
|
424436
|
+
const updateConversationId = useMemoizedFn((currentId, currentSectionId, isNewConversationFromEmpty)=>{
|
|
424437
|
+
if (isNewConversationFromEmpty) {
|
|
424438
|
+
// 只更新 chatCore 的 conversationId,不调用 setConversationIdInArea
|
|
424439
|
+
// 这样可以避免触发重新初始化,导致正在进行的请求被中止
|
|
424440
|
+
chatCore === null || chatCore === void 0 ? void 0 : chatCore.updateConversationId(currentId);
|
|
424441
|
+
updateSectionIdIfNeeded(currentSectionId, sectionId);
|
|
424442
|
+
} else {
|
|
424443
|
+
// 正常切换会话,立即更新
|
|
424444
|
+
setConversationIdInArea(currentId);
|
|
424445
|
+
chatCore === null || chatCore === void 0 ? void 0 : chatCore.updateConversationId(currentId);
|
|
424446
|
+
updateSectionIdIfNeeded(currentSectionId, sectionId);
|
|
424447
|
+
}
|
|
424448
|
+
});
|
|
423646
424449
|
(0,react.useEffect)(()=>{
|
|
423647
424450
|
var _chatConfig_ui_conversations, _chatConfig_ui;
|
|
423648
|
-
if (
|
|
423649
|
-
|
|
423650
|
-
|
|
423651
|
-
|
|
423652
|
-
|
|
423653
|
-
|
|
423654
|
-
|
|
423655
|
-
|
|
423656
|
-
|
|
423657
|
-
|
|
423658
|
-
|
|
423659
|
-
|
|
423660
|
-
|
|
423661
|
-
|
|
423662
|
-
|
|
423663
|
-
|
|
423664
|
-
|
|
423665
|
-
|
|
423666
|
-
|
|
424451
|
+
if (!stableConversationId || !((_chatConfig_ui = chatConfig.ui) === null || _chatConfig_ui === void 0 ? void 0 : (_chatConfig_ui_conversations = _chatConfig_ui.conversations) === null || _chatConfig_ui_conversations === void 0 ? void 0 : _chatConfig_ui_conversations.isNeed)) {
|
|
424452
|
+
return;
|
|
424453
|
+
}
|
|
424454
|
+
const currentId = stableConversationId;
|
|
424455
|
+
const currentConversationWithSectionId = currentConversationInfo;
|
|
424456
|
+
const currentSectionId = stableLastSectionId || currentConversationWithSectionId.sectionId || '';
|
|
424457
|
+
// 先更新 sectionId,再更新 conversationId,确保消息加载时使用正确的 sectionId
|
|
424458
|
+
updateSectionIdIfNeeded(currentSectionId, sectionId);
|
|
424459
|
+
// 检查是否需要跳过更新
|
|
424460
|
+
if (shouldSkipUpdate(currentId, currentSectionId, {
|
|
424461
|
+
prevIdRef: prevConversationIdRef,
|
|
424462
|
+
prevSectionIdRef
|
|
424463
|
+
})) {
|
|
424464
|
+
return;
|
|
424465
|
+
}
|
|
424466
|
+
// 只有当 conversationId 发生变化时才更新
|
|
424467
|
+
if (currentId !== conversationId) {
|
|
424468
|
+
// 如果 conversationId 从空字符串或null变为新ID,说明是从空会话创建的新会话
|
|
424469
|
+
// 此时不应该立即调用 setConversationIdInArea,因为它可能触发重新初始化
|
|
424470
|
+
// 导致正在进行的请求被中止
|
|
424471
|
+
// setConversationIdInArea 会在消息流完成时被调用(在 onGetMessageStreamParser 的 DONE 事件中)
|
|
424472
|
+
const isNewConversationFromEmpty = conversationId === '' || conversationId === null;
|
|
424473
|
+
updateConversationId(currentId, currentSectionId, isNewConversationFromEmpty);
|
|
423667
424474
|
}
|
|
423668
424475
|
}, [
|
|
423669
|
-
|
|
423670
|
-
|
|
424476
|
+
stableConversationId,
|
|
424477
|
+
stableLastSectionId,
|
|
423671
424478
|
conversationId,
|
|
423672
424479
|
sectionId,
|
|
423673
424480
|
setConversationIdInArea,
|
|
423674
424481
|
chatCore,
|
|
423675
|
-
(_chatConfig_ui = chatConfig.ui) === null || _chatConfig_ui === void 0 ? void 0 : (_chatConfig_ui_conversations = _chatConfig_ui.conversations) === null || _chatConfig_ui_conversations === void 0 ? void 0 : _chatConfig_ui_conversations.isNeed
|
|
424482
|
+
(_chatConfig_ui = chatConfig.ui) === null || _chatConfig_ui === void 0 ? void 0 : (_chatConfig_ui_conversations = _chatConfig_ui.conversations) === null || _chatConfig_ui_conversations === void 0 ? void 0 : _chatConfig_ui_conversations.isNeed,
|
|
424483
|
+
updateSectionIdIfNeeded,
|
|
424484
|
+
shouldSkipUpdate,
|
|
424485
|
+
updateConversationId,
|
|
424486
|
+
currentConversationInfo
|
|
423676
424487
|
]);
|
|
423677
424488
|
useUpdateConversationNameByMessage();
|
|
423678
424489
|
const regenerateMessageByUserMessageId = useRegenerateMessageByUserMessageId();
|
|
@@ -435978,6 +436789,7 @@ var header_pc_index_module_update = injectStylesIntoStyleTag_default()(header_pc
|
|
|
435978
436789
|
|
|
435979
436790
|
|
|
435980
436791
|
|
|
436792
|
+
|
|
435981
436793
|
const ChatHeader = (param)=>{
|
|
435982
436794
|
let { iconUrl = coze_logo_namespaceObject, title = 'Coze Bot', extra, theme, isShowConversations, isNeedLogo = true } = param;
|
|
435983
436795
|
const { headerTopLeftOps } = useChatOpInfo();
|
|
@@ -435993,18 +436805,20 @@ const ChatHeader = (param)=>{
|
|
|
435993
436805
|
const [renameInputValue, setRenameInputValue] = (0,react.useState)('');
|
|
435994
436806
|
const [isRenameLoading, setIsRenameLoading] = (0,react.useState)(false);
|
|
435995
436807
|
// 使用 useMemo 计算显示文本,确保 title 变化时能及时更新
|
|
435996
|
-
const conversationTitle = currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.title;
|
|
435997
|
-
const conversationName = currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.name;
|
|
435998
436808
|
const conversationId = currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.id;
|
|
435999
436809
|
const displayTitle = (0,react.useMemo)(()=>{
|
|
436000
436810
|
if (conversationId === '') {
|
|
436001
436811
|
return title;
|
|
436002
436812
|
}
|
|
436003
|
-
|
|
436813
|
+
if (!currentConversationInfo) {
|
|
436814
|
+
return title;
|
|
436815
|
+
}
|
|
436816
|
+
// 使用 getConversationDisplayName 处理 UUID 检查
|
|
436817
|
+
const conversationItem = currentConversationInfo;
|
|
436818
|
+
return getConversationDisplayName(conversationItem) || title;
|
|
436004
436819
|
}, [
|
|
436005
436820
|
conversationId,
|
|
436006
|
-
|
|
436007
|
-
conversationName,
|
|
436821
|
+
currentConversationInfo,
|
|
436008
436822
|
title
|
|
436009
436823
|
]);
|
|
436010
436824
|
// 打开重命名弹窗
|
|
@@ -436230,6 +437044,7 @@ var header_mobile_index_module_update = injectStylesIntoStyleTag_default()(heade
|
|
|
436230
437044
|
|
|
436231
437045
|
|
|
436232
437046
|
|
|
437047
|
+
|
|
436233
437048
|
const ChatHeaderMobile = (param)=>{
|
|
436234
437049
|
let { iconUrl = coze_logo_namespaceObject, title = 'Coze Bot', extra, theme, isShowConversations, isNeedLogo = true } = param;
|
|
436235
437050
|
const { headerTopLeftOps } = useChatOpInfo();
|
|
@@ -436245,18 +437060,20 @@ const ChatHeaderMobile = (param)=>{
|
|
|
436245
437060
|
const [renameInputValue, setRenameInputValue] = (0,react.useState)('');
|
|
436246
437061
|
const [isRenameLoading, setIsRenameLoading] = (0,react.useState)(false);
|
|
436247
437062
|
// 使用 useMemo 计算显示文本,确保 title 变化时能及时更新
|
|
436248
|
-
const conversationTitle = currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.title;
|
|
436249
|
-
const conversationName = currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.name;
|
|
436250
437063
|
const conversationId = currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.id;
|
|
436251
437064
|
const displayTitle = (0,react.useMemo)(()=>{
|
|
436252
437065
|
if (conversationId === '') {
|
|
436253
437066
|
return title;
|
|
436254
437067
|
}
|
|
436255
|
-
|
|
437068
|
+
if (!currentConversationInfo) {
|
|
437069
|
+
return title;
|
|
437070
|
+
}
|
|
437071
|
+
// 使用 getConversationDisplayName 处理 UUID 检查
|
|
437072
|
+
const conversationItem = currentConversationInfo;
|
|
437073
|
+
return getConversationDisplayName(conversationItem) || title;
|
|
436256
437074
|
}, [
|
|
436257
437075
|
conversationId,
|
|
436258
|
-
|
|
436259
|
-
conversationName,
|
|
437076
|
+
currentConversationInfo,
|
|
436260
437077
|
title
|
|
436261
437078
|
]);
|
|
436262
437079
|
// 打开重命名弹窗
|
|
@@ -437699,7 +438516,20 @@ const use_core_manager_useCoreManager = (props)=>{
|
|
|
437699
438516
|
bodyData.additional_messages = bodyDataOld.additional_messages || [];
|
|
437700
438517
|
bodyData.connector_id = bodyDataOld.connector_id;
|
|
437701
438518
|
bodyData.workflow_id = refProps === null || refProps === void 0 ? void 0 : (_refProps_current = refProps.current) === null || _refProps_current === void 0 ? void 0 : (_refProps_current_workflow = _refProps_current.workflow) === null || _refProps_current_workflow === void 0 ? void 0 : _refProps_current_workflow.id;
|
|
437702
|
-
|
|
438519
|
+
// parameters 应该是一个对象,但 SETTING 字段的值需要序列化为字符串
|
|
438520
|
+
const workflowParameters = refProps === null || refProps === void 0 ? void 0 : (_refProps_current1 = refProps.current) === null || _refProps_current1 === void 0 ? void 0 : (_refProps_current_workflow1 = _refProps_current1.workflow) === null || _refProps_current_workflow1 === void 0 ? void 0 : _refProps_current_workflow1.parameters;
|
|
438521
|
+
if (workflowParameters && typeof workflowParameters === 'object') {
|
|
438522
|
+
// 复制 parameters 对象,只序列化 SETTING 字段的值
|
|
438523
|
+
const processedParameters = {
|
|
438524
|
+
...workflowParameters
|
|
438525
|
+
};
|
|
438526
|
+
if (processedParameters.SETTING && typeof processedParameters.SETTING === 'object') {
|
|
438527
|
+
processedParameters.SETTING = JSON.stringify(processedParameters.SETTING);
|
|
438528
|
+
}
|
|
438529
|
+
bodyData.parameters = processedParameters;
|
|
438530
|
+
} else {
|
|
438531
|
+
bodyData.parameters = workflowParameters;
|
|
438532
|
+
}
|
|
437703
438533
|
bodyData.version = (refProps === null || refProps === void 0 ? void 0 : (_refProps_current2 = refProps.current) === null || _refProps_current2 === void 0 ? void 0 : (_refProps_current_project = _refProps_current2.project) === null || _refProps_current_project === void 0 ? void 0 : _refProps_current_project.version) || undefined;
|
|
437704
438534
|
bodyData.execute_mode = (refProps === null || refProps === void 0 ? void 0 : (_refProps_current3 = refProps.current) === null || _refProps_current3 === void 0 ? void 0 : (_refProps_current_project1 = _refProps_current3.project) === null || _refProps_current_project1 === void 0 ? void 0 : _refProps_current_project1.mode) === 'draft' ? 'DEBUG' : undefined;
|
|
437705
438535
|
bodyData.app_id = (refProps === null || refProps === void 0 ? void 0 : (_refProps_current4 = refProps.current) === null || _refProps_current4 === void 0 ? void 0 : (_refProps_current_project2 = _refProps_current4.project) === null || _refProps_current_project2 === void 0 ? void 0 : _refProps_current_project2.type) === 'app' ? refProps === null || refProps === void 0 ? void 0 : (_refProps_current5 = refProps.current) === null || _refProps_current5 === void 0 ? void 0 : (_refProps_current_project3 = _refProps_current5.project) === null || _refProps_current_project3 === void 0 ? void 0 : _refProps_current_project3.id : undefined;
|
|
@@ -437715,8 +438545,13 @@ const use_core_manager_useCoreManager = (props)=>{
|
|
|
437715
438545
|
customized_suggest_prompt: (_refAppData_current2 = refAppData.current) === null || _refAppData_current2 === void 0 ? void 0 : (_refAppData_current_suggestPromoteInfo1 = _refAppData_current2.suggestPromoteInfo) === null || _refAppData_current_suggestPromoteInfo1 === void 0 ? void 0 : _refAppData_current_suggestPromoteInfo1.customizedSuggestPrompt
|
|
437716
438546
|
} : undefined;
|
|
437717
438547
|
requestConfig.body = JSON.stringify(bodyData);
|
|
437718
|
-
//
|
|
437719
|
-
|
|
438548
|
+
// 只有在URL还没有被其他hook设置时才设置URL
|
|
438549
|
+
// 如果URL已经包含conversation_id参数(说明已经被useSendMessageAdapter设置了),保留原URL
|
|
438550
|
+
const urlHasConversationId = new URL(requestConfig.url, 'http://dummy.com').searchParams.has('conversation_id');
|
|
438551
|
+
if (!urlHasConversationId) {
|
|
438552
|
+
// 使用计算后的 finalApiUrl
|
|
438553
|
+
requestConfig.url = `${finalApiUrl}/v1/workflows/chat`;
|
|
438554
|
+
}
|
|
437720
438555
|
requestConfig.headers.push(...Object.entries(((_refProps_current9 = refProps.current) === null || _refProps_current9 === void 0 ? void 0 : (_refProps_current_workflow2 = _refProps_current9.workflow) === null || _refProps_current_workflow2 === void 0 ? void 0 : _refProps_current_workflow2.header) || {}));
|
|
437721
438556
|
return {
|
|
437722
438557
|
...requestConfig
|