@glodon-aiot/chat-app-sdk 0.0.27 → 0.0.29

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 CHANGED
@@ -7414,7 +7414,7 @@ var ___CSS_LOADER_EXPORT___ = _common_temp_default_node_modules_pnpm_css_loader_
7414
7414
  // Module
7415
7415
  ___CSS_LOADER_EXPORT___.push([
7416
7416
  module.id,
7417
- ".d5141aa56d2a57c00935 {\n width: 100%;\n margin-top: 7px;\n text-align: left;\n}\n.d79b06a73340274bc426 {\n font-size: 14px;\n font-weight: 400;\n color: #666;\n margin-bottom: 8px;\n line-height: 20px;\n}\n.eda25befdf424f596ef1 {\n padding-right: 25px;\n padding-left: 69px;\n}\n.e98fa6d756df3cd56afc {\n padding-right: 10px;\n padding-left: 58px;\n}\n.ed28c7ac4d2c9165f95b {\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: center;\n width: -moz-fit-content;\n width: fit-content;\n font-size: 14px;\n font-weight: 400;\n font-style: normal;\n line-height: 20px;\n border-style: solid;\n border-width: 1px;\n}\n.ed28c7ac4d2c9165f95b svg {\n width: 14px;\n height: 14px;\n}\n.b23b4c693bd848c83e8f {\n width: 100%;\n margin-top: 8px;\n}\n.e40e4bebca37dd563842 {\n padding-left: 69px;\n}\n.e854b20ceb21944e2eef {\n padding-left: 44px;\n}\n.fc781d12eaaa0f3deaf9 {\n margin-left: 56px;\n}\n.ced572f6343196fb5030 {\n margin-left: 28px;\n}\n",
7417
+ ".d5141aa56d2a57c00935 {\n width: 100%;\n margin-top: 7px;\n text-align: left;\n}\n.d79b06a73340274bc426 {\n font-size: 14px;\n font-weight: 400;\n color: #666;\n margin-bottom: 8px;\n line-height: 20px;\n}\n.eda25befdf424f596ef1 {\n padding-right: 25px;\n padding-left: 25px;\n}\n.e98fa6d756df3cd56afc {\n padding-right: 10px;\n padding-left: 25px;\n}\n.ed28c7ac4d2c9165f95b {\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: center;\n width: -moz-fit-content;\n width: fit-content;\n font-size: 14px;\n font-weight: 400;\n font-style: normal;\n line-height: 20px;\n border-style: solid;\n border-width: 1px;\n}\n.ed28c7ac4d2c9165f95b svg {\n width: 14px;\n height: 14px;\n}\n.b23b4c693bd848c83e8f {\n width: 100%;\n margin-top: 8px;\n}\n.e40e4bebca37dd563842 {\n padding-left: 69px;\n}\n.e854b20ceb21944e2eef {\n padding-left: 44px;\n}\n.fc781d12eaaa0f3deaf9 {\n margin-left: 56px;\n}\n.ced572f6343196fb5030 {\n margin-left: 28px;\n}\n",
7418
7418
  ""
7419
7419
  ]);
7420
7420
  // Exports
@@ -294756,7 +294756,10 @@ const FileCard_FileCard = (props)=>{
294756
294756
  ].includes(file[statusKey]) ? FAIL_FILE_ICON_MAP : SUCCESS_FILE_ICON_MAP;
294757
294757
  const buttonsVisible = !readonly;
294758
294758
  const { extension, nameWithoutExtension } = getFileExtensionAndName(file.file_name);
294759
- const isCanceled = file[statusKey] === statusEnum.cancelEnum;
294759
+ // Coze Chat SDK uses status 3 for upload failed; show as failed (not canceled)
294760
+ const FILE_STATUS_UPLOAD_FAILED = 3;
294761
+ const isUploadFailed = file[statusKey] === statusEnum.failEnum || file[statusKey] === FILE_STATUS_UPLOAD_FAILED;
294762
+ const isCanceled = file[statusKey] === statusEnum.cancelEnum && file[statusKey] !== FILE_STATUS_UPLOAD_FAILED;
294760
294763
  const fileStatusValue = file[statusKey];
294761
294764
  const fileUrl = file.file_url;
294762
294765
  const fileKey = file.file_key;
@@ -294824,7 +294827,7 @@ const FileCard_FileCard = (props)=>{
294824
294827
  // showBackground && file[statusKey] !== statusEnum.failEnum,
294825
294828
  // })}
294826
294829
  className: classnames_default()(typeSafeFileCardVariants({
294827
- isError: file[statusKey] === statusEnum.failEnum,
294830
+ isError: isUploadFailed,
294828
294831
  layout: layout === common_Layout.PC ? "pc" : "mobile",
294829
294832
  showBackground
294830
294833
  }), className, "cursor-pointer"),
@@ -294890,10 +294893,10 @@ const FileCard_FileCard = (props)=>{
294890
294893
  }
294891
294894
  })
294892
294895
  }),
294893
- [
294896
+ ([
294894
294897
  statusEnum.cancelEnum,
294895
294898
  statusEnum.failEnum
294896
- ].includes(file[statusKey]) && /*#__PURE__*/ (0,jsx_runtime_.jsx)(UIKitTooltip, {
294899
+ ].includes(file[statusKey]) || file[statusKey] === FILE_STATUS_UPLOAD_FAILED) && /*#__PURE__*/ (0,jsx_runtime_.jsx)(UIKitTooltip, {
294897
294900
  theme: "light",
294898
294901
  position: "top",
294899
294902
  content: tooltipsCopywriting === null || tooltipsCopywriting === void 0 ? void 0 : tooltipsCopywriting.retry,
@@ -426655,6 +426658,510 @@ const DragUploadArea = ()=>{
426655
426658
  });
426656
426659
  };
426657
426660
 
426661
+ ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/public/use-latest-section-id.ts
426662
+ /*
426663
+ * Copyright 2025 coze-dev Authors
426664
+ *
426665
+ * Licensed under the Apache License, Version 2.0 (the "License");
426666
+ * you may not use this file except in compliance with the License.
426667
+ * You may obtain a copy of the License at
426668
+ *
426669
+ * http://www.apache.org/licenses/LICENSE-2.0
426670
+ *
426671
+ * Unless required by applicable law or agreed to in writing, software
426672
+ * distributed under the License is distributed on an "AS IS" BASIS,
426673
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
426674
+ * See the License for the specific language governing permissions and
426675
+ * limitations under the License.
426676
+ */
426677
+ const use_latest_section_id_useLatestSectionId = ()=>{
426678
+ const { useSectionIdStore } = use_chat_area_context_useChatAreaStoreSet();
426679
+ const latestSectionId = useSectionIdStore((state)=>state.latestSectionId);
426680
+ return latestSectionId;
426681
+ };
426682
+
426683
+ ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/context/use-conversation-id.ts
426684
+ /*
426685
+ * Copyright 2025 coze-dev Authors
426686
+ *
426687
+ * Licensed under the Apache License, Version 2.0 (the "License");
426688
+ * you may not use this file except in compliance with the License.
426689
+ * You may obtain a copy of the License at
426690
+ *
426691
+ * http://www.apache.org/licenses/LICENSE-2.0
426692
+ *
426693
+ * Unless required by applicable law or agreed to in writing, software
426694
+ * distributed under the License is distributed on an "AS IS" BASIS,
426695
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
426696
+ * See the License for the specific language governing permissions and
426697
+ * limitations under the License.
426698
+ */
426699
+
426700
+
426701
+ const useConversationId = ()=>{
426702
+ const chatAreaStoreSetContext = use_chat_area_context_useChatAreaStoreSet();
426703
+ if (!is_valid_context_isValidContext(chatAreaStoreSetContext)) throw new Error("chatAreaStoreSetContext is not valid");
426704
+ const { useGlobalInitStore } = chatAreaStoreSetContext;
426705
+ const conversationId = useGlobalInitStore((state)=>state.conversationId);
426706
+ return conversationId;
426707
+ };
426708
+
426709
+ ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/file/use-upload-to-knowledge.ts
426710
+ /*
426711
+ * Copyright 2025 coze-dev Authors
426712
+ *
426713
+ * Licensed under the Apache License, Version 2.0 (the "License");
426714
+ * you may not use this file except in compliance with the License.
426715
+ * You may obtain a copy of the License at
426716
+ *
426717
+ * http://www.apache.org/licenses/LICENSE-2.0
426718
+ *
426719
+ * Unless required by applicable law or agreed to in writing, software
426720
+ * distributed under the License is distributed on an "AS IS" BASIS,
426721
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
426722
+ * See the License for the specific language governing permissions and
426723
+ * limitations under the License.
426724
+ */ /* eslint-disable max-lines -- This file contains complex upload logic that requires many lines */
426725
+
426726
+
426727
+
426728
+ // Try to import from open-chat if available
426729
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426730
+ let use_upload_to_knowledge_useChatAppProps = null;
426731
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426732
+ let use_upload_to_knowledge_useChatCozeSdk = null;
426733
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426734
+ let use_upload_to_knowledge_useChatAppStore = null;
426735
+ // Try to import updateCurrentConversationInfo from open-chat if available
426736
+ // Note: This variable is currently unused but kept for future use
426737
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
426738
+ const use_upload_to_knowledge_updateCurrentConversationInfo = null;
426739
+ let use_upload_to_knowledge_createConversationForMessage = null;
426740
+ try {
426741
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
426742
+ const openChatModule = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module '@coze-studio/open-chat'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
426743
+ if (openChatModule.useChatAppProps) use_upload_to_knowledge_useChatAppProps = openChatModule.useChatAppProps;
426744
+ if (openChatModule.useChatCozeSdk) use_upload_to_knowledge_useChatCozeSdk = openChatModule.useChatCozeSdk;
426745
+ if (openChatModule.useChatAppStore) use_upload_to_knowledge_useChatAppStore = openChatModule.useChatAppStore;
426746
+ // Try to get updateCurrentConversationInfo from store
426747
+ try {
426748
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426749
+ const storeHook = openChatModule.useChatAppStore;
426750
+ storeHook && typeof storeHook;
426751
+ } catch (error) {
426752
+ // Store not available
426753
+ error;
426754
+ }
426755
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
426756
+ const createConversationModule = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module '@coze-studio/open-chat/chat/builder-chat/services/create-conversation'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
426757
+ if (createConversationModule.createConversationForMessage) use_upload_to_knowledge_createConversationForMessage = createConversationModule.createConversationForMessage;
426758
+ } catch (error) {
426759
+ // Module not available, hooks will be null
426760
+ error;
426761
+ }
426762
+ /** 按 fileId 存储轮询的 AbortController,删除文件时用于停止轮询 */ const knowledgePollingControllers = new Map();
426763
+ /**
426764
+ * 取消指定 fileId 的知识库文件状态轮询(会话中删除正在上传的文件时调用)
426765
+ */ function cancelKnowledgePolling(fileId) {
426766
+ const controller = knowledgePollingControllers.get(fileId);
426767
+ if (controller) {
426768
+ controller.abort();
426769
+ knowledgePollingControllers.delete(fileId);
426770
+ }
426771
+ }
426772
+ var use_upload_to_knowledge_FileProcessStatus;
426773
+ (function(FileProcessStatus) {
426774
+ FileProcessStatus[FileProcessStatus["Processing"] = 1] = "Processing";
426775
+ FileProcessStatus[FileProcessStatus["Completed"] = 2] = "Completed";
426776
+ FileProcessStatus[FileProcessStatus["Failed"] = 3] = "Failed";
426777
+ FileProcessStatus[FileProcessStatus["NotFound"] = -1] = "NotFound";
426778
+ })(use_upload_to_knowledge_FileProcessStatus || (use_upload_to_knowledge_FileProcessStatus = {}));
426779
+ /**
426780
+ * Query file processing status
426781
+ * @param params Query parameters
426782
+ * @returns File status items or null if query failed
426783
+ */ async function queryFileStatus(params) {
426784
+ const { apiUrl, token, appId, conversationId, sectionId, knowledgeId, docIds } = params;
426785
+ try {
426786
+ const requestBody = {
426787
+ app_id: appId,
426788
+ conversation_id: conversationId,
426789
+ section_id: sectionId,
426790
+ knowledge_id: knowledgeId,
426791
+ doc_ids: docIds
426792
+ };
426793
+ const apiEndpoint = `${apiUrl}/v1/workflows/conversation/file/status`;
426794
+ const response = await fetch(apiEndpoint, {
426795
+ method: "POST",
426796
+ headers: {
426797
+ "Content-Type": "application/json",
426798
+ Authorization: `Bearer ${token}`
426799
+ },
426800
+ body: JSON.stringify(requestBody)
426801
+ });
426802
+ const result = await response.json();
426803
+ if (result.code === 0 && result.data) {
426804
+ // Log status for each file
426805
+ result.data.forEach((item)=>{
426806
+ const statusText = item.status === 1 ? "处理中" : item.status === 2 ? "已完成" : item.status === 3 ? "处理失败" : item.status === -1 ? "文件不存在或异常" : `未知状态(${item.status})`;
426807
+ console.log(`File ${item.file_id} status: ${statusText}`, {
426808
+ file_id: item.file_id,
426809
+ status: item.status,
426810
+ message: item.message
426811
+ });
426812
+ });
426813
+ return result.data;
426814
+ } else {
426815
+ console.error("Failed to query file status:", result.msg || "Unknown error");
426816
+ return null;
426817
+ }
426818
+ } catch (error) {
426819
+ console.error("Error querying file status:", error);
426820
+ return null;
426821
+ }
426822
+ }
426823
+ /**
426824
+ * Poll file status until completion or failure
426825
+ * @param params Query parameters
426826
+ * @param options Polling options (intervalMs, signal for cancellation)
426827
+ * @returns Final file status items or null if polling failed / was aborted
426828
+ */ async function pollFileStatus(params) {
426829
+ let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
426830
+ const { intervalMs = 2000, signal } = options;
426831
+ for(;;){
426832
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) return null;
426833
+ const statusResult = await queryFileStatus(params);
426834
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) return null;
426835
+ if (!statusResult || statusResult.length === 0) {
426836
+ await new Promise((resolve)=>setTimeout(resolve, intervalMs));
426837
+ continue;
426838
+ }
426839
+ // Check if all files are in final state (completed, failed, or not found)
426840
+ const allFinal = statusResult.every((item)=>item.status === 2 || item.status === 3 || item.status === -1);
426841
+ if (allFinal) return statusResult;
426842
+ // Some files are still processing, wait and retry
426843
+ await new Promise((resolve)=>setTimeout(resolve, intervalMs));
426844
+ }
426845
+ }
426846
+ /**
426847
+ * Hook to upload file to knowledge base
426848
+ */ // eslint-disable-next-line @coze-arch/max-line-per-function
426849
+ const useUploadToKnowledge = (config)=>{
426850
+ const conversationId = useConversationId();
426851
+ const sectionId = use_latest_section_id_useLatestSectionId();
426852
+ const storeSet = use_chat_area_context_useChatAreaStoreSet();
426853
+ const { useGlobalInitStore, useSectionIdStore } = storeSet;
426854
+ // Get setLatestSectionId from the store
426855
+ // Always call the hook to satisfy React Hooks rules
426856
+ // useChatAreaStoreSet() throws if context is invalid, so useSectionIdStore is always defined
426857
+ const setLatestSectionId = useSectionIdStore((state)=>state.setLatestSectionId);
426858
+ // Try to get apiUrl from useChatAppStore as fallback
426859
+ let apiUrlFromStore;
426860
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426861
+ const chatAppStoreHook = use_upload_to_knowledge_useChatAppStore;
426862
+ if (chatAppStoreHook && typeof chatAppStoreHook === "function") try {
426863
+ apiUrlFromStore = chatAppStoreHook((state)=>state.apiUrl);
426864
+ } catch (error) {
426865
+ // Store not available
426866
+ error;
426867
+ }
426868
+ const uploadFileToKnowledge = (0,react_.useCallback)(// eslint-disable-next-line @coze-arch/max-line-per-function, max-lines-per-function, complexity -- uploadFileToKnowledge requires many lines for complete file upload functionality
426869
+ async (file, options)=>{
426870
+ const fileId = options === null || options === void 0 ? void 0 : options.fileId;
426871
+ const controller = fileId ? new AbortController() : undefined;
426872
+ if (fileId && controller) knowledgePollingControllers.set(fileId, controller);
426873
+ try {
426874
+ var _chatConfig_appInfo, _chatConfig_auth;
426875
+ let chatConfig;
426876
+ let cozeApiSdk;
426877
+ // Use config from props first, then try to get from hooks, then fallback to store
426878
+ let apiUrl = (config === null || config === void 0 ? void 0 : config.apiUrl) || apiUrlFromStore;
426879
+ let appId = config === null || config === void 0 ? void 0 : config.appId;
426880
+ let token = config === null || config === void 0 ? void 0 : config.token;
426881
+ let workflowId = config === null || config === void 0 ? void 0 : config.workflowId;
426882
+ let draftMode = config === null || config === void 0 ? void 0 : config.draftMode;
426883
+ let conversationName = config === null || config === void 0 ? void 0 : config.conversationName;
426884
+ let connectorId = config === null || config === void 0 ? void 0 : config.connectorId;
426885
+ let chatType = config === null || config === void 0 ? void 0 : config.chatType;
426886
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useChatAppProps may not be available in all contexts
426887
+ const chatAppPropsHook = use_upload_to_knowledge_useChatAppProps;
426888
+ if (chatAppPropsHook && typeof chatAppPropsHook === "function") try {
426889
+ const chatAppProps = chatAppPropsHook();
426890
+ chatConfig = chatAppProps === null || chatAppProps === void 0 ? void 0 : chatAppProps.chatConfig;
426891
+ // Use values from hook if not provided in config
426892
+ if (!apiUrl) {
426893
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useChatAppStore may not be available in all contexts
426894
+ const storeHook = use_upload_to_knowledge_useChatAppStore;
426895
+ if (storeHook && typeof storeHook === "function") try {
426896
+ apiUrl = storeHook((state)=>state.apiUrl) || apiUrl;
426897
+ } catch (error) {
426898
+ // Store not available
426899
+ error;
426900
+ }
426901
+ }
426902
+ // Fill in missing values from chatConfig if not in config
426903
+ if (!appId) {
426904
+ var _chatConfig_appInfo1;
426905
+ appId = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo1 = chatConfig.appInfo) === null || _chatConfig_appInfo1 === void 0 ? void 0 : _chatConfig_appInfo1.appId) || (chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.bot_id);
426906
+ }
426907
+ if (!token) {
426908
+ var _chatConfig_auth1;
426909
+ token = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth1 = chatConfig.auth) === null || _chatConfig_auth1 === void 0 ? void 0 : _chatConfig_auth1.token;
426910
+ }
426911
+ if (!workflowId) {
426912
+ var _chatConfig_appInfo2;
426913
+ workflowId = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo2 = chatConfig.appInfo) === null || _chatConfig_appInfo2 === void 0 ? void 0 : _chatConfig_appInfo2.workflowId;
426914
+ }
426915
+ if (draftMode === undefined) {
426916
+ var _chatConfig_appInfo3;
426917
+ draftMode = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo3 = chatConfig.appInfo) === null || _chatConfig_appInfo3 === void 0 ? void 0 : _chatConfig_appInfo3.draft_mode;
426918
+ }
426919
+ if (!conversationName) {
426920
+ var _chatConfig_appInfo4;
426921
+ conversationName = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo4 = chatConfig.appInfo) === null || _chatConfig_appInfo4 === void 0 ? void 0 : _chatConfig_appInfo4.conversationName;
426922
+ }
426923
+ if (!connectorId) {
426924
+ var _chatConfig_auth2;
426925
+ connectorId = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth2 = chatConfig.auth) === null || _chatConfig_auth2 === void 0 ? void 0 : _chatConfig_auth2.connectorId;
426926
+ }
426927
+ if (!chatType) chatType = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.type;
426928
+ } catch (error) {
426929
+ // Hook not available in this context
426930
+ error;
426931
+ }
426932
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useChatCozeSdk may not be available in all contexts
426933
+ const chatCozeSdkHook = use_upload_to_knowledge_useChatCozeSdk;
426934
+ if (chatCozeSdkHook && typeof chatCozeSdkHook === "function") try {
426935
+ const chatCozeSdk = chatCozeSdkHook();
426936
+ cozeApiSdk = chatCozeSdk === null || chatCozeSdk === void 0 ? void 0 : chatCozeSdk.cozeApiSdk;
426937
+ } catch (error1) {
426938
+ // Hook not available in this context
426939
+ error1;
426940
+ }
426941
+ // Check if we have minimum required info (apiUrl and appId)
426942
+ // We can work without chatConfig and cozeApiSdk if config is provided
426943
+ if (!apiUrl || !appId) {
426944
+ console.warn("Cannot upload to knowledge: apiUrl or appId is missing");
426945
+ return null;
426946
+ }
426947
+ // If we don't have chatConfig, create a minimal one from config
426948
+ if (!chatConfig) chatConfig = {
426949
+ type: chatType,
426950
+ appInfo: {
426951
+ appId,
426952
+ workflowId,
426953
+ draft_mode: draftMode,
426954
+ conversationName
426955
+ },
426956
+ bot_id: appId,
426957
+ auth: {
426958
+ token,
426959
+ connectorId
426960
+ }
426961
+ };
426962
+ // 1. Get or create conversation
426963
+ let currentConversationId = conversationId || "";
426964
+ let currentSectionId = sectionId || "";
426965
+ // If no conversation, create one
426966
+ if (!currentConversationId) {
426967
+ var _chatConfig_appInfo5, _chatConfig_appInfo6, _chatConfig_appInfo7, _chatConfig_appInfo8, _chatConfig_auth3, _chatConfig_auth4;
426968
+ const finalAppId = appId || ((_chatConfig_appInfo5 = chatConfig.appInfo) === null || _chatConfig_appInfo5 === void 0 ? void 0 : _chatConfig_appInfo5.appId) || chatConfig.bot_id || "";
426969
+ if (!finalAppId) {
426970
+ console.error("Cannot upload to knowledge: app_id is missing");
426971
+ return null;
426972
+ }
426973
+ const projectType = (chatType || chatConfig.type) === "app" ? "app" : "bot";
426974
+ const finalWorkflowId = workflowId || ((_chatConfig_appInfo6 = chatConfig.appInfo) === null || _chatConfig_appInfo6 === void 0 ? void 0 : _chatConfig_appInfo6.workflowId);
426975
+ const finalDraftMode = draftMode !== undefined ? draftMode : (_chatConfig_appInfo7 = chatConfig.appInfo) === null || _chatConfig_appInfo7 === void 0 ? void 0 : _chatConfig_appInfo7.draft_mode;
426976
+ const finalConversationName = conversationName || ((_chatConfig_appInfo8 = chatConfig.appInfo) === null || _chatConfig_appInfo8 === void 0 ? void 0 : _chatConfig_appInfo8.conversationName);
426977
+ const finalConnectorId = connectorId || ((_chatConfig_auth3 = chatConfig.auth) === null || _chatConfig_auth3 === void 0 ? void 0 : _chatConfig_auth3.connectorId);
426978
+ const finalToken = token || ((_chatConfig_auth4 = chatConfig.auth) === null || _chatConfig_auth4 === void 0 ? void 0 : _chatConfig_auth4.token) || "";
426979
+ // Try to use createConversationForMessage if available
426980
+ if (use_upload_to_knowledge_createConversationForMessage && cozeApiSdk) try {
426981
+ const conversationResult = await use_upload_to_knowledge_createConversationForMessage(cozeApiSdk, {
426982
+ projectType,
426983
+ projectId: finalAppId,
426984
+ workflowId: finalWorkflowId,
426985
+ mode: finalDraftMode ? "draft" : "release",
426986
+ conversationName: finalConversationName,
426987
+ connectorId: finalConnectorId
426988
+ });
426989
+ currentConversationId = conversationResult.conversationId;
426990
+ currentSectionId = conversationResult.sectionId;
426991
+ } catch (error) {
426992
+ console.warn("Failed to create conversation using createConversationForMessage:", error);
426993
+ // Fall through to direct API call
426994
+ }
426995
+ // If createConversationForMessage failed or is not available, use direct API call
426996
+ // Note: finalApiUrl is defined later in the code, so we use apiUrl here
426997
+ if (!currentConversationId && apiUrl && finalToken) try {
426998
+ let createUrl = "";
426999
+ let createPayload = {};
427000
+ if (projectType === "bot") {
427001
+ createUrl = `${apiUrl}/v1/conversations/create`;
427002
+ createPayload = {
427003
+ connector_id: finalConnectorId
427004
+ };
427005
+ } else {
427006
+ createUrl = `${apiUrl}/v1/workflow/conversation/create`;
427007
+ createPayload = {
427008
+ app_id: finalAppId,
427009
+ draft_mode: finalDraftMode || false,
427010
+ workflow_id: finalWorkflowId || "",
427011
+ connector_id: finalConnectorId
427012
+ };
427013
+ // Only add get_or_create if conversationName is provided
427014
+ if (finalConversationName && finalConversationName.trim() !== "") {
427015
+ createPayload.get_or_create = true;
427016
+ createPayload.conversation_name = finalConversationName;
427017
+ }
427018
+ }
427019
+ const createResponse = await fetch(createUrl, {
427020
+ method: "POST",
427021
+ headers: {
427022
+ "Content-Type": "application/json",
427023
+ Authorization: `Bearer ${finalToken}`,
427024
+ "Accept-Language": "en"
427025
+ },
427026
+ body: JSON.stringify(createPayload)
427027
+ });
427028
+ const createResult = await createResponse.json();
427029
+ if (createResult.code === 0 && createResult.data) {
427030
+ currentConversationId = createResult.data.id || "";
427031
+ currentSectionId = createResult.data.last_section_id || "";
427032
+ } else {
427033
+ console.error("Failed to create conversation:", createResult.msg || "Unknown error");
427034
+ return null;
427035
+ }
427036
+ } catch (error1) {
427037
+ console.error("Error creating conversation:", error1);
427038
+ return null;
427039
+ }
427040
+ // Update conversation ID in chat area
427041
+ if (currentConversationId) {
427042
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useGlobalInitStore type may vary by context
427043
+ const globalStore = useGlobalInitStore;
427044
+ if (globalStore && typeof globalStore.getState === "function") {
427045
+ const { setConversationId } = globalStore.getState();
427046
+ setConversationId(currentConversationId);
427047
+ }
427048
+ if (currentSectionId && setLatestSectionId) setLatestSectionId(currentSectionId);
427049
+ // Also update currentConversationInfo in store so text messages can use it
427050
+ // First try to use the callback from config (preferred method)
427051
+ if (config === null || config === void 0 ? void 0 : config.updateCurrentConversationInfo) try {
427052
+ // Delay updating currentConversationInfo to ensure file message is displayed first
427053
+ // This prevents chatarea from refreshing before the file message is added to the store
427054
+ // Use requestAnimationFrame + setTimeout to ensure file message is fully rendered and saved
427055
+ const DELAY_MS = 200; // Increased delay to ensure file message is fully saved to store
427056
+ requestAnimationFrame(()=>{
427057
+ setTimeout(()=>{
427058
+ if (config.updateCurrentConversationInfo) config.updateCurrentConversationInfo({
427059
+ id: currentConversationId,
427060
+ last_section_id: currentSectionId
427061
+ });
427062
+ }, DELAY_MS);
427063
+ });
427064
+ } catch (error) {
427065
+ console.warn("Failed to schedule updateCurrentConversationInfo:", error);
427066
+ }
427067
+ else {
427068
+ // Fallback: try to use dynamically imported hook (may not work in callbacks)
427069
+ // Note: This is a fallback that may not work in callbacks
427070
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- fallback hook may not be available
427071
+ const storeHook = use_upload_to_knowledge_useChatAppStore;
427072
+ }
427073
+ }
427074
+ }
427075
+ if (!currentConversationId || !currentSectionId) {
427076
+ console.error("Cannot upload to knowledge: conversation_id or section_id is missing");
427077
+ return null;
427078
+ }
427079
+ // 2. Prepare FormData
427080
+ const formData = new FormData();
427081
+ formData.append("file", file);
427082
+ formData.append("app_id", appId || ((_chatConfig_appInfo = chatConfig.appInfo) === null || _chatConfig_appInfo === void 0 ? void 0 : _chatConfig_appInfo.appId) || chatConfig.bot_id || "");
427083
+ formData.append("conversation_id", currentConversationId);
427084
+ formData.append("section_id", currentSectionId);
427085
+ // 3. Call upload API
427086
+ // Use apiUrl from config, store, or from cozeApiSdk
427087
+ const finalApiUrl = apiUrl || (cozeApiSdk === null || cozeApiSdk === void 0 ? void 0 : cozeApiSdk.baseURL) || "";
427088
+ const finalToken = token || ((_chatConfig_auth = chatConfig.auth) === null || _chatConfig_auth === void 0 ? void 0 : _chatConfig_auth.token) || "";
427089
+ if (!finalApiUrl) {
427090
+ console.error("Cannot upload to knowledge: API URL is missing");
427091
+ return null;
427092
+ }
427093
+ // Use fetch to upload file
427094
+ const apiEndpoint = `${finalApiUrl}/v1/workflows/conversation/file/toKnowledge`;
427095
+ const response = await fetch(apiEndpoint, {
427096
+ method: "POST",
427097
+ headers: {
427098
+ Authorization: `Bearer ${finalToken}`
427099
+ },
427100
+ body: formData
427101
+ });
427102
+ const result = await response.json();
427103
+ if (result.code === 0 && result.data) {
427104
+ var _chatConfig_appInfo9;
427105
+ // Response data includes: url, uri, bytes, CreatedAt, file_name, id, doc_id, knowledge_id
427106
+ console.log("File uploaded to knowledge successfully:", {
427107
+ url: result.data.url,
427108
+ uri: result.data.uri,
427109
+ file_name: result.data.file_name,
427110
+ id: result.data.id,
427111
+ doc_id: result.data.doc_id,
427112
+ knowledge_id: result.data.knowledge_id,
427113
+ bytes: result.data.bytes,
427114
+ CreatedAt: result.data.CreatedAt
427115
+ });
427116
+ // 4. Query file status after upload (poll until completion or failure)
427117
+ const statusResult = await pollFileStatus({
427118
+ apiUrl: finalApiUrl,
427119
+ token: finalToken,
427120
+ appId: appId || ((_chatConfig_appInfo9 = chatConfig.appInfo) === null || _chatConfig_appInfo9 === void 0 ? void 0 : _chatConfig_appInfo9.appId) || chatConfig.bot_id || "",
427121
+ conversationId: currentConversationId,
427122
+ sectionId: currentSectionId,
427123
+ knowledgeId: result.data.knowledge_id,
427124
+ docIds: [
427125
+ result.data.doc_id
427126
+ ]
427127
+ }, {
427128
+ intervalMs: 2000,
427129
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal
427130
+ });
427131
+ // 轮询被用户取消(已删除文件)时不再更新 store,直接返回 null
427132
+ if (statusResult === null && (controller === null || controller === void 0 ? void 0 : controller.signal.aborted)) return null;
427133
+ if (statusResult) {
427134
+ // 处理失败时返回 null,让 chat-input 将文件标为 Error,file card 展示上传失败
427135
+ const failedFile = statusResult.find((item)=>item.status === 3);
427136
+ if (failedFile) {
427137
+ console.error(`File processing failed: ${failedFile.message}`, failedFile);
427138
+ return null;
427139
+ }
427140
+ }
427141
+ return result.data;
427142
+ } else {
427143
+ console.error("Failed to upload file to knowledge:", result.msg || "Unknown error");
427144
+ return null;
427145
+ }
427146
+ } catch (error) {
427147
+ console.error("Error uploading file to knowledge:", error);
427148
+ return null;
427149
+ } finally{
427150
+ if (fileId) knowledgePollingControllers.delete(fileId);
427151
+ }
427152
+ }, [
427153
+ conversationId,
427154
+ sectionId,
427155
+ setLatestSectionId,
427156
+ useGlobalInitStore,
427157
+ apiUrlFromStore,
427158
+ config
427159
+ ]);
427160
+ return {
427161
+ uploadFileToKnowledge
427162
+ };
427163
+ };
427164
+
426658
427165
  ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/file/use-delete-file.ts
426659
427166
  /*
426660
427167
  * Copyright 2025 coze-dev Authors
@@ -426672,10 +427179,12 @@ const DragUploadArea = ()=>{
426672
427179
  * limitations under the License.
426673
427180
  */
426674
427181
 
427182
+
426675
427183
  const use_delete_file_useDeleteFile = ()=>{
426676
427184
  const { useBatchFileUploadStore } = use_chat_area_context_useChatAreaStoreSet();
426677
427185
  const { cancelUploadById } = useUploadController();
426678
427186
  return (fileId)=>{
427187
+ cancelKnowledgePolling(fileId);
426679
427188
  const { immerDeleteFileDataById } = useBatchFileUploadStore.getState();
426680
427189
  immerDeleteFileDataById(fileId);
426681
427190
  cancelUploadById(fileId);
@@ -427091,20 +427600,20 @@ const ProgressMask = (param)=>{
427091
427600
 
427092
427601
 
427093
427602
 
427603
+ // import { IconRefresh } from '@coze-arch/bot-icons';
427094
427604
 
427095
427605
 
427096
427606
 
427097
427607
 
427098
-
427099
-
427608
+ // import { useRetryUpload } from '../../../hooks/file/use-upload';
427100
427609
 
427101
427610
 
427102
427611
  const CommonFile = (param)=>{
427103
427612
  let { file, status, percent, id, className, uri, url } = param;
427104
427613
  const ref = (0,react_.useRef)(null);
427105
427614
  const isHover = useHover_(ref);
427106
- const retryUpload = useRetryUpload();
427107
- const onRetry = ()=>retryUpload(id, file);
427615
+ // const retryUpload = useRetryUpload();
427616
+ // const onRetry = () => retryUpload(id, file);
427108
427617
  const isError = status === types_FileStatus.Error;
427109
427618
  const isSuccess = status === types_FileStatus.Success;
427110
427619
  const fileTypeConfig = getFileTypConfig(file);
@@ -427188,15 +427697,6 @@ const CommonFile = (param)=>{
427188
427697
  }) : null
427189
427698
  ]
427190
427699
  }),
427191
- isError ? /*#__PURE__*/ (0,jsx_runtime_.jsx)(ui_button_Button, {
427192
- icon: /*#__PURE__*/ (0,jsx_runtime_.jsx)(IconRefresh, {}),
427193
- onClick: (e)=>{
427194
- e.stopPropagation();
427195
- onRetry();
427196
- },
427197
- theme: "borderless",
427198
- className: batch_upload_file_list_common_file_index_module_["retry-button"]
427199
- }) : null,
427200
427700
  isSuccess ? /*#__PURE__*/ (0,jsx_runtime_.jsx)(esm_webpack_exports_Tooltip, {
427201
427701
  content: "预览",
427202
427702
  theme: "light",
@@ -427754,500 +428254,6 @@ const DELAY_TIME = 150;
427754
428254
  };
427755
428255
  };
427756
428256
 
427757
- ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/public/use-latest-section-id.ts
427758
- /*
427759
- * Copyright 2025 coze-dev Authors
427760
- *
427761
- * Licensed under the Apache License, Version 2.0 (the "License");
427762
- * you may not use this file except in compliance with the License.
427763
- * You may obtain a copy of the License at
427764
- *
427765
- * http://www.apache.org/licenses/LICENSE-2.0
427766
- *
427767
- * Unless required by applicable law or agreed to in writing, software
427768
- * distributed under the License is distributed on an "AS IS" BASIS,
427769
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
427770
- * See the License for the specific language governing permissions and
427771
- * limitations under the License.
427772
- */
427773
- const use_latest_section_id_useLatestSectionId = ()=>{
427774
- const { useSectionIdStore } = use_chat_area_context_useChatAreaStoreSet();
427775
- const latestSectionId = useSectionIdStore((state)=>state.latestSectionId);
427776
- return latestSectionId;
427777
- };
427778
-
427779
- ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/context/use-conversation-id.ts
427780
- /*
427781
- * Copyright 2025 coze-dev Authors
427782
- *
427783
- * Licensed under the Apache License, Version 2.0 (the "License");
427784
- * you may not use this file except in compliance with the License.
427785
- * You may obtain a copy of the License at
427786
- *
427787
- * http://www.apache.org/licenses/LICENSE-2.0
427788
- *
427789
- * Unless required by applicable law or agreed to in writing, software
427790
- * distributed under the License is distributed on an "AS IS" BASIS,
427791
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
427792
- * See the License for the specific language governing permissions and
427793
- * limitations under the License.
427794
- */
427795
-
427796
-
427797
- const useConversationId = ()=>{
427798
- const chatAreaStoreSetContext = use_chat_area_context_useChatAreaStoreSet();
427799
- if (!is_valid_context_isValidContext(chatAreaStoreSetContext)) throw new Error("chatAreaStoreSetContext is not valid");
427800
- const { useGlobalInitStore } = chatAreaStoreSetContext;
427801
- const conversationId = useGlobalInitStore((state)=>state.conversationId);
427802
- return conversationId;
427803
- };
427804
-
427805
- ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/file/use-upload-to-knowledge.ts
427806
- /*
427807
- * Copyright 2025 coze-dev Authors
427808
- *
427809
- * Licensed under the Apache License, Version 2.0 (the "License");
427810
- * you may not use this file except in compliance with the License.
427811
- * You may obtain a copy of the License at
427812
- *
427813
- * http://www.apache.org/licenses/LICENSE-2.0
427814
- *
427815
- * Unless required by applicable law or agreed to in writing, software
427816
- * distributed under the License is distributed on an "AS IS" BASIS,
427817
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
427818
- * See the License for the specific language governing permissions and
427819
- * limitations under the License.
427820
- */ /* eslint-disable max-lines -- This file contains complex upload logic that requires many lines */
427821
-
427822
-
427823
-
427824
- // Try to import from open-chat if available
427825
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
427826
- let use_upload_to_knowledge_useChatAppProps = null;
427827
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
427828
- let use_upload_to_knowledge_useChatCozeSdk = null;
427829
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
427830
- let use_upload_to_knowledge_useChatAppStore = null;
427831
- // Try to import updateCurrentConversationInfo from open-chat if available
427832
- // Note: This variable is currently unused but kept for future use
427833
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
427834
- const use_upload_to_knowledge_updateCurrentConversationInfo = null;
427835
- let use_upload_to_knowledge_createConversationForMessage = null;
427836
- try {
427837
- // eslint-disable-next-line @typescript-eslint/no-require-imports
427838
- const openChatModule = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module '@coze-studio/open-chat'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
427839
- if (openChatModule.useChatAppProps) use_upload_to_knowledge_useChatAppProps = openChatModule.useChatAppProps;
427840
- if (openChatModule.useChatCozeSdk) use_upload_to_knowledge_useChatCozeSdk = openChatModule.useChatCozeSdk;
427841
- if (openChatModule.useChatAppStore) use_upload_to_knowledge_useChatAppStore = openChatModule.useChatAppStore;
427842
- // Try to get updateCurrentConversationInfo from store
427843
- try {
427844
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
427845
- const storeHook = openChatModule.useChatAppStore;
427846
- storeHook && typeof storeHook;
427847
- } catch (error) {
427848
- // Store not available
427849
- error;
427850
- }
427851
- // eslint-disable-next-line @typescript-eslint/no-require-imports
427852
- const createConversationModule = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module '@coze-studio/open-chat/chat/builder-chat/services/create-conversation'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
427853
- if (createConversationModule.createConversationForMessage) use_upload_to_knowledge_createConversationForMessage = createConversationModule.createConversationForMessage;
427854
- } catch (error) {
427855
- // Module not available, hooks will be null
427856
- error;
427857
- }
427858
- var use_upload_to_knowledge_FileProcessStatus;
427859
- (function(FileProcessStatus) {
427860
- FileProcessStatus[FileProcessStatus["Processing"] = 1] = "Processing";
427861
- FileProcessStatus[FileProcessStatus["Completed"] = 2] = "Completed";
427862
- FileProcessStatus[FileProcessStatus["Failed"] = 3] = "Failed";
427863
- FileProcessStatus[FileProcessStatus["NotFound"] = -1] = "NotFound";
427864
- })(use_upload_to_knowledge_FileProcessStatus || (use_upload_to_knowledge_FileProcessStatus = {}));
427865
- /**
427866
- * Query file processing status
427867
- * @param params Query parameters
427868
- * @returns File status items or null if query failed
427869
- */ async function queryFileStatus(params) {
427870
- const { apiUrl, token, appId, conversationId, sectionId, knowledgeId, docIds } = params;
427871
- try {
427872
- const requestBody = {
427873
- app_id: appId,
427874
- conversation_id: conversationId,
427875
- section_id: sectionId,
427876
- knowledge_id: knowledgeId,
427877
- doc_ids: docIds
427878
- };
427879
- const apiEndpoint = `${apiUrl}/v1/workflows/conversation/file/status`;
427880
- const response = await fetch(apiEndpoint, {
427881
- method: "POST",
427882
- headers: {
427883
- "Content-Type": "application/json",
427884
- Authorization: `Bearer ${token}`
427885
- },
427886
- body: JSON.stringify(requestBody)
427887
- });
427888
- const result = await response.json();
427889
- if (result.code === 0 && result.data) {
427890
- // Log status for each file
427891
- result.data.forEach((item)=>{
427892
- const statusText = item.status === 1 ? "处理中" : item.status === 2 ? "已完成" : item.status === 3 ? "处理失败" : item.status === -1 ? "文件不存在或异常" : `未知状态(${item.status})`;
427893
- console.log(`File ${item.file_id} status: ${statusText}`, {
427894
- file_id: item.file_id,
427895
- status: item.status,
427896
- message: item.message
427897
- });
427898
- });
427899
- return result.data;
427900
- } else {
427901
- console.error("Failed to query file status:", result.msg || "Unknown error");
427902
- return null;
427903
- }
427904
- } catch (error) {
427905
- console.error("Error querying file status:", error);
427906
- return null;
427907
- }
427908
- }
427909
- /**
427910
- * Poll file status until completion or failure
427911
- * @param params Query parameters
427912
- * @param options Polling options
427913
- * @returns Final file status items or null if polling failed
427914
- */ async function pollFileStatus(params) {
427915
- let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
427916
- const { maxAttempts = 30, intervalMs = 2000 } = options;
427917
- let attempts = 0;
427918
- while(attempts < maxAttempts){
427919
- const statusResult = await queryFileStatus(params);
427920
- if (!statusResult || statusResult.length === 0) {
427921
- attempts++;
427922
- if (attempts >= maxAttempts) {
427923
- console.warn("File status polling reached max attempts");
427924
- return null;
427925
- }
427926
- await new Promise((resolve)=>setTimeout(resolve, intervalMs));
427927
- continue;
427928
- }
427929
- // Check if all files are in final state (completed, failed, or not found)
427930
- const allFinal = statusResult.every((item)=>item.status === 2 || item.status === 3 || item.status === -1);
427931
- if (allFinal) return statusResult;
427932
- // Some files are still processing, wait and retry
427933
- attempts++;
427934
- if (attempts >= maxAttempts) {
427935
- console.warn("File status polling reached max attempts, some files may still be processing");
427936
- return statusResult;
427937
- }
427938
- await new Promise((resolve)=>setTimeout(resolve, intervalMs));
427939
- }
427940
- return null;
427941
- }
427942
- /**
427943
- * Hook to upload file to knowledge base
427944
- */ // eslint-disable-next-line @coze-arch/max-line-per-function
427945
- const useUploadToKnowledge = (config)=>{
427946
- const conversationId = useConversationId();
427947
- const sectionId = use_latest_section_id_useLatestSectionId();
427948
- const storeSet = use_chat_area_context_useChatAreaStoreSet();
427949
- const { useGlobalInitStore, useSectionIdStore } = storeSet;
427950
- // Get setLatestSectionId from the store
427951
- // Always call the hook to satisfy React Hooks rules
427952
- // useChatAreaStoreSet() throws if context is invalid, so useSectionIdStore is always defined
427953
- const setLatestSectionId = useSectionIdStore((state)=>state.setLatestSectionId);
427954
- // Try to get apiUrl from useChatAppStore as fallback
427955
- let apiUrlFromStore;
427956
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
427957
- const chatAppStoreHook = use_upload_to_knowledge_useChatAppStore;
427958
- if (chatAppStoreHook && typeof chatAppStoreHook === "function") try {
427959
- apiUrlFromStore = chatAppStoreHook((state)=>state.apiUrl);
427960
- } catch (error) {
427961
- // Store not available
427962
- error;
427963
- }
427964
- const uploadFileToKnowledge = (0,react_.useCallback)(// eslint-disable-next-line @coze-arch/max-line-per-function, max-lines-per-function, complexity -- uploadFileToKnowledge requires many lines for complete file upload functionality
427965
- async (file)=>{
427966
- try {
427967
- var _chatConfig_appInfo, _chatConfig_auth;
427968
- let chatConfig;
427969
- let cozeApiSdk;
427970
- // Use config from props first, then try to get from hooks, then fallback to store
427971
- let apiUrl = (config === null || config === void 0 ? void 0 : config.apiUrl) || apiUrlFromStore;
427972
- let appId = config === null || config === void 0 ? void 0 : config.appId;
427973
- let token = config === null || config === void 0 ? void 0 : config.token;
427974
- let workflowId = config === null || config === void 0 ? void 0 : config.workflowId;
427975
- let draftMode = config === null || config === void 0 ? void 0 : config.draftMode;
427976
- let conversationName = config === null || config === void 0 ? void 0 : config.conversationName;
427977
- let connectorId = config === null || config === void 0 ? void 0 : config.connectorId;
427978
- let chatType = config === null || config === void 0 ? void 0 : config.chatType;
427979
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useChatAppProps may not be available in all contexts
427980
- const chatAppPropsHook = use_upload_to_knowledge_useChatAppProps;
427981
- if (chatAppPropsHook && typeof chatAppPropsHook === "function") try {
427982
- const chatAppProps = chatAppPropsHook();
427983
- chatConfig = chatAppProps === null || chatAppProps === void 0 ? void 0 : chatAppProps.chatConfig;
427984
- // Use values from hook if not provided in config
427985
- if (!apiUrl) {
427986
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useChatAppStore may not be available in all contexts
427987
- const storeHook = use_upload_to_knowledge_useChatAppStore;
427988
- if (storeHook && typeof storeHook === "function") try {
427989
- apiUrl = storeHook((state)=>state.apiUrl) || apiUrl;
427990
- } catch (error) {
427991
- // Store not available
427992
- error;
427993
- }
427994
- }
427995
- // Fill in missing values from chatConfig if not in config
427996
- if (!appId) {
427997
- var _chatConfig_appInfo1;
427998
- appId = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo1 = chatConfig.appInfo) === null || _chatConfig_appInfo1 === void 0 ? void 0 : _chatConfig_appInfo1.appId) || (chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.bot_id);
427999
- }
428000
- if (!token) {
428001
- var _chatConfig_auth1;
428002
- token = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth1 = chatConfig.auth) === null || _chatConfig_auth1 === void 0 ? void 0 : _chatConfig_auth1.token;
428003
- }
428004
- if (!workflowId) {
428005
- var _chatConfig_appInfo2;
428006
- workflowId = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo2 = chatConfig.appInfo) === null || _chatConfig_appInfo2 === void 0 ? void 0 : _chatConfig_appInfo2.workflowId;
428007
- }
428008
- if (draftMode === undefined) {
428009
- var _chatConfig_appInfo3;
428010
- draftMode = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo3 = chatConfig.appInfo) === null || _chatConfig_appInfo3 === void 0 ? void 0 : _chatConfig_appInfo3.draft_mode;
428011
- }
428012
- if (!conversationName) {
428013
- var _chatConfig_appInfo4;
428014
- conversationName = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo4 = chatConfig.appInfo) === null || _chatConfig_appInfo4 === void 0 ? void 0 : _chatConfig_appInfo4.conversationName;
428015
- }
428016
- if (!connectorId) {
428017
- var _chatConfig_auth2;
428018
- connectorId = chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth2 = chatConfig.auth) === null || _chatConfig_auth2 === void 0 ? void 0 : _chatConfig_auth2.connectorId;
428019
- }
428020
- if (!chatType) chatType = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.type;
428021
- } catch (error) {
428022
- // Hook not available in this context
428023
- error;
428024
- }
428025
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useChatCozeSdk may not be available in all contexts
428026
- const chatCozeSdkHook = use_upload_to_knowledge_useChatCozeSdk;
428027
- if (chatCozeSdkHook && typeof chatCozeSdkHook === "function") try {
428028
- const chatCozeSdk = chatCozeSdkHook();
428029
- cozeApiSdk = chatCozeSdk === null || chatCozeSdk === void 0 ? void 0 : chatCozeSdk.cozeApiSdk;
428030
- } catch (error1) {
428031
- // Hook not available in this context
428032
- error1;
428033
- }
428034
- // Check if we have minimum required info (apiUrl and appId)
428035
- // We can work without chatConfig and cozeApiSdk if config is provided
428036
- if (!apiUrl || !appId) {
428037
- console.warn("Cannot upload to knowledge: apiUrl or appId is missing");
428038
- return null;
428039
- }
428040
- // If we don't have chatConfig, create a minimal one from config
428041
- if (!chatConfig) chatConfig = {
428042
- type: chatType,
428043
- appInfo: {
428044
- appId,
428045
- workflowId,
428046
- draft_mode: draftMode,
428047
- conversationName
428048
- },
428049
- bot_id: appId,
428050
- auth: {
428051
- token,
428052
- connectorId
428053
- }
428054
- };
428055
- // 1. Get or create conversation
428056
- let currentConversationId = conversationId || "";
428057
- let currentSectionId = sectionId || "";
428058
- // If no conversation, create one
428059
- if (!currentConversationId) {
428060
- var _chatConfig_appInfo5, _chatConfig_appInfo6, _chatConfig_appInfo7, _chatConfig_appInfo8, _chatConfig_auth3, _chatConfig_auth4;
428061
- const finalAppId = appId || ((_chatConfig_appInfo5 = chatConfig.appInfo) === null || _chatConfig_appInfo5 === void 0 ? void 0 : _chatConfig_appInfo5.appId) || chatConfig.bot_id || "";
428062
- if (!finalAppId) {
428063
- console.error("Cannot upload to knowledge: app_id is missing");
428064
- return null;
428065
- }
428066
- const projectType = (chatType || chatConfig.type) === "app" ? "app" : "bot";
428067
- const finalWorkflowId = workflowId || ((_chatConfig_appInfo6 = chatConfig.appInfo) === null || _chatConfig_appInfo6 === void 0 ? void 0 : _chatConfig_appInfo6.workflowId);
428068
- const finalDraftMode = draftMode !== undefined ? draftMode : (_chatConfig_appInfo7 = chatConfig.appInfo) === null || _chatConfig_appInfo7 === void 0 ? void 0 : _chatConfig_appInfo7.draft_mode;
428069
- const finalConversationName = conversationName || ((_chatConfig_appInfo8 = chatConfig.appInfo) === null || _chatConfig_appInfo8 === void 0 ? void 0 : _chatConfig_appInfo8.conversationName);
428070
- const finalConnectorId = connectorId || ((_chatConfig_auth3 = chatConfig.auth) === null || _chatConfig_auth3 === void 0 ? void 0 : _chatConfig_auth3.connectorId);
428071
- const finalToken = token || ((_chatConfig_auth4 = chatConfig.auth) === null || _chatConfig_auth4 === void 0 ? void 0 : _chatConfig_auth4.token) || "";
428072
- // Try to use createConversationForMessage if available
428073
- if (use_upload_to_knowledge_createConversationForMessage && cozeApiSdk) try {
428074
- const conversationResult = await use_upload_to_knowledge_createConversationForMessage(cozeApiSdk, {
428075
- projectType,
428076
- projectId: finalAppId,
428077
- workflowId: finalWorkflowId,
428078
- mode: finalDraftMode ? "draft" : "release",
428079
- conversationName: finalConversationName,
428080
- connectorId: finalConnectorId
428081
- });
428082
- currentConversationId = conversationResult.conversationId;
428083
- currentSectionId = conversationResult.sectionId;
428084
- } catch (error) {
428085
- console.warn("Failed to create conversation using createConversationForMessage:", error);
428086
- // Fall through to direct API call
428087
- }
428088
- // If createConversationForMessage failed or is not available, use direct API call
428089
- // Note: finalApiUrl is defined later in the code, so we use apiUrl here
428090
- if (!currentConversationId && apiUrl && finalToken) try {
428091
- let createUrl = "";
428092
- let createPayload = {};
428093
- if (projectType === "bot") {
428094
- createUrl = `${apiUrl}/v1/conversations/create`;
428095
- createPayload = {
428096
- connector_id: finalConnectorId
428097
- };
428098
- } else {
428099
- createUrl = `${apiUrl}/v1/workflow/conversation/create`;
428100
- createPayload = {
428101
- app_id: finalAppId,
428102
- draft_mode: finalDraftMode || false,
428103
- workflow_id: finalWorkflowId || "",
428104
- connector_id: finalConnectorId
428105
- };
428106
- // Only add get_or_create if conversationName is provided
428107
- if (finalConversationName && finalConversationName.trim() !== "") {
428108
- createPayload.get_or_create = true;
428109
- createPayload.conversation_name = finalConversationName;
428110
- }
428111
- }
428112
- const createResponse = await fetch(createUrl, {
428113
- method: "POST",
428114
- headers: {
428115
- "Content-Type": "application/json",
428116
- Authorization: `Bearer ${finalToken}`,
428117
- "Accept-Language": "en"
428118
- },
428119
- body: JSON.stringify(createPayload)
428120
- });
428121
- const createResult = await createResponse.json();
428122
- if (createResult.code === 0 && createResult.data) {
428123
- currentConversationId = createResult.data.id || "";
428124
- currentSectionId = createResult.data.last_section_id || "";
428125
- } else {
428126
- console.error("Failed to create conversation:", createResult.msg || "Unknown error");
428127
- return null;
428128
- }
428129
- } catch (error1) {
428130
- console.error("Error creating conversation:", error1);
428131
- return null;
428132
- }
428133
- // Update conversation ID in chat area
428134
- if (currentConversationId) {
428135
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useGlobalInitStore type may vary by context
428136
- const globalStore = useGlobalInitStore;
428137
- if (globalStore && typeof globalStore.getState === "function") {
428138
- const { setConversationId } = globalStore.getState();
428139
- setConversationId(currentConversationId);
428140
- }
428141
- if (currentSectionId && setLatestSectionId) setLatestSectionId(currentSectionId);
428142
- // Also update currentConversationInfo in store so text messages can use it
428143
- // First try to use the callback from config (preferred method)
428144
- if (config === null || config === void 0 ? void 0 : config.updateCurrentConversationInfo) try {
428145
- // Delay updating currentConversationInfo to ensure file message is displayed first
428146
- // This prevents chatarea from refreshing before the file message is added to the store
428147
- // Use requestAnimationFrame + setTimeout to ensure file message is fully rendered and saved
428148
- const DELAY_MS = 200; // Increased delay to ensure file message is fully saved to store
428149
- requestAnimationFrame(()=>{
428150
- setTimeout(()=>{
428151
- if (config.updateCurrentConversationInfo) config.updateCurrentConversationInfo({
428152
- id: currentConversationId,
428153
- last_section_id: currentSectionId
428154
- });
428155
- }, DELAY_MS);
428156
- });
428157
- } catch (error) {
428158
- console.warn("Failed to schedule updateCurrentConversationInfo:", error);
428159
- }
428160
- else {
428161
- // Fallback: try to use dynamically imported hook (may not work in callbacks)
428162
- // Note: This is a fallback that may not work in callbacks
428163
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- fallback hook may not be available
428164
- const storeHook = use_upload_to_knowledge_useChatAppStore;
428165
- }
428166
- }
428167
- }
428168
- if (!currentConversationId || !currentSectionId) {
428169
- console.error("Cannot upload to knowledge: conversation_id or section_id is missing");
428170
- return null;
428171
- }
428172
- // 2. Prepare FormData
428173
- const formData = new FormData();
428174
- formData.append("file", file);
428175
- formData.append("app_id", appId || ((_chatConfig_appInfo = chatConfig.appInfo) === null || _chatConfig_appInfo === void 0 ? void 0 : _chatConfig_appInfo.appId) || chatConfig.bot_id || "");
428176
- formData.append("conversation_id", currentConversationId);
428177
- formData.append("section_id", currentSectionId);
428178
- // 3. Call upload API
428179
- // Use apiUrl from config, store, or from cozeApiSdk
428180
- const finalApiUrl = apiUrl || (cozeApiSdk === null || cozeApiSdk === void 0 ? void 0 : cozeApiSdk.baseURL) || "";
428181
- const finalToken = token || ((_chatConfig_auth = chatConfig.auth) === null || _chatConfig_auth === void 0 ? void 0 : _chatConfig_auth.token) || "";
428182
- if (!finalApiUrl) {
428183
- console.error("Cannot upload to knowledge: API URL is missing");
428184
- return null;
428185
- }
428186
- // Use fetch to upload file
428187
- const apiEndpoint = `${finalApiUrl}/v1/workflows/conversation/file/toKnowledge`;
428188
- const response = await fetch(apiEndpoint, {
428189
- method: "POST",
428190
- headers: {
428191
- Authorization: `Bearer ${finalToken}`
428192
- },
428193
- body: formData
428194
- });
428195
- const result = await response.json();
428196
- if (result.code === 0 && result.data) {
428197
- var _chatConfig_appInfo9;
428198
- // Response data includes: url, uri, bytes, CreatedAt, file_name, id, doc_id, knowledge_id
428199
- console.log("File uploaded to knowledge successfully:", {
428200
- url: result.data.url,
428201
- uri: result.data.uri,
428202
- file_name: result.data.file_name,
428203
- id: result.data.id,
428204
- doc_id: result.data.doc_id,
428205
- knowledge_id: result.data.knowledge_id,
428206
- bytes: result.data.bytes,
428207
- CreatedAt: result.data.CreatedAt
428208
- });
428209
- // 4. Query file status after upload (poll until completion or failure)
428210
- const statusResult = await pollFileStatus({
428211
- apiUrl: finalApiUrl,
428212
- token: finalToken,
428213
- appId: appId || ((_chatConfig_appInfo9 = chatConfig.appInfo) === null || _chatConfig_appInfo9 === void 0 ? void 0 : _chatConfig_appInfo9.appId) || chatConfig.bot_id || "",
428214
- conversationId: currentConversationId,
428215
- sectionId: currentSectionId,
428216
- knowledgeId: result.data.knowledge_id,
428217
- docIds: [
428218
- result.data.doc_id
428219
- ]
428220
- }, {
428221
- maxAttempts: 30,
428222
- intervalMs: 2000
428223
- });
428224
- if (statusResult) {
428225
- // Check if file processing failed
428226
- const failedFile = statusResult.find((item)=>item.status === 3);
428227
- if (failedFile) console.error(`File processing failed: ${failedFile.message}`, failedFile);
428228
- }
428229
- return result.data;
428230
- } else {
428231
- console.error("Failed to upload file to knowledge:", result.msg || "Unknown error");
428232
- return null;
428233
- }
428234
- } catch (error) {
428235
- console.error("Error uploading file to knowledge:", error);
428236
- return null;
428237
- }
428238
- }, [
428239
- conversationId,
428240
- sectionId,
428241
- setLatestSectionId,
428242
- useGlobalInitStore,
428243
- apiUrlFromStore,
428244
- config
428245
- ]);
428246
- return {
428247
- uploadFileToKnowledge
428248
- };
428249
- };
428250
-
428251
428257
  ;// CONCATENATED MODULE: ../../../common/chat-area/chat-area/src/hooks/file/use-paste-upload.ts
428252
428258
  /*
428253
428259
  * Copyright 2025 coze-dev Authors
@@ -428397,6 +428403,7 @@ var components_chat_input_index_module_update = injectStylesIntoStyleTag_default
428397
428403
 
428398
428404
 
428399
428405
 
428406
+
428400
428407
 
428401
428408
 
428402
428409
  const ChatInputArea = /*#__PURE__*/ (0,react_.forwardRef)((_, ref)=>{
@@ -428535,29 +428542,52 @@ const chat_input_ChatInput = /*#__PURE__*/ (0,react_.forwardRef)((props, ref)=>{
428535
428542
  return;
428536
428543
  }
428537
428544
  // 如果是非图片文件且 uploadToKnowledge 启用,上传到知识库
428538
- if (uploadToKnowledge) try {
428539
- // Add file to BatchUploadFileList (display above input) instead of sending as message
428540
- // This matches the behavior of normal file uploads
428541
- const { immerCreateFileData } = useBatchFileUploadStore.getState();
428542
- const fileId = index_browser_nanoid();
428543
- immerCreateFileData(fileId, payload.file);
428544
- // Now upload to knowledge (this will create conversation and update currentConversationInfo)
428545
- // The update is delayed to prevent chatarea refresh before file is displayed
428546
- const uploadResult = await uploadFileToKnowledge(payload.file);
428547
- // Update file status based on upload result
428548
- const { immerUpdateFileDataById } = useBatchFileUploadStore.getState();
428549
- if (uploadResult) // Upload successful, mark as success and save uri and fileId from response
428550
- immerUpdateFileDataById(fileId, (data)=>{
428551
- data.status = types_FileStatus.Success;
428552
- data.percent = 100;
428553
- // Save uri, fileId, and knowledge_id from API response for sending messages
428554
- data.uri = uploadResult.uri;
428555
- data.fileId = uploadResult.id;
428556
- data.url = uploadResult.url;
428557
- data.knowledge_id = uploadResult.knowledge_id;
428558
- });
428559
- else {
428560
- // Upload failed, mark as error and show toast
428545
+ if (uploadToKnowledge) {
428546
+ let fileId;
428547
+ try {
428548
+ // Add file to BatchUploadFileList (display above input) instead of sending as message
428549
+ const { immerCreateFileData } = useBatchFileUploadStore.getState();
428550
+ fileId = index_browser_nanoid();
428551
+ immerCreateFileData(fileId, payload.file);
428552
+ // Now upload to knowledge (this will create conversation and update currentConversationInfo)
428553
+ // The update is delayed to prevent chatarea refresh before file is displayed
428554
+ const uploadResult = await uploadFileToKnowledge(payload.file, {
428555
+ fileId
428556
+ });
428557
+ // Update file status based on upload result(若用户已删除该文件则不再更新,也不提示失败)
428558
+ const storeState = useBatchFileUploadStore.getState();
428559
+ const fileStillExists = storeState.fileIdList.includes(fileId);
428560
+ if (!fileStillExists) return;
428561
+ const { immerUpdateFileDataById } = storeState;
428562
+ if (uploadResult) // Upload successful, mark as success and save uri and fileId from response
428563
+ immerUpdateFileDataById(fileId, (data)=>{
428564
+ data.status = types_FileStatus.Success;
428565
+ data.percent = 100;
428566
+ // Save uri, fileId, and knowledge_id from API response for sending messages
428567
+ data.uri = uploadResult.uri;
428568
+ data.fileId = uploadResult.id;
428569
+ data.url = uploadResult.url;
428570
+ data.knowledge_id = uploadResult.knowledge_id;
428571
+ });
428572
+ else {
428573
+ // Upload failed, mark as error and show toast
428574
+ immerUpdateFileDataById(fileId, (data)=>{
428575
+ data.status = types_FileStatus.Error;
428576
+ data.percent = 0;
428577
+ });
428578
+ esm_webpack_exports_Toast.error({
428579
+ content: "上传文件到知识库失败,请重试",
428580
+ showClose: false
428581
+ });
428582
+ }
428583
+ return;
428584
+ } catch (error) {
428585
+ console.error("Failed to upload file to knowledge:", error);
428586
+ // 若用户已删除该文件(store 中不存在),不再重新创建并展示错误
428587
+ const storeState = useBatchFileUploadStore.getState();
428588
+ if (fileId === undefined || !storeState.fileIdList.includes(fileId)) return;
428589
+ // 上传异常时仅把当前文件标为错误,不重复创建新文件
428590
+ const { immerUpdateFileDataById } = storeState;
428561
428591
  immerUpdateFileDataById(fileId, (data)=>{
428562
428592
  data.status = types_FileStatus.Error;
428563
428593
  data.percent = 0;
@@ -428566,25 +428596,8 @@ const chat_input_ChatInput = /*#__PURE__*/ (0,react_.forwardRef)((props, ref)=>{
428566
428596
  content: "上传文件到知识库失败,请重试",
428567
428597
  showClose: false
428568
428598
  });
428599
+ return;
428569
428600
  }
428570
- return;
428571
- } catch (error) {
428572
- console.error("Failed to upload file to knowledge:", error);
428573
- // Even on error, show file in BatchUploadFileList so user can see what was attempted
428574
- // Add file to BatchUploadFileList (display above input) instead of sending as message
428575
- const { immerCreateFileData, immerUpdateFileDataById } = useBatchFileUploadStore.getState();
428576
- const fileId = index_browser_nanoid();
428577
- immerCreateFileData(fileId, payload.file);
428578
- // Mark file as error and show toast
428579
- immerUpdateFileDataById(fileId, (data)=>{
428580
- data.status = types_FileStatus.Error;
428581
- data.percent = 0;
428582
- });
428583
- esm_webpack_exports_Toast.error({
428584
- content: "上传文件到知识库失败,请重试",
428585
- showClose: false
428586
- });
428587
- return;
428588
428601
  }
428589
428602
  // Then proceed with normal upload (only if uploadToKnowledge is false)
428590
428603
  if (enableMultimodalUpload) {
@@ -438426,7 +438439,7 @@ var conversation_list_index_module_update = injectStylesIntoStyleTag_default()(c
438426
438439
 
438427
438440
  const ConversationList = /*#__PURE__*/ (0,react_.forwardRef)(// eslint-disable-next-line @coze-arch/max-line-per-function
438428
438441
  (param, ref)=>{
438429
- let { onRename, onDelete, loading, groupedConversations, conversations, hasMore, loadMore, removeConversation } = param;
438442
+ let { onRename, onDelete, onConversationKeyChange, loading, groupedConversations, conversations, hasMore, loadMore, removeConversation } = param;
438430
438443
  const { currentConversationInfo, updateCurrentConversationInfo, cozeApi, updateConversations } = context_useChatAppStore(shallow_useShallow((state)=>({
438431
438444
  currentConversationInfo: state.currentConversationInfo,
438432
438445
  updateCurrentConversationInfo: state.updateCurrentConversationInfo,
@@ -438485,6 +438498,7 @@ const ConversationList = /*#__PURE__*/ (0,react_.forwardRef)(// eslint-disable-n
438485
438498
  // 更新当前会话信息为空会话,这会触发 chat-area 重新初始化
438486
438499
  updateCurrentConversationInfo(emptyConversationInfo);
438487
438500
  conversationRef.current = emptyConversationInfo;
438501
+ onConversationKeyChange === null || onConversationKeyChange === void 0 || onConversationKeyChange("empty");
438488
438502
  } catch (error) {
438489
438503
  console.error(error);
438490
438504
  } finally{
@@ -438512,6 +438526,7 @@ const ConversationList = /*#__PURE__*/ (0,react_.forwardRef)(// eslint-disable-n
438512
438526
  };
438513
438527
  conversationRef.current = c;
438514
438528
  updateCurrentConversationInfo(c);
438529
+ onConversationKeyChange === null || onConversationKeyChange === void 0 || onConversationKeyChange(conversation.id);
438515
438530
  return;
438516
438531
  }
438517
438532
  // 如果会话ID相同,检查是否真的需要更新(避免不必要的重载)
@@ -438536,6 +438551,7 @@ const ConversationList = /*#__PURE__*/ (0,react_.forwardRef)(// eslint-disable-n
438536
438551
  console.log("handleConversationChange conversation2", c);
438537
438552
  conversationRef.current = c;
438538
438553
  updateCurrentConversationInfo(c);
438554
+ onConversationKeyChange === null || onConversationKeyChange === void 0 || onConversationKeyChange(conversation.id);
438539
438555
  return;
438540
438556
  }
438541
438557
  // 会话ID不同,正常更新
@@ -438557,6 +438573,7 @@ const ConversationList = /*#__PURE__*/ (0,react_.forwardRef)(// eslint-disable-n
438557
438573
  conversationRef.current = c;
438558
438574
  // 然后更新 currentConversationInfo,这会触发 openRequestInit 重新调用
438559
438575
  updateCurrentConversationInfo(c);
438576
+ onConversationKeyChange === null || onConversationKeyChange === void 0 || onConversationKeyChange(conversation.id);
438560
438577
  };
438561
438578
  const handleDeleteConversation = async (conversation)=>{
438562
438579
  try {
@@ -438774,6 +438791,12 @@ var conversation_list_sider_index_module_update = injectStylesIntoStyleTag_defau
438774
438791
  const groupedConversations = useGroupedConversations(conversations);
438775
438792
  const [isModalLoading, setIsModalLoading] = (0,react_.useState)(false);
438776
438793
  const [modalInfo, setModalInfo] = (0,react_.useState)(null);
438794
+ // 使用稳定 key,避免空会话下上传文件创建新会话时因 key 从 '' 变为 newId 导致整树 remount、上传列表被清空
438795
+ const [fragmentKey, setFragmentKey] = (0,react_.useState)(()=>(currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.id) ?? "empty");
438796
+ // 点击「新会话」时使用唯一 key 强制 remount,否则 fragmentKey 本就为 'empty' 不会 remount,空会话界面不展示
438797
+ const handleConversationKeyChange = (0,react_.useCallback)((key)=>{
438798
+ setFragmentKey((k)=>key === "empty" ? `empty-${Date.now()}` : key);
438799
+ }, []);
438777
438800
  const handleOpenRenameModal = (conversation)=>{
438778
438801
  if (!(conversation === null || conversation === void 0 ? void 0 : conversation.id)) {
438779
438802
  console.error("Cannot rename conversation: id is missing", conversation);
@@ -438899,6 +438922,7 @@ var conversation_list_sider_index_module_update = injectStylesIntoStyleTag_defau
438899
438922
  ref: conversationListRef,
438900
438923
  onRename: handleOpenRenameModal,
438901
438924
  onDelete: handleOpenDeleteModal,
438925
+ onConversationKeyChange: handleConversationKeyChange,
438902
438926
  loading: loading,
438903
438927
  groupedConversations: groupedConversations,
438904
438928
  conversations: conversations,
@@ -438908,7 +438932,7 @@ var conversation_list_sider_index_module_update = injectStylesIntoStyleTag_defau
438908
438932
  }) : null,
438909
438933
  /*#__PURE__*/ (0,jsx_runtime_.jsx)(react_.Fragment, {
438910
438934
  children: children
438911
- }, currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.id),
438935
+ }, fragmentKey),
438912
438936
  /*#__PURE__*/ (0,jsx_runtime_.jsx)(esm_webpack_exports_SideSheet, {
438913
438937
  visible: (currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.conversationListVisible) && !(currentConversationInfo === null || currentConversationInfo === void 0 ? void 0 : currentConversationInfo.isLargeWidth),
438914
438938
  closeIcon: /*#__PURE__*/ (0,jsx_runtime_.jsx)(__webpack_exports__IconCozSideNav, {}),
@@ -438930,6 +438954,7 @@ var conversation_list_sider_index_module_update = injectStylesIntoStyleTag_defau
438930
438954
  ref: conversationListRef,
438931
438955
  onRename: handleOpenRenameModal,
438932
438956
  onDelete: handleOpenDeleteModal,
438957
+ onConversationKeyChange: handleConversationKeyChange,
438933
438958
  loading: loading,
438934
438959
  groupedConversations: groupedConversations,
438935
438960
  conversations: conversations,
@@ -447131,7 +447156,7 @@ const use_request_init_getConversationInfo = async (param)=>{
447131
447156
  next_cursor: nextCursor
447132
447157
  };
447133
447158
  };
447134
- // 新增:获取当前 section 对应的知识库列表
447159
+ // 新增:获取当前 section 对应的知识库列表(供清除对话后刷新知识库使用)
447135
447160
  const getConversationKnowledges = async (param)=>{
447136
447161
  let { cozeApiSdk, conversationId, sectionId, appId } = param;
447137
447162
  if (!conversationId || !sectionId || !appId) return [];
@@ -449481,6 +449506,8 @@ class MessageParser {
449481
449506
  case "error":
449482
449507
  {
449483
449508
  const messageError = src_safe_json_parse_safeJSONParse(data);
449509
+ const hasExplicitError = (messageError === null || messageError === void 0 ? void 0 : messageError.code) !== undefined && (messageError === null || messageError === void 0 ? void 0 : messageError.code) !== 0 || (messageError === null || messageError === void 0 ? void 0 : messageError.msg) !== undefined && String(messageError.msg).trim() !== "";
449510
+ if (!hasExplicitError) return;
449484
449511
  const errorMsg = (messageError === null || messageError === void 0 ? void 0 : messageError.msg) || src_I18n.t("sendFailed");
449485
449512
  esm_webpack_exports_Toast.error(errorMsg);
449486
449513
  throw new Error("Chat stream error");
@@ -449971,10 +449998,12 @@ class MessageParser {
449971
449998
 
449972
449999
 
449973
450000
 
450001
+
450002
+
449974
450003
  /* eslint-disable @coze-arch/max-line-per-function -- This adapter function handles complex message sending logic */ const useSendMessageAdapter = (userInfo, refChatFunc)=>{
449975
450004
  var _chatConfig_auth;
449976
450005
  const { debug, chatConfig } = context_useChatAppProps();
449977
- const { shortcuts, apiUrl, updateConversations, updateCurrentConversationInfo, currentConversationInfo, conversations, cozeApi, conversationKnowledgeIds } = context_useChatAppStore(shallow_useShallow((state)=>({
450006
+ const { shortcuts, apiUrl, updateConversations, updateCurrentConversationInfo, currentConversationInfo, conversations, cozeApi, conversationKnowledgeIds, setConversationKnowledgeIds } = context_useChatAppStore(shallow_useShallow((state)=>({
449978
450007
  shortcuts: state.shortcuts,
449979
450008
  apiUrl: state.apiUrl,
449980
450009
  updateConversations: state.updateConversations,
@@ -449982,7 +450011,8 @@ class MessageParser {
449982
450011
  currentConversationInfo: state.currentConversationInfo,
449983
450012
  conversations: state.conversations,
449984
450013
  cozeApi: state.cozeApi,
449985
- conversationKnowledgeIds: state.conversationKnowledgeIds
450014
+ conversationKnowledgeIds: state.conversationKnowledgeIds,
450015
+ setConversationKnowledgeIds: state.setConversationKnowledgeIds
449986
450016
  })));
449987
450017
  // 从 context 获取 cozeApiSdk 作为备用
449988
450018
  const { cozeApiSdk } = context_useChatCozeSdk();
@@ -449999,6 +450029,8 @@ class MessageParser {
449999
450029
  refStore.current = storeInstance;
450000
450030
  // 保存新创建的 conversation 信息,以便在消息发送成功后更新状态
450001
450031
  const refPendingConversationInfo = (0,react_.useRef)(null);
450032
+ // 已因 DONE 返回过 synthetic ack 时置为 true,后续 ERROR 事件不再交给 parser(避免误报「发送失败」)
450033
+ const refStreamAlreadySucceeded = (0,react_.useRef)(false);
450002
450034
  // 新增:追踪最新的 conversationKnowledgeIds
450003
450035
  const refConversationKnowledgeIds = (0,react_.useRef)(conversationKnowledgeIds);
450004
450036
  shortcutsRef.current = shortcuts;
@@ -450182,6 +450214,7 @@ class MessageParser {
450182
450214
  sectionId: conversationResult.sectionId || "",
450183
450215
  conversationName: conversationResult.conversationName
450184
450216
  };
450217
+ refStreamAlreadySucceeded.current = false;
450185
450218
  // 立即添加会话到列表,使用创建时返回的名称
450186
450219
  const existingConversation = refConversations.current.find((c)=>c.id === conversationResult.conversationId);
450187
450220
  if (!existingConversation && refUpdateConversations.current) {
@@ -450205,20 +450238,32 @@ class MessageParser {
450205
450238
  conversationId: conversationResult.conversationId,
450206
450239
  conversationName: conversationResult.conversationName
450207
450240
  });
450241
+ // 立即更新 currentConversationInfo,使会话历史中新 item 显示选中样式(fragmentKey 已保证不会 remount)
450242
+ const existingInfo = refCurrentConversationInfo.current;
450243
+ refUpdateCurrentConversationInfo.current({
450244
+ ...existingInfo,
450245
+ id: conversationResult.conversationId,
450246
+ last_section_id: conversationResult.sectionId || "",
450247
+ name: conversationResult.conversationName || "",
450248
+ ...isAppType && {
450249
+ title: ""
450250
+ },
450251
+ created_at: newConversation.created_at,
450252
+ updated_at: newConversation.updated_at,
450253
+ meta_data: {},
450254
+ conversationListVisible: (existingInfo === null || existingInfo === void 0 ? void 0 : existingInfo.conversationListVisible) ?? false,
450255
+ isLargeWidth: (existingInfo === null || existingInfo === void 0 ? void 0 : existingInfo.isLargeWidth) ?? false
450256
+ });
450208
450257
  }
450209
- // 选中新创建的会话:先更新 currentConversationInfo,确保会话被选中
450210
- // 不立即调用 updateCurrentConversationInfo,避免触发组件卸载
450211
- // 将在消息流完成(DONE 事件)时更新 currentConversationInfo
450212
- // 这样可以避免触发 useRequestInit 的依赖变化,防止重新初始化
450213
- // 会话列表中的新会话已经通过 updateConversations 添加,可以正常显示
450214
- console.log("onBeforeSendMessage: Conversation created, will update currentConversationInfo after stream completes", {
450215
- conversationId: conversationResult.conversationId
450216
- });
450258
+ // 选中新创建的会话:currentConversationInfo 已在上方更新,会话列表会显示选中样式
450217
450259
  // 确保 pendingInfo 被设置,以便在 DONE 事件时更新
450218
- if (refPendingConversationInfo) refPendingConversationInfo.current = {
450219
- conversationId: conversationResult.conversationId,
450220
- sectionId: conversationResult.sectionId || ""
450221
- };
450260
+ if (refPendingConversationInfo) {
450261
+ refPendingConversationInfo.current = {
450262
+ conversationId: conversationResult.conversationId,
450263
+ sectionId: conversationResult.sectionId || ""
450264
+ };
450265
+ refStreamAlreadySucceeded.current = false;
450266
+ }
450222
450267
  // 注意:不在这里调用 setConversationId,因为它会触发额外的 updateConversations 调用
450223
450268
  // 这会导致 useConversationList 的同步逻辑被触发,设置 isSyncing = true
450224
450269
  // 当真正的 store 更新发生时,isSyncing 仍然是 true,导致 useEffect 被跳过
@@ -450289,8 +450334,18 @@ class MessageParser {
450289
450334
  ...configSetting,
450290
450335
  ...bodySetting
450291
450336
  };
450292
- // 新增:合并会话 section 关联的知识库 ID SETTING.KNOWLEDGE_IDS
450293
- // 直接从 store 获取最新值,避免 ref 因 React 渲染时机延迟导致数据不是最新
450337
+ // 提前解析 body 中的 knowledge_ids(文件上传等),与 store 一起参与 SETTING.KNOWLEDGE_IDS 合并
450338
+ const parsedBodyForKnowledge = catchParse(requestConfig.body) || {};
450339
+ let existingBodyKnowledgeIds = [];
450340
+ if (parsedBodyForKnowledge.knowledge_ids) existingBodyKnowledgeIds = Array.isArray(parsedBodyForKnowledge.knowledge_ids) ? parsedBodyForKnowledge.knowledge_ids.map(String) : typeof parsedBodyForKnowledge.knowledge_ids === "string" ? (()=>{
450341
+ try {
450342
+ return JSON.parse(parsedBodyForKnowledge.knowledge_ids);
450343
+ } catch {
450344
+ return [];
450345
+ }
450346
+ })() : [];
450347
+ // 合并会话 section 关联的知识库 ID 与本次 body 的 knowledge_ids 到 SETTING.KNOWLEDGE_IDS
450348
+ // 来源:mergedSetting 已有、store(ref)、body.knowledge_ids,保证第二次发送仍带上前一次的知识库
450294
450349
  let knowledgeIdsFromConversation = [];
450295
450350
  try {
450296
450351
  var _refStore_current;
@@ -450299,54 +450354,44 @@ class MessageParser {
450299
450354
  } catch {
450300
450355
  knowledgeIdsFromConversation = refConversationKnowledgeIds.current || [];
450301
450356
  }
450302
- if (knowledgeIdsFromConversation.length > 0) {
450303
- // 获取已有的 KNOWLEDGE_IDS
450304
- let existingIds = [];
450305
- if (mergedSetting.KNOWLEDGE_IDS) {
450306
- if (Array.isArray(mergedSetting.KNOWLEDGE_IDS)) existingIds = mergedSetting.KNOWLEDGE_IDS.map(String);
450307
- else if (typeof mergedSetting.KNOWLEDGE_IDS === "string") try {
450308
- existingIds = JSON.parse(mergedSetting.KNOWLEDGE_IDS);
450309
- } catch {
450310
- existingIds = [];
450311
- }
450357
+ let existingIds = [];
450358
+ if (mergedSetting.KNOWLEDGE_IDS) {
450359
+ if (Array.isArray(mergedSetting.KNOWLEDGE_IDS)) existingIds = mergedSetting.KNOWLEDGE_IDS.map(String);
450360
+ else if (typeof mergedSetting.KNOWLEDGE_IDS === "string") try {
450361
+ existingIds = JSON.parse(mergedSetting.KNOWLEDGE_IDS);
450362
+ } catch {
450363
+ existingIds = [];
450312
450364
  }
450313
- // 合并并去重
450314
- const allIds = [
450315
- ...existingIds,
450316
- ...knowledgeIdsFromConversation
450317
- ];
450318
- const uniqueIds = Array.from(new Set(allIds));
450319
- if (uniqueIds.length > 0) mergedSetting.KNOWLEDGE_IDS = uniqueIds;
450320
- console.log("onBeforeSendMessage: Merged conversation knowledge IDs into parameters", {
450321
- knowledgeIdsFromConversation,
450322
- existingIds,
450323
- uniqueIds
450324
- });
450325
450365
  }
450366
+ const allIds = [
450367
+ ...existingIds,
450368
+ ...knowledgeIdsFromConversation,
450369
+ ...existingBodyKnowledgeIds
450370
+ ];
450371
+ const uniqueIds = Array.from(new Set(allIds));
450372
+ if (uniqueIds.length > 0) {
450373
+ mergedSetting.KNOWLEDGE_IDS = uniqueIds;
450374
+ // 将本次请求使用的知识库 ID 同步到 store,保证下次发送(无 body knowledge_ids 时)仍能带上
450375
+ setConversationKnowledgeIds(uniqueIds);
450376
+ }
450377
+ if (uniqueIds.length > 0) console.log("onBeforeSendMessage: Merged conversation knowledge IDs into parameters", {
450378
+ knowledgeIdsFromConversation,
450379
+ existingBodyKnowledgeIds,
450380
+ existingIds,
450381
+ uniqueIds
450382
+ });
450326
450383
  // 将合并后的 SETTING 设回 parameters
450327
450384
  if (Object.keys(mergedSetting).length > 0) mergedParameters.SETTING = mergedSetting;
450328
450385
  console.log("onBeforeSendMessage: Final mergedParameters", mergedParameters);
450329
450386
  // 更新 requestConfig.body 中的 conversation_id
450330
450387
  // 同时将会话知识库 ID 写入 body 的 knowledge_ids 字段
450331
- // 这样 builder-chat 的 onBeforeSendMessage hook 可以从 body 中读取
450332
- // 并合并到最终的 parameters.SETTING.KNOWLEDGE_IDS
450333
- const parsedBody = catchParse(requestConfig.body) || {};
450334
- // 合并已有的 knowledge_ids(来自文件上传等)和会话知识库 ID
450335
- let existingBodyKnowledgeIds = [];
450336
- if (parsedBody.knowledge_ids) existingBodyKnowledgeIds = Array.isArray(parsedBody.knowledge_ids) ? parsedBody.knowledge_ids.map(String) : typeof parsedBody.knowledge_ids === "string" ? (()=>{
450337
- try {
450338
- return JSON.parse(parsedBody.knowledge_ids);
450339
- } catch {
450340
- return [];
450341
- }
450342
- })() : [];
450343
450388
  const combinedKnowledgeIds = [
450344
450389
  ...existingBodyKnowledgeIds,
450345
450390
  ...knowledgeIdsFromConversation
450346
450391
  ];
450347
450392
  const uniqueBodyKnowledgeIds = Array.from(new Set(combinedKnowledgeIds));
450348
450393
  const updatedBodyObj = {
450349
- ...parsedBody,
450394
+ ...parsedBodyForKnowledge,
450350
450395
  conversation_id: conversationId
450351
450396
  };
450352
450397
  // 只在有知识库 ID 时才添加 knowledge_ids 字段
@@ -450408,110 +450453,137 @@ class MessageParser {
450408
450453
  sectionId: refChatFunc === null || refChatFunc === void 0 ? void 0 : (_refChatFunc_current = refChatFunc.current) === null || _refChatFunc_current === void 0 ? void 0 : _refChatFunc_current.getSectionId(),
450409
450454
  onConversationUpdate: handleConversationUpdateRef.current || undefined
450410
450455
  });
450411
- // 如果有待更新的 conversation 信息,在收到第一条消息(CHAT_CREATED)时更新会话列表
450412
- // 在消息流完成(DONE)时更新 currentConversationInfo 和 chatCore 的 conversationId
450413
- if (refPendingConversationInfo.current && originalParser) {
450414
- let hasUpdatedConversationList = false;
450415
- let hasUpdatedChatCore = false;
450456
+ // pending 时在 CHAT_CREATED/DONE 时更新会话状态;每次 DONE 时都刷新知识库列表
450457
+ if (!originalParser) return undefined;
450458
+ let hasUpdatedConversationList = false;
450459
+ let hasUpdatedChatCore = false;
450460
+ return (parseEvent, method)=>{
450416
450461
  const pendingInfo = refPendingConversationInfo.current;
450417
- return (parseEvent, method)=>{
450418
- if (!originalParser) return undefined;
450419
- const result = originalParser(parseEvent, method);
450420
- // 检查事件类型
450421
- const { type, event } = parseEvent;
450422
- const isChatCreatedEvent = type === "event" && event === "conversation.chat.created";
450423
- const isDoneEvent = type === "event" && event === "done";
450424
- // 在收到第一条消息(CHAT_CREATED)时更新会话列表和 currentConversationInfo
450425
- // 更新 currentConversationInfo 以确保会话列表中的新会话显示为选中状态
450426
- // 只更新 id last_section_id,不更新 name,避免触发不必要的重新初始化
450427
- if (isChatCreatedEvent && !hasUpdatedConversationList && pendingInfo.conversationId) {
450428
- hasUpdatedConversationList = true;
450429
- console.log("onGetMessageStreamParser: Updating conversation list and currentConversationInfo after CHAT_CREATED", {
450430
- conversationId: pendingInfo.conversationId
450431
- });
450432
- // 检查会话是否已经存在于列表中,避免重复添加
450433
- const existingConversation = refConversations.current.find((c)=>c.id === pendingInfo.conversationId);
450434
- // 如果会话不存在,才更新会话列表
450435
- // 注意:会话已经在创建时添加到列表了,这里主要是为了兼容性检查
450436
- if (!existingConversation) {
450437
- const chatType = refChatConfig.current.type;
450438
- const isAppType = chatType === client_ChatType.APP;
450439
- const newConversation = {
450440
- id: pendingInfo.conversationId,
450441
- last_section_id: pendingInfo.sectionId,
450442
- // 使用创建时返回的名称
450443
- name: pendingInfo.conversationName || "",
450444
- created_at: Math.floor(Date.now() / 1000),
450445
- updated_at: Math.floor(Date.now() / 1000),
450446
- meta_data: {},
450447
- // App 模式需要 title 字段
450448
- ...isAppType && pendingInfo.conversationName && {
450449
- title: pendingInfo.conversationName
450450
- }
450451
- };
450452
- if (refUpdateConversations.current) refUpdateConversations.current([
450453
- newConversation
450454
- ], "add");
450455
- }
450456
- // 在 CHAT_CREATED 时,只添加会话到列表,不更新 currentConversationInfo
450457
- // 这样可以避免触发 useRequestInit 的依赖变化,防止重新初始化
450458
- // 但是,我们需要确保 chatCore 的 conversationId 被更新,以便消息流能正常继续
450459
- // 通过 refChatFunc.setConversationId 更新,但只更新 chatCore,不更新 currentConversationInfo
450460
- // 注意:setConversationId 会检查会话是否存在,如果存在就不会添加,所以是安全的
450461
- // 但是,setConversationId 也会更新 currentConversationInfo,这可能会触发重新初始化
450462
- // 所以我们需要延迟更新,或者找到其他方式更新 chatCore 的 conversationId
450463
- // 暂时不更新 currentConversationInfo,让 DONE 事件时再更新
450464
- // 这样可以避免触发重新初始化,但会话列表中的新会话不会立即显示为选中状态
450465
- // 这是可以接受的,因为用户正在查看消息流,不会立即点击会话列表
450462
+ const isErrorEvent = parseEvent.type === "event" && parseEvent.event === "error";
450463
+ if (isErrorEvent && refStreamAlreadySucceeded.current) return undefined;
450464
+ const result = originalParser(parseEvent, method);
450465
+ const { type, event } = parseEvent;
450466
+ const isChatCreatedEvent = type === "event" && event === "conversation.chat.created";
450467
+ const isDoneEvent = type === "event" && event === "done";
450468
+ // 空会话首条消息时 workflow 可能不推送 conversation.chat.created,流结束只有 DONE,chat-core 收不到 ack 会触发 MESSAGE_SEND_FAIL。在 DONE 且存在 pending 时补发合成 ack,使 sendMessage 正常 resolve
450469
+ const shouldReturnSyntheticAck = isDoneEvent && pendingInfo;
450470
+ // pending 时:在 CHAT_CREATED 时更新会话列表
450471
+ if (pendingInfo && isChatCreatedEvent && !hasUpdatedConversationList && pendingInfo.conversationId) {
450472
+ hasUpdatedConversationList = true;
450473
+ console.log("onGetMessageStreamParser: Updating conversation list and currentConversationInfo after CHAT_CREATED", {
450474
+ conversationId: pendingInfo.conversationId
450475
+ });
450476
+ const existingConversation = refConversations.current.find((c)=>c.id === pendingInfo.conversationId);
450477
+ if (!existingConversation) {
450478
+ const chatType = refChatConfig.current.type;
450479
+ const isAppType = chatType === client_ChatType.APP;
450480
+ const newConversation = {
450481
+ id: pendingInfo.conversationId,
450482
+ last_section_id: pendingInfo.sectionId,
450483
+ name: pendingInfo.conversationName || "",
450484
+ created_at: Math.floor(Date.now() / 1000),
450485
+ updated_at: Math.floor(Date.now() / 1000),
450486
+ meta_data: {},
450487
+ ...isAppType && pendingInfo.conversationName && {
450488
+ title: pendingInfo.conversationName
450489
+ }
450490
+ };
450491
+ if (refUpdateConversations.current) refUpdateConversations.current([
450492
+ newConversation
450493
+ ], "add");
450466
450494
  }
450467
- // 在消息流完成(DONE)时更新 currentConversationInfo 和 chatCore 的 conversationId
450468
- // 注意:不更新 name,让 useUpdateConversationNameByMessage hook 在收到第一条消息后自动更新
450469
- // 这样可以避免 name 的变化触发 useRequestInit 的依赖变化,防止重新初始化
450470
- if (isDoneEvent && !hasUpdatedChatCore && pendingInfo.conversationId) {
450495
+ }
450496
+ // DONE 时:若有 pending 则更新 currentConversationInfo 和 chatCore;并始终刷新知识库列表(含发送带文件消息后)
450497
+ if (isDoneEvent) {
450498
+ var _refChatFunc_current_getConversationId, _refChatFunc_current, _refChatFunc_current_getSectionId, _refChatFunc_current1, _refChatConfig_current_appInfo, _refChatConfig_current, _refChatConfig_current1;
450499
+ const conversationId = (pendingInfo === null || pendingInfo === void 0 ? void 0 : pendingInfo.conversationId) || (refChatFunc === null || refChatFunc === void 0 ? void 0 : (_refChatFunc_current = refChatFunc.current) === null || _refChatFunc_current === void 0 ? void 0 : (_refChatFunc_current_getConversationId = _refChatFunc_current.getConversationId) === null || _refChatFunc_current_getConversationId === void 0 ? void 0 : _refChatFunc_current_getConversationId.call(_refChatFunc_current));
450500
+ const sectionId = (pendingInfo === null || pendingInfo === void 0 ? void 0 : pendingInfo.sectionId) || (refChatFunc === null || refChatFunc === void 0 ? void 0 : (_refChatFunc_current1 = refChatFunc.current) === null || _refChatFunc_current1 === void 0 ? void 0 : (_refChatFunc_current_getSectionId = _refChatFunc_current1.getSectionId) === null || _refChatFunc_current_getSectionId === void 0 ? void 0 : _refChatFunc_current_getSectionId.call(_refChatFunc_current1));
450501
+ const appId = ((_refChatConfig_current = refChatConfig.current) === null || _refChatConfig_current === void 0 ? void 0 : (_refChatConfig_current_appInfo = _refChatConfig_current.appInfo) === null || _refChatConfig_current_appInfo === void 0 ? void 0 : _refChatConfig_current_appInfo.appId) || ((_refChatConfig_current1 = refChatConfig.current) === null || _refChatConfig_current1 === void 0 ? void 0 : _refChatConfig_current1.bot_id) || "";
450502
+ if (cozeApiSdk && conversationId && sectionId && appId && setConversationKnowledgeIds) getConversationKnowledges({
450503
+ cozeApiSdk,
450504
+ conversationId,
450505
+ sectionId,
450506
+ appId
450507
+ }).then((knowledgeIds)=>{
450508
+ // 仅当接口返回非空时更新 store,避免返回 [] 时清空已有知识库导致第二次发送缺少 KNOWLEDGE_IDS
450509
+ if (Array.isArray(knowledgeIds) && knowledgeIds.length > 0) setConversationKnowledgeIds(knowledgeIds);
450510
+ }).catch((e)=>{
450511
+ console.warn("Failed to refresh conversation knowledges after chat:", e);
450512
+ });
450513
+ if (pendingInfo && !hasUpdatedChatCore && pendingInfo.conversationId) {
450471
450514
  var _refCurrentConversationInfo_current;
450472
450515
  hasUpdatedChatCore = true;
450473
450516
  console.log("onGetMessageStreamParser: Updating currentConversationInfo and chatCore after stream done", {
450474
450517
  conversationId: pendingInfo.conversationId
450475
450518
  });
450476
- // 检查当前的 currentConversationInfo.id 是否已经是我们要设置的 conversationId
450477
450519
  const currentId = (_refCurrentConversationInfo_current = refCurrentConversationInfo.current) === null || _refCurrentConversationInfo_current === void 0 ? void 0 : _refCurrentConversationInfo_current.id;
450478
450520
  if (currentId === pendingInfo.conversationId) {
450479
450521
  console.log("onGetMessageStreamParser: Conversation ID already matches, only updating chatCore", {
450480
450522
  conversationId: pendingInfo.conversationId
450481
450523
  });
450482
- // 即使 ID 相同,也要更新 chatCore 的 conversationId
450483
450524
  if (refChatFunc === null || refChatFunc === void 0 ? void 0 : refChatFunc.current) refChatFunc.current.setConversationId(pendingInfo.conversationId, pendingInfo.sectionId);
450484
450525
  refPendingConversationInfo.current = null;
450485
450526
  return result;
450486
450527
  }
450487
- // 使用 setTimeout 确保在消息发送流程完全完成后更新状态
450488
450528
  setTimeout(()=>{
450489
450529
  if (refUpdateCurrentConversationInfo.current) {
450490
- // 保留当前的 conversationListVisible 和 isLargeWidth,避免会话列表被收起
450491
450530
  const currentInfo = refCurrentConversationInfo.current;
450492
450531
  refUpdateCurrentConversationInfo.current({
450493
450532
  id: pendingInfo.conversationId,
450494
450533
  last_section_id: pendingInfo.sectionId,
450495
- // 不设置 name,让 useUpdateConversationNameByMessage hook 自动更新
450496
450534
  name: "",
450497
450535
  created_at: Math.floor(Date.now() / 1000),
450498
450536
  updated_at: Math.floor(Date.now() / 1000),
450499
450537
  meta_data: {},
450500
- // 保留当前的 conversationListVisible,避免会话列表被收起
450501
450538
  conversationListVisible: (currentInfo === null || currentInfo === void 0 ? void 0 : currentInfo.conversationListVisible) ?? false,
450502
- // 保留当前的 isLargeWidth
450503
450539
  isLargeWidth: (currentInfo === null || currentInfo === void 0 ? void 0 : currentInfo.isLargeWidth) ?? false
450504
450540
  });
450505
450541
  }
450506
450542
  if (refChatFunc === null || refChatFunc === void 0 ? void 0 : refChatFunc.current) refChatFunc.current.setConversationId(pendingInfo.conversationId, pendingInfo.sectionId);
450507
- // 清除 pending 信息
450508
450543
  refPendingConversationInfo.current = null;
450509
450544
  }, 0);
450510
450545
  }
450511
- return result;
450512
- };
450513
- }
450514
- return originalParser;
450546
+ }
450547
+ if (shouldReturnSyntheticAck && pendingInfo) {
450548
+ const localMessageId = (requestMessageRawBody === null || requestMessageRawBody === void 0 ? void 0 : requestMessageRawBody.local_message_id) || "";
450549
+ const replyId = pendingInfo.conversationId || `--ack--${localMessageId}`;
450550
+ refStreamAlreadySucceeded.current = true;
450551
+ const extraInfo = {
450552
+ local_message_id: localMessageId,
450553
+ input_tokens: "",
450554
+ output_tokens: "",
450555
+ token: "",
450556
+ plugin_status: "",
450557
+ time_cost: "",
450558
+ workflow_tokens: "",
450559
+ bot_state: "",
450560
+ plugin_request: "",
450561
+ tool_name: "",
450562
+ plugin: "",
450563
+ execute_display_name: ""
450564
+ };
450565
+ const syntheticAck = {
450566
+ event: "message",
450567
+ data: {
450568
+ index: 0,
450569
+ seq_id: 0,
450570
+ is_finish: true,
450571
+ message: {
450572
+ type: "ack",
450573
+ message_id: replyId,
450574
+ reply_id: replyId,
450575
+ section_id: pendingInfo.sectionId || "",
450576
+ content_type: types_ContentType.Text,
450577
+ content: "",
450578
+ extra_info: extraInfo,
450579
+ role: "user"
450580
+ }
450581
+ }
450582
+ };
450583
+ return syntheticAck;
450584
+ }
450585
+ return result;
450586
+ };
450515
450587
  }
450516
450588
  }
450517
450589
  };
@@ -450535,19 +450607,20 @@ class MessageParser {
450535
450607
  */
450536
450608
 
450537
450609
  const useClearHistoryAdapter = (param)=>{
450538
- let { refChatFunc } = param;
450610
+ let { refChatFunc, onAfterCreateConversation } = param;
450539
450611
  var _chatConfig_auth;
450540
450612
  const { chatConfig } = context_useChatAppProps();
450541
450613
  const refConnectorId = (0,react_.useRef)("");
450542
450614
  refConnectorId.current = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_auth = chatConfig.auth) === null || _chatConfig_auth === void 0 ? void 0 : _chatConfig_auth.connectorId) || "";
450543
450615
  return (0,react_.useMemo)(()=>{
450544
450616
  const onAfterResponse = [
450545
- (response)=>{
450617
+ async (response)=>{
450546
450618
  var _refChatFunc_current;
450547
450619
  const { data: resCreateConversation } = response;
450548
450620
  const { code, data: conversationData } = resCreateConversation;
450549
450621
  const { id: conversationId, last_section_id: sectionId } = conversationData || {};
450550
450622
  refChatFunc === null || refChatFunc === void 0 || (_refChatFunc_current = refChatFunc.current) === null || _refChatFunc_current === void 0 || _refChatFunc_current.setConversationId(conversationId, sectionId);
450623
+ if (conversationId && sectionId && onAfterCreateConversation) await onAfterCreateConversation(conversationId, sectionId);
450551
450624
  return {
450552
450625
  ...response,
450553
450626
  data: {
@@ -450578,7 +450651,9 @@ const useClearHistoryAdapter = (param)=>{
450578
450651
  }
450579
450652
  };
450580
450653
  return config;
450581
- }, []);
450654
+ }, [
450655
+ onAfterCreateConversation
450656
+ ]);
450582
450657
  };
450583
450658
 
450584
450659
  ;// CONCATENATED MODULE: ../open-chat/src/components/studio-open-chat/provider/coz-sdk/api-adapter/use-common-hooks.ts
@@ -450719,24 +450794,47 @@ const useBreakMessage = ()=>(0,react_.useMemo)(()=>{
450719
450794
 
450720
450795
 
450721
450796
 
450797
+
450722
450798
  const useCoreManager = (param)=>{
450723
450799
  let { refChatFunc } = param;
450800
+ var _chatConfig_appInfo;
450724
450801
  const userInfo = useUserInfo();
450725
- const { refreshToken } = context_useChatCozeSdk();
450802
+ const { refreshToken, cozeApiSdk } = context_useChatCozeSdk();
450803
+ const { chatConfig, requestManagerOptions } = context_useChatAppProps();
450804
+ const setConversationKnowledgeIds = context_useChatAppStore((s)=>s.setConversationKnowledgeIds);
450726
450805
  // 获取 apiUrl
450727
450806
  const { apiUrl } = context_useChatAppStore(shallow_useShallow((s)=>({
450728
450807
  apiUrl: s.apiUrl
450729
450808
  })));
450809
+ // 删除对话记录(创建新 conversation)成功后,重新拉取 workflows/conversation/knowledges 更新知识库列表
450810
+ const onAfterCreateConversation = (0,react_.useCallback)(async (conversationId, sectionId)=>{
450811
+ var _chatConfig_appInfo;
450812
+ if (!cozeApiSdk) return;
450813
+ const appId = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo = chatConfig.appInfo) === null || _chatConfig_appInfo === void 0 ? void 0 : _chatConfig_appInfo.appId) || (chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.bot_id) || "";
450814
+ if (!appId) return;
450815
+ const knowledgeIds = await getConversationKnowledges({
450816
+ cozeApiSdk,
450817
+ conversationId,
450818
+ sectionId,
450819
+ appId
450820
+ });
450821
+ setConversationKnowledgeIds(knowledgeIds);
450822
+ }, [
450823
+ cozeApiSdk,
450824
+ chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig_appInfo = chatConfig.appInfo) === null || _chatConfig_appInfo === void 0 ? void 0 : _chatConfig_appInfo.appId,
450825
+ chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.bot_id,
450826
+ setConversationKnowledgeIds
450827
+ ]);
450730
450828
  const clearMessageContextAdapter = useClearMessageContextAdapter();
450731
450829
  const sendMessageAdapter = useSendMessageAdapter(userInfo || undefined, refChatFunc);
450732
450830
  const clearHistoryAdapter = useClearHistoryAdapter({
450733
- refChatFunc
450831
+ refChatFunc,
450832
+ onAfterCreateConversation
450734
450833
  });
450735
450834
  const commonOnBeforeRequestHooks = useCommonOnBeforeRequestHooks();
450736
450835
  const commonOnAfterResponseHooks = useCommonOnAfterResponseHooks(refreshToken);
450737
450836
  const commonErrorResponseHooks = useCommonErrorResponseHooks(refreshToken);
450738
450837
  const messageListAdapter = useMessageList();
450739
- const { requestManagerOptions } = context_useChatAppProps();
450740
450838
  const breakMessageAdapter = useBreakMessage();
450741
450839
  // 计算最终的 baseURL
450742
450840
  const finalBaseURL = apiUrl || openApiHostByRegionWithToken;
@@ -465395,6 +465493,8 @@ const StudioChatArea = (param)=>{
465395
465493
  const refContainer = (0,react_.useRef)(null);
465396
465494
  const { readonly } = context_useChatAppProps();
465397
465495
  const currentConversationInfo = context_useChatAppStore((state)=>state.currentConversationInfo);
465496
+ const updateConversations = context_useChatAppStore((state)=>state.updateConversations);
465497
+ const conversations = context_useChatAppStore((state)=>state.conversations);
465398
465498
  // Get apiUrl from store for knowledge upload
465399
465499
  const apiUrl = context_useChatAppStore((state)=>state.apiUrl);
465400
465500
  // Get updateCurrentConversationInfo from store for knowledge upload
@@ -465486,7 +465586,6 @@ const StudioChatArea = (param)=>{
465486
465586
  // Pass updateCurrentConversationInfo callback so file upload can update the store
465487
465587
  updateCurrentConversationInfo: (info)=>{
465488
465588
  // Update currentConversationInfo with the new conversation info
465489
- // Merge with existing to preserve other fields
465490
465589
  updateCurrentConversationInfo({
465491
465590
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- currentConversationInfo may have additional fields not in type definition
465492
465591
  ...currentConversationInfo,
@@ -465494,6 +465593,20 @@ const StudioChatArea = (param)=>{
465494
465593
  last_section_id: info.last_section_id,
465495
465594
  name: info.name
465496
465595
  });
465596
+ // 上传文件创建新会话时,将会话加入会话历史列表,否则列表中看不到新会话
465597
+ if (info.id && !conversations.some((c)=>c.id === info.id)) {
465598
+ const timestamp = Math.floor(Date.now() / 1000);
465599
+ updateConversations([
465600
+ {
465601
+ id: info.id,
465602
+ last_section_id: info.last_section_id ?? "",
465603
+ name: info.name ?? "",
465604
+ created_at: timestamp,
465605
+ updated_at: timestamp,
465606
+ meta_data: {}
465607
+ }
465608
+ ], "add");
465609
+ }
465497
465610
  }
465498
465611
  }
465499
465612
  }