@glodon-aiot/chat-app-sdk 0.0.28 → 0.0.30

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/README.md CHANGED
@@ -8,7 +8,7 @@ Glodon AIoT Chat App SDK - 基于广联达行业AI平台的智能聊天 SDK,
8
8
 
9
9
  ## 📚 在线示例
10
10
 
11
- **🎯 [查看完整示例和演示](https://aruna1990.github.io/glodon-aiot-examples/)**
11
+ **🎯 [查看完整示例和演示](https://glodon-aiot.github.io/chat-app-sdk-demo/live/#/demo)**
12
12
 
13
13
  示例项目展示了以下功能:
14
14
  - ✅ Web Components 集成
@@ -272,7 +272,7 @@ const client = new WebChatClient({
272
272
 
273
273
  ### 示例组件
274
274
 
275
- 查看 [在线示例](https://aruna1990.github.io/glodon-aiot-examples/) 了解以下组件的实现:
275
+ 查看 [在线示例](https://glodon-aiot.github.io/chat-app-sdk-demo/live/#/demo) 了解以下组件的实现:
276
276
 
277
277
  - `knowledge-reference-list` - 知识库引用列表组件
278
278
  - `search-result-list` - 搜索结果列表组件
@@ -440,7 +440,7 @@ auth: {
440
440
 
441
441
  ### Q6: 如何自定义 Web Components?
442
442
 
443
- 参考 [在线示例](https://aruna1990.github.io/glodon-aiot-examples/) 中的实现,注册自定义组件并在配置中指定:
443
+ 参考 [在线示例](https://glodon-aiot.github.io/chat-app-sdk-demo/live/#/demo) 中的实现,注册自定义组件并在配置中指定:
444
444
 
445
445
  ```typescript
446
446
  // 注册组件
@@ -496,7 +496,7 @@ Apache-2.0
496
496
 
497
497
  ## 🔗 相关链接
498
498
 
499
- - 📚 [在线示例和演示](https://aruna1990.github.io/glodon-aiot-examples/)
499
+ - 📚 [在线示例和演示](https://glodon-aiot.github.io/chat-app-sdk-demo/live/#/demo)
500
500
  - 📦 [npm 包地址](https://www.npmjs.com/package/@glodon-aiot/chat-app-sdk)
501
501
  - 📖 [广联达行业AI平台官方文档](https://glodon-cv-help.yuque.com/cuv0se/ol9231)
502
502
 
package/es/index.esm.js CHANGED
@@ -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,
@@ -426757,6 +426760,10 @@ try {
426757
426760
  error;
426758
426761
  }
426759
426762
  /** 按 fileId 存储轮询的 AbortController,删除文件时用于停止轮询 */ const knowledgePollingControllers = new Map();
426763
+ /**
426764
+ * 空会话时并发上传多个文件共用的「创建会话」Promise。
426765
+ * 保证同一时刻只有一次创建会话请求,后续上传复用同一会话,避免多文件一次选择时创建多个会话。
426766
+ */ let pendingCreateConversationPromise = null;
426760
426767
  /**
426761
426768
  * 取消指定 fileId 的知识库文件状态轮询(会话中删除正在上传的文件时调用)
426762
426769
  */ function cancelKnowledgePolling(fileId) {
@@ -426959,7 +426966,7 @@ const useUploadToKnowledge = (config)=>{
426959
426966
  // 1. Get or create conversation
426960
426967
  let currentConversationId = conversationId || "";
426961
426968
  let currentSectionId = sectionId || "";
426962
- // If no conversation, create one
426969
+ // If no conversation, create one (or reuse in-flight creation when multiple files are uploaded at once)
426963
426970
  if (!currentConversationId) {
426964
426971
  var _chatConfig_appInfo5, _chatConfig_appInfo6, _chatConfig_appInfo7, _chatConfig_appInfo8, _chatConfig_auth3, _chatConfig_auth4;
426965
426972
  const finalAppId = appId || ((_chatConfig_appInfo5 = chatConfig.appInfo) === null || _chatConfig_appInfo5 === void 0 ? void 0 : _chatConfig_appInfo5.appId) || chatConfig.bot_id || "";
@@ -426973,100 +426980,95 @@ const useUploadToKnowledge = (config)=>{
426973
426980
  const finalConversationName = conversationName || ((_chatConfig_appInfo8 = chatConfig.appInfo) === null || _chatConfig_appInfo8 === void 0 ? void 0 : _chatConfig_appInfo8.conversationName);
426974
426981
  const finalConnectorId = connectorId || ((_chatConfig_auth3 = chatConfig.auth) === null || _chatConfig_auth3 === void 0 ? void 0 : _chatConfig_auth3.connectorId);
426975
426982
  const finalToken = token || ((_chatConfig_auth4 = chatConfig.auth) === null || _chatConfig_auth4 === void 0 ? void 0 : _chatConfig_auth4.token) || "";
426976
- // Try to use createConversationForMessage if available
426977
- if (use_upload_to_knowledge_createConversationForMessage && cozeApiSdk) try {
426978
- const conversationResult = await use_upload_to_knowledge_createConversationForMessage(cozeApiSdk, {
426979
- projectType,
426980
- projectId: finalAppId,
426981
- workflowId: finalWorkflowId,
426982
- mode: finalDraftMode ? "draft" : "release",
426983
- conversationName: finalConversationName,
426984
- connectorId: finalConnectorId
426985
- });
426986
- currentConversationId = conversationResult.conversationId;
426987
- currentSectionId = conversationResult.sectionId;
426988
- } catch (error) {
426989
- console.warn("Failed to create conversation using createConversationForMessage:", error);
426990
- // Fall through to direct API call
426991
- }
426992
- // If createConversationForMessage failed or is not available, use direct API call
426993
- // Note: finalApiUrl is defined later in the code, so we use apiUrl here
426994
- if (!currentConversationId && apiUrl && finalToken) try {
426995
- let createUrl = "";
426996
- let createPayload = {};
426997
- if (projectType === "bot") {
426998
- createUrl = `${apiUrl}/v1/conversations/create`;
426999
- createPayload = {
427000
- connector_id: finalConnectorId
427001
- };
427002
- } else {
427003
- createUrl = `${apiUrl}/v1/workflow/conversation/create`;
427004
- createPayload = {
427005
- app_id: finalAppId,
427006
- draft_mode: finalDraftMode || false,
427007
- workflow_id: finalWorkflowId || "",
427008
- connector_id: finalConnectorId
427009
- };
427010
- // Only add get_or_create if conversationName is provided
427011
- if (finalConversationName && finalConversationName.trim() !== "") {
427012
- createPayload.get_or_create = true;
427013
- createPayload.conversation_name = finalConversationName;
427014
- }
427015
- }
427016
- const createResponse = await fetch(createUrl, {
427017
- method: "POST",
427018
- headers: {
427019
- "Content-Type": "application/json",
427020
- Authorization: `Bearer ${finalToken}`,
427021
- "Accept-Language": "en"
427022
- },
427023
- body: JSON.stringify(createPayload)
427024
- });
427025
- const createResult = await createResponse.json();
427026
- if (createResult.code === 0 && createResult.data) {
427027
- currentConversationId = createResult.data.id || "";
427028
- currentSectionId = createResult.data.last_section_id || "";
427029
- } else {
427030
- console.error("Failed to create conversation:", createResult.msg || "Unknown error");
427031
- return null;
427032
- }
427033
- } catch (error1) {
427034
- console.error("Error creating conversation:", error1);
427035
- return null;
427036
- }
427037
- // Update conversation ID in chat area
427038
- if (currentConversationId) {
427039
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- useGlobalInitStore type may vary by context
427040
- const globalStore = useGlobalInitStore;
427041
- if (globalStore && typeof globalStore.getState === "function") {
427042
- const { setConversationId } = globalStore.getState();
427043
- setConversationId(currentConversationId);
427044
- }
427045
- if (currentSectionId && setLatestSectionId) setLatestSectionId(currentSectionId);
427046
- // Also update currentConversationInfo in store so text messages can use it
427047
- // First try to use the callback from config (preferred method)
427048
- if (config === null || config === void 0 ? void 0 : config.updateCurrentConversationInfo) try {
427049
- // Delay updating currentConversationInfo to ensure file message is displayed first
427050
- // This prevents chatarea from refreshing before the file message is added to the store
427051
- // Use requestAnimationFrame + setTimeout to ensure file message is fully rendered and saved
427052
- const DELAY_MS = 200; // Increased delay to ensure file message is fully saved to store
427053
- requestAnimationFrame(()=>{
427054
- setTimeout(()=>{
427055
- if (config.updateCurrentConversationInfo) config.updateCurrentConversationInfo({
427056
- id: currentConversationId,
427057
- last_section_id: currentSectionId
427058
- });
427059
- }, DELAY_MS);
426983
+ const runCreateConversation = async ()=>{
426984
+ let newConversationId = "";
426985
+ let newSectionId = "";
426986
+ if (use_upload_to_knowledge_createConversationForMessage && cozeApiSdk) try {
426987
+ const conversationResult = await use_upload_to_knowledge_createConversationForMessage(cozeApiSdk, {
426988
+ projectType,
426989
+ projectId: finalAppId,
426990
+ workflowId: finalWorkflowId,
426991
+ mode: finalDraftMode ? "draft" : "release",
426992
+ conversationName: finalConversationName,
426993
+ connectorId: finalConnectorId
427060
426994
  });
426995
+ newConversationId = conversationResult.conversationId;
426996
+ newSectionId = conversationResult.sectionId;
427061
426997
  } catch (error) {
427062
- console.warn("Failed to schedule updateCurrentConversationInfo:", error);
426998
+ console.warn("Failed to create conversation using createConversationForMessage:", error);
427063
426999
  }
427064
- else {
427065
- // Fallback: try to use dynamically imported hook (may not work in callbacks)
427066
- // Note: This is a fallback that may not work in callbacks
427067
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- fallback hook may not be available
427068
- const storeHook = use_upload_to_knowledge_useChatAppStore;
427000
+ if (!newConversationId && apiUrl && finalToken) try {
427001
+ let createUrl = "";
427002
+ let createPayload = {};
427003
+ if (projectType === "bot") {
427004
+ createUrl = `${apiUrl}/v1/conversations/create`;
427005
+ createPayload = {
427006
+ connector_id: finalConnectorId
427007
+ };
427008
+ } else {
427009
+ createUrl = `${apiUrl}/v1/workflow/conversation/create`;
427010
+ createPayload = {
427011
+ app_id: finalAppId,
427012
+ draft_mode: finalDraftMode || false,
427013
+ workflow_id: finalWorkflowId || "",
427014
+ connector_id: finalConnectorId
427015
+ };
427016
+ if (finalConversationName && finalConversationName.trim() !== "") {
427017
+ createPayload.get_or_create = true;
427018
+ createPayload.conversation_name = finalConversationName;
427019
+ }
427020
+ }
427021
+ const createResponse = await fetch(createUrl, {
427022
+ method: "POST",
427023
+ headers: {
427024
+ "Content-Type": "application/json",
427025
+ Authorization: `Bearer ${finalToken}`,
427026
+ "Accept-Language": "en"
427027
+ },
427028
+ body: JSON.stringify(createPayload)
427029
+ });
427030
+ const createResult = await createResponse.json();
427031
+ if (createResult.code === 0 && createResult.data) {
427032
+ newConversationId = createResult.data.id || "";
427033
+ newSectionId = createResult.data.last_section_id || "";
427034
+ } else console.error("Failed to create conversation:", createResult.msg || "Unknown error");
427035
+ } catch (error1) {
427036
+ console.error("Error creating conversation:", error1);
427037
+ }
427038
+ if (newConversationId) {
427039
+ if (useGlobalInitStore && typeof useGlobalInitStore.getState === "function") {
427040
+ const { setConversationId } = useGlobalInitStore.getState();
427041
+ setConversationId(newConversationId);
427042
+ }
427043
+ if (newSectionId && setLatestSectionId) setLatestSectionId(newSectionId);
427044
+ if (config === null || config === void 0 ? void 0 : config.updateCurrentConversationInfo) try {
427045
+ const DELAY_MS = 200;
427046
+ requestAnimationFrame(()=>{
427047
+ setTimeout(()=>{
427048
+ if (config.updateCurrentConversationInfo) config.updateCurrentConversationInfo({
427049
+ id: newConversationId,
427050
+ last_section_id: newSectionId
427051
+ });
427052
+ }, DELAY_MS);
427053
+ });
427054
+ } catch (err) {
427055
+ console.warn("Failed to schedule updateCurrentConversationInfo:", err);
427056
+ }
427069
427057
  }
427058
+ return {
427059
+ conversationId: newConversationId,
427060
+ sectionId: newSectionId
427061
+ };
427062
+ };
427063
+ if (!pendingCreateConversationPromise) pendingCreateConversationPromise = runCreateConversation().finally(()=>{
427064
+ pendingCreateConversationPromise = null;
427065
+ });
427066
+ try {
427067
+ const result = await pendingCreateConversationPromise;
427068
+ currentConversationId = result.conversationId;
427069
+ currentSectionId = result.sectionId;
427070
+ } catch (error) {
427071
+ console.warn("Create conversation promise rejected:", error);
427070
427072
  }
427071
427073
  }
427072
427074
  if (!currentConversationId || !currentSectionId) {
@@ -427128,9 +427130,12 @@ const useUploadToKnowledge = (config)=>{
427128
427130
  // 轮询被用户取消(已删除文件)时不再更新 store,直接返回 null
427129
427131
  if (statusResult === null && (controller === null || controller === void 0 ? void 0 : controller.signal.aborted)) return null;
427130
427132
  if (statusResult) {
427131
- // Check if file processing failed
427133
+ // 处理失败时返回 null,让 chat-input 将文件标为 Error,file card 展示上传失败
427132
427134
  const failedFile = statusResult.find((item)=>item.status === 3);
427133
- if (failedFile) console.error(`File processing failed: ${failedFile.message}`, failedFile);
427135
+ if (failedFile) {
427136
+ console.error(`File processing failed: ${failedFile.message}`, failedFile);
427137
+ return null;
427138
+ }
427134
427139
  }
427135
427140
  return result.data;
427136
427141
  } else {
@@ -427594,20 +427599,20 @@ const ProgressMask = (param)=>{
427594
427599
 
427595
427600
 
427596
427601
 
427602
+ // import { IconRefresh } from '@coze-arch/bot-icons';
427597
427603
 
427598
427604
 
427599
427605
 
427600
427606
 
427601
-
427602
-
427607
+ // import { useRetryUpload } from '../../../hooks/file/use-upload';
427603
427608
 
427604
427609
 
427605
427610
  const CommonFile = (param)=>{
427606
427611
  let { file, status, percent, id, className, uri, url } = param;
427607
427612
  const ref = (0,react_.useRef)(null);
427608
427613
  const isHover = useHover_(ref);
427609
- const retryUpload = useRetryUpload();
427610
- const onRetry = ()=>retryUpload(id, file);
427614
+ // const retryUpload = useRetryUpload();
427615
+ // const onRetry = () => retryUpload(id, file);
427611
427616
  const isError = status === types_FileStatus.Error;
427612
427617
  const isSuccess = status === types_FileStatus.Success;
427613
427618
  const fileTypeConfig = getFileTypConfig(file);
@@ -427691,15 +427696,6 @@ const CommonFile = (param)=>{
427691
427696
  }) : null
427692
427697
  ]
427693
427698
  }),
427694
- isError ? /*#__PURE__*/ (0,jsx_runtime_.jsx)(ui_button_Button, {
427695
- icon: /*#__PURE__*/ (0,jsx_runtime_.jsx)(IconRefresh, {}),
427696
- onClick: (e)=>{
427697
- e.stopPropagation();
427698
- onRetry();
427699
- },
427700
- theme: "borderless",
427701
- className: batch_upload_file_list_common_file_index_module_["retry-button"]
427702
- }) : null,
427703
427699
  isSuccess ? /*#__PURE__*/ (0,jsx_runtime_.jsx)(esm_webpack_exports_Tooltip, {
427704
427700
  content: "预览",
427705
427701
  theme: "light",