@tencent-rtc/mcp 1.6.3 → 1.6.5

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.
Files changed (250) hide show
  1. package/index.js +0 -4
  2. package/knowledge/chunker.js +83 -54
  3. package/knowledge/path-meta.js +179 -26
  4. package/knowledge/search/exact-lookup.js +153 -0
  5. package/knowledge/search/filter-pool.js +73 -19
  6. package/knowledge/search/product-scope-intent.js +2 -2
  7. package/knowledge/search/requires-framework.js +2 -2
  8. package/knowledge/search/search-knowledge.js +235 -58
  9. package/package.json +1 -1
  10. package/resource/index/manifest.json +1 -1
  11. package/resource/integration/callkit/preset/android/integration.md +2 -4
  12. package/resource/integration/callkit/preset/flutter/integration.md +4 -5
  13. package/resource/integration/callkit/preset/ios/integration.md +1 -4
  14. package/resource/integration/callkit/preset/react/integration.md +13 -20
  15. package/resource/integration/callkit/preset/vue/integration.md +14 -21
  16. package/resource/integration/chat/preset/android/integration.md +6 -9
  17. package/resource/integration/chat/preset/flutter/integration.md +9 -12
  18. package/resource/integration/chat/preset/ios/integration.md +2 -4
  19. package/resource/integration/chat/preset/react/integration.md +0 -10
  20. package/resource/integration/livekit/preset/live/android/live-audience-integration.md +129 -0
  21. package/resource/integration/livekit/preset/live/android/live-host-integration.md +219 -0
  22. package/resource/integration/livekit/preset/live/android/live-list-integration.md +261 -0
  23. package/resource/integration/livekit/preset/live/android/prepare-integration.md +254 -0
  24. package/resource/integration/livekit/preset/live/ios/live-audience-integration.md +202 -0
  25. package/resource/integration/livekit/preset/live/ios/live-host-integration.md +369 -0
  26. package/resource/integration/livekit/preset/live/ios/live-list-integration.md +229 -0
  27. package/resource/integration/livekit/preset/live/ios/prepare-integration.md +204 -0
  28. package/resource/integration/livekit/preset/live/vue/live-list-integration.md +0 -3
  29. package/resource/integration/livekit/preset/live/vue/live-player-desk-integration.md +0 -5
  30. package/resource/integration/livekit/preset/live/vue/live-player-h5-integration.md +0 -6
  31. package/resource/integration/livekit/preset/live/vue/live-pusher-integration.md +5 -10
  32. package/resource/integration/roomkit/preset/vue/integration.md +0 -4
  33. package/resource/knowledge/callkit/best-practice/web/callengine-invitation.md +80 -0
  34. package/resource/knowledge/callkit/best-practice/web/callengine-log-control.md +24 -0
  35. package/resource/knowledge/callkit/best-practice/web/callkit-call-vs-calls.md +116 -0
  36. package/resource/knowledge/callkit/core-sdk/android/answer-call.md +7 -8
  37. package/resource/knowledge/callkit/core-sdk/android/make-call.md +5 -7
  38. package/resource/knowledge/callkit/core-sdk/android/offline-push.md +3 -5
  39. package/resource/knowledge/callkit/core-sdk/flutter/answer-call.md +2 -6
  40. package/resource/knowledge/callkit/core-sdk/flutter/make-call.md +2 -6
  41. package/resource/knowledge/callkit/core-sdk/flutter/offline-push.md +4 -9
  42. package/resource/knowledge/callkit/core-sdk/ios/answer-call.md +1 -4
  43. package/resource/knowledge/callkit/core-sdk/ios/make-call.md +8 -11
  44. package/resource/knowledge/callkit/core-sdk/ios/offline-push.md +17 -23
  45. package/resource/knowledge/callkit/core-sdk/web/call-engine.md +33 -0
  46. package/resource/knowledge/callkit/core-sdk/web/call-event.md +327 -0
  47. package/resource/knowledge/callkit/core-sdk/web/callengine-api-overview.md +33 -0
  48. package/resource/knowledge/callkit/faq/android.md +0 -2
  49. package/resource/knowledge/callkit/faq/error-code.md +0 -2
  50. package/resource/knowledge/callkit/faq/flutter.md +2 -2
  51. package/resource/knowledge/callkit/faq/ios.md +3 -5
  52. package/resource/knowledge/callkit/faq/web.md +2 -3
  53. package/resource/knowledge/callkit/preset/android/api.md +2 -5
  54. package/resource/knowledge/callkit/preset/ios/api.md +0 -2
  55. package/resource/knowledge/callkit/preset/react/api.md +445 -0
  56. package/resource/knowledge/callkit/preset/react/uikit-api-reference.md +445 -0
  57. package/resource/knowledge/callkit/preset/vue/api.md +465 -0
  58. package/resource/knowledge/callkit/preset/vue/uikit-api-reference.md +465 -0
  59. package/resource/knowledge/chat/best-practice/web/image-message-url-handling.md +16 -0
  60. package/resource/knowledge/chat/preset/android/features/chat-setting.md +1 -1
  61. package/resource/knowledge/chat/preset/android/features/conversation-list.md +1 -1
  62. package/resource/knowledge/chat/preset/android/features/language.md +0 -1
  63. package/resource/knowledge/chat/preset/android/features/message-input.md +1 -1
  64. package/resource/knowledge/chat/preset/android/features/message-list.md +2 -3
  65. package/resource/knowledge/chat/preset/android/features/search.md +0 -1
  66. package/resource/knowledge/chat/preset/android/features/theme.md +1 -1
  67. package/resource/knowledge/chat/preset/android-view/integration.md +3 -11
  68. package/resource/knowledge/chat/preset/flutter/features/conversation-list.md +0 -1
  69. package/resource/knowledge/chat/preset/flutter/features/message-list.md +1 -2
  70. package/resource/knowledge/chat/preset/flutter/features/search.md +5 -6
  71. package/resource/knowledge/chat/preset/flutter/features/theme.md +2 -2
  72. package/resource/knowledge/chat/preset/ios/features/chat-setting.md +1 -1
  73. package/resource/knowledge/chat/preset/ios/features/conversation-list.md +1 -2
  74. package/resource/knowledge/chat/preset/ios/features/message-list.md +1 -2
  75. package/resource/knowledge/chat/preset/ios/features/search.md +0 -1
  76. package/resource/knowledge/chat/preset/ios-uikit/integration.md +13 -15
  77. package/resource/knowledge/chat/preset/react/features/conversation-list.md +5 -5
  78. package/resource/knowledge/chat/preset/react/features/message-input.md +2 -3
  79. package/resource/knowledge/chat/preset/react/features/search.md +0 -1
  80. package/resource/knowledge/chat/preset/react/features/theme.md +0 -1
  81. package/resource/knowledge/livekit/core-sdk/api-reference/android/AudioEffectStore.md +7 -14
  82. package/resource/knowledge/livekit/core-sdk/api-reference/android/BarrageStore.md +5 -8
  83. package/resource/knowledge/livekit/core-sdk/api-reference/android/BattleStore.md +15 -18
  84. package/resource/knowledge/livekit/core-sdk/api-reference/android/CameraView.md +1 -2
  85. package/resource/knowledge/livekit/core-sdk/api-reference/android/CoGuestStore.md +15 -20
  86. package/resource/knowledge/livekit/core-sdk/api-reference/android/CoHostStore.md +10 -13
  87. package/resource/knowledge/livekit/core-sdk/api-reference/android/DeviceStore.md +2 -4
  88. package/resource/knowledge/livekit/core-sdk/api-reference/android/GiftStore.md +4 -6
  89. package/resource/knowledge/livekit/core-sdk/api-reference/android/LikeStore.md +2 -4
  90. package/resource/knowledge/livekit/core-sdk/api-reference/android/LiveAudienceStore.md +2 -4
  91. package/resource/knowledge/livekit/core-sdk/api-reference/android/LiveCoreView.md +1 -2
  92. package/resource/knowledge/livekit/core-sdk/api-reference/android/LiveSeatStore.md +8 -10
  93. package/resource/knowledge/livekit/core-sdk/api-reference/android/LoginStore.md +5 -7
  94. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/AudioEffectStore.md +7 -14
  95. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/BarrageStore.md +6 -9
  96. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/BaseBeautyStore.md +1 -2
  97. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/BattleStore.md +15 -18
  98. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/CoGuestStore.md +15 -20
  99. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/CoHostStore.md +10 -13
  100. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/DeviceStore.md +2 -4
  101. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/GiftStore.md +4 -6
  102. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/LikeStore.md +2 -4
  103. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/LiveAudienceStore.md +2 -4
  104. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/LiveCoreView.md +1 -2
  105. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/LiveSeatStore.md +8 -10
  106. package/resource/knowledge/livekit/core-sdk/api-reference/flutter/LoginStore.md +3 -5
  107. package/resource/knowledge/livekit/core-sdk/api-reference/ios/AudioEffectStore.md +7 -14
  108. package/resource/knowledge/livekit/core-sdk/api-reference/ios/BarrageStore.md +5 -8
  109. package/resource/knowledge/livekit/core-sdk/api-reference/ios/BaseBeautyStore.md +1 -2
  110. package/resource/knowledge/livekit/core-sdk/api-reference/ios/BattleStore.md +6 -9
  111. package/resource/knowledge/livekit/core-sdk/api-reference/ios/CoGuestStore.md +5 -10
  112. package/resource/knowledge/livekit/core-sdk/api-reference/ios/CoHostStore.md +3 -6
  113. package/resource/knowledge/livekit/core-sdk/api-reference/ios/DeviceStore.md +2 -4
  114. package/resource/knowledge/livekit/core-sdk/api-reference/ios/GiftStore.md +4 -6
  115. package/resource/knowledge/livekit/core-sdk/api-reference/ios/LikeStore.md +2 -4
  116. package/resource/knowledge/livekit/core-sdk/api-reference/ios/LiveAudienceStore.md +2 -4
  117. package/resource/knowledge/livekit/core-sdk/api-reference/ios/LiveCoreView.md +1 -2
  118. package/resource/knowledge/livekit/core-sdk/api-reference/ios/LiveSeatStore.md +4 -6
  119. package/resource/knowledge/livekit/core-sdk/api-reference/ios/LoginStore.md +3 -5
  120. package/resource/knowledge/livekit/core-sdk/api-reference/{web → vue}/index.md +24 -24
  121. package/resource/knowledge/livekit/core-sdk/{voice/android/voice-audio-effect.md → features/android/audio-effect.md} +1 -2
  122. package/resource/knowledge/livekit/core-sdk/{live/android/live-gift.md → features/android/gift.md} +2 -3
  123. package/resource/knowledge/livekit/core-sdk/{voice/android/voice-room-list.md → features/android/live-list.md} +2 -4
  124. package/resource/knowledge/livekit/core-sdk/{live/flutter/live-audio-effect.md → features/flutter/audio-effect.md} +0 -2
  125. package/resource/knowledge/livekit/core-sdk/{voice/flutter/voice-barrage.md → features/flutter/barrage.md} +2 -2
  126. package/resource/knowledge/livekit/core-sdk/{live/flutter/live-gift.md → features/flutter/gift.md} +2 -3
  127. package/resource/knowledge/livekit/core-sdk/{voice/flutter/voice-room-list.md → features/flutter/live-list.md} +1 -1
  128. package/resource/knowledge/livekit/core-sdk/{voice/ios/voice-audience-list.md → features/ios/audience-list.md} +1 -2
  129. package/resource/knowledge/livekit/core-sdk/{voice/ios/voice-audio-effect.md → features/ios/audio-effect.md} +1 -3
  130. package/resource/knowledge/livekit/core-sdk/{live/ios/live-base-beauty.md → features/ios/base-beauty.md} +2 -2
  131. package/resource/knowledge/livekit/core-sdk/{voice/ios/voice-gift.md → features/ios/gift.md} +2 -3
  132. package/resource/knowledge/livekit/core-sdk/{voice/ios/voice-room-list.md → features/ios/live-list.md} +2 -4
  133. package/resource/knowledge/livekit/core-sdk/live/android/{live-co-guest-interaction.md → co-guest-interaction.md} +0 -1
  134. package/resource/knowledge/livekit/core-sdk/live/android/{live-host-interaction.md → host-interaction.md} +5 -7
  135. package/resource/knowledge/livekit/core-sdk/live/android/{live-integration.md → integration.md} +3 -6
  136. package/resource/knowledge/livekit/core-sdk/live/flutter/{live-co-guest-interaction.md → co-guest-interaction.md} +1 -1
  137. package/resource/knowledge/livekit/core-sdk/live/flutter/{live-host-interaction.md → host-interaction.md} +0 -2
  138. package/resource/knowledge/livekit/core-sdk/live/flutter/{live-integration.md → integration.md} +1 -4
  139. package/resource/knowledge/livekit/core-sdk/live/ios/{live-co-guest-interaction.md → co-guest-interaction.md} +0 -1
  140. package/resource/knowledge/livekit/core-sdk/live/ios/{live-host-interaction.md → host-interaction.md} +2 -4
  141. package/resource/knowledge/livekit/core-sdk/live/ios/{live-integration.md → integration.md} +2 -5
  142. package/resource/knowledge/livekit/core-sdk/voice/android/{voice-host-interaction.md → host-interaction.md} +3 -5
  143. package/resource/knowledge/livekit/core-sdk/voice/android/{voice-integration.md → integration.md} +3 -6
  144. package/resource/knowledge/livekit/core-sdk/voice/flutter/{voice-co-guest-interaction.md → co-guest-interaction.md} +1 -2
  145. package/resource/knowledge/livekit/core-sdk/voice/flutter/{voice-integration.md → integration.md} +6 -9
  146. package/resource/knowledge/livekit/core-sdk/voice/ios/{voice-co-guest-interaction.md → co-guest-interaction.md} +2 -2
  147. package/resource/knowledge/livekit/core-sdk/voice/ios/{voice-host-interaction.md → host-interaction.md} +4 -6
  148. package/resource/knowledge/livekit/core-sdk/voice/ios/{voice-integration.md → integration.md} +1 -4
  149. package/resource/knowledge/livekit/preset/live/vue/features/barrage.md +0 -2
  150. package/resource/knowledge/push/api-reference/android.md +123 -0
  151. package/resource/knowledge/push/api-reference/flutter.md +176 -0
  152. package/resource/knowledge/push/api-reference/harmonyos.md +138 -0
  153. package/resource/knowledge/push/api-reference/ios.md +176 -0
  154. package/resource/knowledge/push/api-reference/react-native.md +147 -0
  155. package/resource/knowledge/push/api-reference/uni-app.md +147 -0
  156. package/resource/knowledge/push/api-reference/unity.md +119 -0
  157. package/resource/knowledge/push/api-reference/unreal-engine.md +123 -0
  158. package/resource/knowledge/push/config/android.md +4 -7
  159. package/resource/knowledge/push/config/harmonyos.md +0 -3
  160. package/resource/knowledge/push/config/ios.md +12 -20
  161. package/resource/knowledge/push/config/react-native.md +18 -26
  162. package/resource/knowledge/push/config/unity.md +20 -28
  163. package/resource/knowledge/push/config/unreal-engine.md +21 -29
  164. package/resource/knowledge/push/integration/android.md +6 -8
  165. package/resource/knowledge/push/integration/flutter.md +6 -9
  166. package/resource/knowledge/push/integration/harmonyos.md +1 -0
  167. package/resource/knowledge/push/integration/ios.md +7 -9
  168. package/resource/knowledge/push/integration/react-native.md +9 -13
  169. package/resource/knowledge/push/integration/uni-app.md +7 -7
  170. package/resource/knowledge/push/integration/unity.md +10 -13
  171. package/resource/knowledge/push/integration/unreal-engine.md +6 -9
  172. package/resource/knowledge/push/overview/prepare.md +2 -2
  173. package/resource/knowledge/roomkit/core-sdk/android/call-user-to-room.md +3 -3
  174. package/resource/knowledge/roomkit/core-sdk/android/capability-matrix.md +46 -0
  175. package/resource/knowledge/roomkit/core-sdk/android/room-participant-state.md +1 -1
  176. package/resource/knowledge/roomkit/core-sdk/android/room-state.md +2 -2
  177. package/resource/knowledge/roomkit/core-sdk/android/schedule-room.md +6 -6
  178. package/resource/knowledge/roomkit/core-sdk/android/unsupported-features.md +79 -0
  179. package/resource/knowledge/roomkit/core-sdk/flutter/capability-matrix.md +46 -0
  180. package/resource/knowledge/roomkit/core-sdk/flutter/room-participant-state.md +1 -1
  181. package/resource/knowledge/roomkit/core-sdk/flutter/unsupported-features.md +79 -0
  182. package/resource/knowledge/roomkit/core-sdk/ios/capability-matrix.md +46 -0
  183. package/resource/knowledge/roomkit/core-sdk/ios/room-participant-state.md +1 -1
  184. package/resource/knowledge/roomkit/core-sdk/ios/unsupported-features.md +79 -0
  185. package/resource/knowledge/roomkit/preset/android/integration.md +5 -7
  186. package/resource/knowledge/roomkit/preset/flutter/integration.md +2 -7
  187. package/resource/knowledge/roomkit/preset/ios/integration.md +3 -9
  188. package/resource/knowledge/roomkit/preset/react/integration.md +12 -16
  189. package/resource/knowledge/trtc/android/TRTCCloud.md +154 -238
  190. package/resource/knowledge/trtc/android/TRTCCloudDef.md +133 -134
  191. package/resource/knowledge/trtc/android/TRTCCloudListener.md +86 -120
  192. package/resource/knowledge/trtc/android/TRTCStatistics.md +10 -10
  193. package/resource/knowledge/trtc/android/TXAudioEffectManager.md +10 -30
  194. package/resource/knowledge/trtc/android/TXBeautyManager.md +25 -25
  195. package/resource/knowledge/trtc/android/TXDeviceManager.md +2 -2
  196. package/resource/knowledge/trtc/android/TXLiteAVCode.md +12 -12
  197. package/resource/knowledge/trtc/c++/ITRTCCloud.md +166 -261
  198. package/resource/knowledge/trtc/c++/ITRTCStatistics.md +12 -12
  199. package/resource/knowledge/trtc/c++/ITXAudioEffectManager.md +10 -30
  200. package/resource/knowledge/trtc/c++/ITXDeviceManager.md +9 -11
  201. package/resource/knowledge/trtc/c++/TRTCCloudCallback.md +96 -130
  202. package/resource/knowledge/trtc/c++/TRTCTypeDef.md +122 -123
  203. package/resource/knowledge/trtc/c++/TXLiteAVCode.md +12 -12
  204. package/resource/knowledge/trtc/ios/TRTCCloud.md +168 -255
  205. package/resource/knowledge/trtc/ios/TRTCCloudDef.md +124 -125
  206. package/resource/knowledge/trtc/ios/TRTCCloudDelegate.md +89 -124
  207. package/resource/knowledge/trtc/ios/TRTCStatistics.md +10 -10
  208. package/resource/knowledge/trtc/ios/TXAudioEffectManager.md +9 -28
  209. package/resource/knowledge/trtc/ios/TXBeautyManager.md +25 -25
  210. package/resource/knowledge/trtc/ios/TXDeviceManager.md +9 -11
  211. package/resource/knowledge/trtc/ios/TXLiteAVCode.md +12 -12
  212. package/server-config.js +7 -4
  213. package/server.js +21 -21
  214. package/tools/common/finalize_answer.js +1 -1
  215. package/tools/common/present_framework_choice.js +2 -2
  216. package/tools/common/search_trtc_knowledge.js +3 -3
  217. package/tools/common/submit_feedback.js +1 -1
  218. package/tools/definitions/get_native_live_uikit_integration_def.js +61 -0
  219. package/tools/definitions/get_native_livekit_core_integration_def.js +3 -3
  220. package/tools/definitions/present_framework_choice_def.js +2 -2
  221. package/tools/definitions/search_trtc_knowledge_def.js +5 -5
  222. package/tools/index.js +2 -0
  223. package/tools/live/get_native_live_uikit_integration.js +69 -0
  224. package/tools/live/get_native_livekit_core_integration.js +6 -6
  225. package/utils/is-valid-sdkappid.js +4 -0
  226. package/utils/report-cls-client.js +1 -1
  227. package/utils/report-es-client.js +1 -1
  228. package/resource/knowledge/callkit/preset/web/api.md +0 -83
  229. package/resource/knowledge/livekit/core-sdk/live/android/live-audio-effect.md +0 -226
  230. package/resource/knowledge/livekit/core-sdk/live/android/live-live-list.md +0 -438
  231. package/resource/knowledge/livekit/core-sdk/live/flutter/live-barrage.md +0 -490
  232. package/resource/knowledge/livekit/core-sdk/live/flutter/live-live-list.md +0 -726
  233. package/resource/knowledge/livekit/core-sdk/live/ios/live-audience-list.md +0 -264
  234. package/resource/knowledge/livekit/core-sdk/live/ios/live-audio-effect.md +0 -216
  235. package/resource/knowledge/livekit/core-sdk/live/ios/live-gift.md +0 -407
  236. package/resource/knowledge/livekit/core-sdk/live/ios/live-live-list.md +0 -349
  237. package/resource/knowledge/livekit/core-sdk/voice/android/voice-audience-list.md +0 -269
  238. package/resource/knowledge/livekit/core-sdk/voice/android/voice-barrage.md +0 -456
  239. package/resource/knowledge/livekit/core-sdk/voice/android/voice-gift.md +0 -455
  240. package/resource/knowledge/livekit/core-sdk/voice/flutter/voice-audience-list.md +0 -260
  241. package/resource/knowledge/livekit/core-sdk/voice/flutter/voice-audio-effect.md +0 -598
  242. package/resource/knowledge/livekit/core-sdk/voice/flutter/voice-gift.md +0 -424
  243. package/resource/knowledge/livekit/core-sdk/voice/ios/voice-barrage.md +0 -408
  244. /package/resource/knowledge/livekit/core-sdk/{live/android/live-audience-list.md → features/android/audience-list.md} +0 -0
  245. /package/resource/knowledge/livekit/core-sdk/{live/android/live-barrage.md → features/android/barrage.md} +0 -0
  246. /package/resource/knowledge/livekit/core-sdk/{live/android/live-base-beauty.md → features/android/base-beauty.md} +0 -0
  247. /package/resource/knowledge/livekit/core-sdk/{live/flutter/live-audience-list.md → features/flutter/audience-list.md} +0 -0
  248. /package/resource/knowledge/livekit/core-sdk/{live/flutter/live-base-beauty.md → features/flutter/base-beauty.md} +0 -0
  249. /package/resource/knowledge/livekit/core-sdk/{live/ios/live-barrage.md → features/ios/barrage.md} +0 -0
  250. /package/resource/knowledge/livekit/core-sdk/voice/android/{voice-co-guest-interaction.md → co-guest-interaction.md} +0 -0
package/index.js CHANGED
@@ -5,10 +5,6 @@ import { ServerConfig } from './server-config.js';
5
5
  // 启动服务器
6
6
  async function main() {
7
7
  ServerConfig.getInstance();
8
- // const { SDKAppID } = ServerConfig.getInstance().getConfig();
9
- // if (isNaN(SDKAppID)) {
10
- // throw new Error('You have not configured the SDKAppID, or the configured SDKAppID is invalid. Please configure the correct SDKAppID through the `env` parameter in MCP.');
11
- // }
12
8
  const server = createServer();
13
9
  const transport = new StdioServerTransport();
14
10
  await server.connect(transport);
@@ -36,11 +36,83 @@ function splitByHeading(content, level) {
36
36
  return sections;
37
37
  }
38
38
  function isFaqLike(source, content) {
39
- return /faq|error-code|error_code|TXLiteAVCode/i.test(source) || (content.match(/^###\s+/gm) ?? []).length >= 3;
39
+ return /faq|error-code|error_code|TXLiteAVCode|unsupported-features/i.test(source)
40
+ || (content.match(/^###\s+/gm) ?? []).length >= 3;
41
+ }
42
+ function shouldForceSectionSplit(source, meta) {
43
+ return source.endsWith('unsupported-features.md') || meta.doc_kind === 'unsupported_summary';
40
44
  }
41
45
  function isChatUrlMapping(source) {
42
46
  return /knowledge\/chat\/urls\/.+\.md$/i.test(source.replace(/\\/g, '/'));
43
47
  }
48
+ function containsCodeBlock(body) {
49
+ return /```[\s\S]*?```/.test(body);
50
+ }
51
+ function extractApiNames(body) {
52
+ const names = new Set();
53
+ const upperNoise = new Set(['SDK', 'API', 'HTTP', 'HTTPS', 'JSON']);
54
+ for (const match of body.matchAll(/`([a-z][A-Za-z0-9_]{2,})`/g)) {
55
+ names.add(match[1]);
56
+ }
57
+ for (const match of body.matchAll(/\b([a-z]+[A-Z][A-Za-z0-9_]*)\b/g)) {
58
+ names.add(match[1]);
59
+ }
60
+ for (const match of body.matchAll(/\b([A-Z][A-Za-z0-9_]*\.[a-zA-Z_][A-Za-z0-9_]*)\b/g)) {
61
+ names.add(match[1]);
62
+ }
63
+ for (const match of body.matchAll(/\b(I[A-Z][A-Za-z0-9_]*)\b/g)) {
64
+ names.add(match[1]);
65
+ }
66
+ for (const match of body.matchAll(/\b([A-Z][A-Za-z0-9_]*\.[A-Z_][A-Z0-9_]*)\b/g)) {
67
+ names.add(match[1]);
68
+ }
69
+ for (const match of body.matchAll(/\b([A-Z_]{3,})\b/g)) {
70
+ const token = match[1];
71
+ if (!upperNoise.has(token))
72
+ names.add(token);
73
+ }
74
+ return [...names].slice(0, 90);
75
+ }
76
+ function extractKeyPhrases(title, body) {
77
+ const firstParagraph = body
78
+ .replace(/^#{1,6}\s+.+$/gm, '')
79
+ .split(/\n\s*\n/)
80
+ .map((p) => p.trim())
81
+ .find(Boolean) ?? '';
82
+ const phrases = [title, firstParagraph]
83
+ .flatMap((part) => part.split(/[,。;;\n]/))
84
+ .map((s) => s.trim())
85
+ .filter((s) => s.length >= 2)
86
+ .slice(0, 8);
87
+ return [...new Set(phrases)];
88
+ }
89
+ function buildChunk(meta, source, title, body, id, char_start, char_end) {
90
+ const api_names = extractApiNames(body);
91
+ const key_phrases = extractKeyPhrases(title, body);
92
+ return {
93
+ id,
94
+ corpus: meta.corpus,
95
+ product: meta.product,
96
+ framework: meta.framework,
97
+ types: meta.types,
98
+ scenario: meta.scenario,
99
+ variant: meta.variant,
100
+ scope: meta.scope,
101
+ doc_kind: meta.doc_kind,
102
+ capability_status: meta.capability_status,
103
+ retrievable_scope: meta.retrievable_scope,
104
+ title,
105
+ source,
106
+ content: body,
107
+ symbols: extractSymbols(body),
108
+ error_codes: extractErrorCodes(body),
109
+ ...(api_names.length ? { api_names } : {}),
110
+ ...(containsCodeBlock(body) ? { contains_code: true } : {}),
111
+ ...(key_phrases.length ? { key_phrases } : {}),
112
+ char_start,
113
+ char_end,
114
+ };
115
+ }
44
116
  function parseUrlMappingRows(content) {
45
117
  const lines = content.split('\n');
46
118
  let sectionTitle = '';
@@ -58,7 +130,7 @@ function parseUrlMappingRows(content) {
58
130
  const rowMatch = line.match(/^\|\s*([^|]+?)\s*\|\s*`?(https?:\/\/[^|`\s]+)`?\s*\|/);
59
131
  if (rowMatch) {
60
132
  const label = rowMatch[1].trim();
61
- if (label && label !== '子问题' && label !== 'Query' && label !== 'Topic' && !/^-+$/.test(label)) {
133
+ if (label && label !== '子问题' && !/^-+$/.test(label)) {
62
134
  rows.push({
63
135
  label,
64
136
  url: rowMatch[2],
@@ -78,28 +150,12 @@ function chunkUrlMapping(source, content, meta) {
78
150
  return [];
79
151
  }
80
152
  const baseSlug = sourceSlug(source);
81
- const chunks = [];
82
- for (const row of rows) {
153
+ return rows.map((row) => {
83
154
  const sectionLine = row.sectionTitle ? `### ${row.sectionTitle}\n\n` : '';
84
- const body = `${sectionLine}| Query | Documentation |\n|-------|---------------|\n| ${row.label} | \`${row.url}\` |`;
155
+ const body = `${sectionLine}| 子问题 | 目标文档 |\n|--------|---------|\n| ${row.label} | \`${row.url}\` |`;
85
156
  const headingSlug = slugify(row.label);
86
- chunks.push({
87
- id: `${baseSlug}#${headingSlug}`,
88
- corpus: meta.corpus,
89
- product: meta.product,
90
- framework: meta.framework,
91
- types: meta.types,
92
- scenario: meta.scenario,
93
- title: row.label,
94
- source,
95
- content: body,
96
- symbols: extractSymbols(body),
97
- error_codes: extractErrorCodes(body),
98
- char_start: row.lineStart,
99
- char_end: row.lineEnd,
100
- });
101
- }
102
- return chunks;
157
+ return buildChunk(meta, source, row.label, body, `${baseSlug}#${headingSlug}`, row.lineStart, row.lineEnd);
158
+ });
103
159
  }
104
160
  export function chunkMarkdown(source, content, meta) {
105
161
  const chunks = [];
@@ -110,49 +166,22 @@ export function chunkMarkdown(source, content, meta) {
110
166
  return urlChunks;
111
167
  }
112
168
  }
113
- if (content.length < 2048) {
169
+ const forceSectionSplit = shouldForceSectionSplit(source, meta);
170
+ if (content.length < 2048 && !forceSectionSplit) {
114
171
  const { body, char_start, char_end } = trimSliceOffsets(content, 0);
115
172
  if (!body)
116
173
  return chunks;
117
- chunks.push({
118
- id: `${baseSlug}#full`,
119
- corpus: meta.corpus,
120
- product: meta.product,
121
- framework: meta.framework,
122
- types: meta.types,
123
- scenario: meta.scenario,
124
- title: pathBasename(source),
125
- source,
126
- content: body,
127
- symbols: extractSymbols(body),
128
- error_codes: extractErrorCodes(body),
129
- char_start,
130
- char_end,
131
- });
174
+ chunks.push(buildChunk(meta, source, pathBasename(source), body, `${baseSlug}#full`, char_start, char_end));
132
175
  return chunks;
133
176
  }
134
- const level = isFaqLike(source, content) ? 3 : 2;
177
+ const level = forceSectionSplit ? 3 : (isFaqLike(source, content) ? 3 : 2);
135
178
  const sections = splitByHeading(content, level);
136
179
  for (const section of sections) {
137
180
  const { body, char_start, char_end } = trimSliceOffsets(section.raw, section.start);
138
181
  if (!body)
139
182
  continue;
140
183
  const headingSlug = slugify(section.title);
141
- chunks.push({
142
- id: `${baseSlug}#${headingSlug}`,
143
- corpus: meta.corpus,
144
- product: meta.product,
145
- framework: meta.framework,
146
- types: meta.types,
147
- scenario: meta.scenario,
148
- title: section.title,
149
- source,
150
- content: body,
151
- symbols: extractSymbols(body),
152
- error_codes: extractErrorCodes(body),
153
- char_start,
154
- char_end,
155
- });
184
+ chunks.push(buildChunk(meta, source, section.title, body, `${baseSlug}#${headingSlug}`, char_start, char_end));
156
185
  }
157
186
  return chunks.length > 0 ? chunks : chunkMarkdown(source, content.slice(0, 2048), meta);
158
187
  }
@@ -10,7 +10,10 @@ function inferTypesFromFilename(fileName, baseTypes) {
10
10
  types.push('api');
11
11
  if (lower === 'faq.md')
12
12
  types.push('faq');
13
- if (lower === 'integration.md' || lower.endsWith('-integration.md'))
13
+ // 文件名 = integration.md 不再默认 push integration(由上游 framework 分支显式声明 type)
14
+ // live 分支 core 文档的 filename = integration.md 应是 type=core,不是 type=integration
15
+ // chat/preset/integration.md 等仍由 preset 分支的 types.push('integration') 处理
16
+ if (lower.endsWith('-integration.md'))
14
17
  types.push('integration');
15
18
  if (/live-.*-interaction|voice-/.test(lower))
16
19
  types.push('feature');
@@ -26,6 +29,29 @@ const DIR_TO_FRAMEWORK = {
26
29
  function normalizeFrameworkDir(dir) {
27
30
  return DIR_TO_FRAMEWORK[dir] ?? dir;
28
31
  }
32
+ function inferDocMeta(fileName) {
33
+ const lower = fileName.toLowerCase();
34
+ if (lower === 'capability-matrix.md') {
35
+ return { doc_kind: 'capability_matrix' };
36
+ }
37
+ if (lower === 'unsupported-features.md') {
38
+ return { doc_kind: 'unsupported_summary', capability_status: 'unsupported' };
39
+ }
40
+ if (lower.endsWith('-unsupported.md')) {
41
+ return { doc_kind: 'negative_faq', capability_status: 'unsupported' };
42
+ }
43
+ return {};
44
+ }
45
+ function inferShareScope(fileName) {
46
+ const lower = fileName.toLowerCase();
47
+ if (lower === 'usersig.md') {
48
+ return [
49
+ 'usersig', 'sdkappid', 'secretkey', 'sdk 密钥', '鉴权', '签名',
50
+ 'gentestusersig', 'tls', 'hmac',
51
+ ];
52
+ }
53
+ return 'always';
54
+ }
29
55
  export function inferPathMeta(relativeSource) {
30
56
  const normalized = relativeSource.replace(/\\/g, '/');
31
57
  const parts = normalized.split('/');
@@ -35,7 +61,18 @@ export function inferPathMeta(relativeSource) {
35
61
  let framework = ['*'];
36
62
  let types = corpus === 'integration' ? ['integration'] : [];
37
63
  let scenario = null;
38
- if (normalized.startsWith('knowledge/chat/') || normalized.startsWith('integration/chat/')) {
64
+ let variant;
65
+ let doc_kind;
66
+ let capability_status;
67
+ let retrievable_scope;
68
+ if (normalized.startsWith('knowledge/share/')) {
69
+ // 通配语料(跨产品共享)显式建模,不再依赖默认兜底路径。
70
+ product = '*';
71
+ framework = ['*'];
72
+ types.push('faq', 'product');
73
+ retrievable_scope = inferShareScope(fileName);
74
+ }
75
+ else if (normalized.startsWith('knowledge/chat/') || normalized.startsWith('integration/chat/')) {
39
76
  product = 'chat';
40
77
  if (parts.includes('preset') && parts.length >= 4) {
41
78
  framework = [normalizeFrameworkDir(parts[parts.indexOf('preset') + 1])];
@@ -67,6 +104,22 @@ export function inferPathMeta(relativeSource) {
67
104
  }
68
105
  }
69
106
  }
107
+ // chat FAQ / best-practice 平台拆分:
108
+ // - 新结构:knowledge/chat/best-practice/{platform}/{topic}.md
109
+ // - 旧结构:knowledge/chat/faq/{platform}.md(保留兼容)
110
+ // 两者都统一标记为 types=['faq'],便于通过 types=faq 命中“经验类问答”。
111
+ if (parts[1] === 'chat' && parts[2] === 'best-practice' && parts.length >= 5) {
112
+ const fwSlug = normalizeFrameworkDir(parts[3]);
113
+ framework = [fwSlug];
114
+ types.push('faq');
115
+ }
116
+ if (parts[1] === 'chat' && parts[2] === 'faq' && parts.length >= 4) {
117
+ const fwSlug = fileName.replace(/\.mdx?$/, '');
118
+ if (fwSlug) {
119
+ framework = [fwSlug];
120
+ types.push('faq');
121
+ }
122
+ }
70
123
  if (fileName === 'faq.md')
71
124
  types.push('faq');
72
125
  }
@@ -74,10 +127,24 @@ export function inferPathMeta(relativeSource) {
74
127
  product = 'call';
75
128
  const presetIdx = parts.indexOf('preset');
76
129
  const coreIdx = parts.indexOf('core-sdk');
77
- if (presetIdx >= 0 && parts[presetIdx + 1])
130
+ if (presetIdx >= 0 && parts[presetIdx + 1]) {
78
131
  framework = [normalizeFrameworkDir(parts[presetIdx + 1])];
79
- if (coreIdx >= 0 && parts[coreIdx + 1])
132
+ variant = 'preset';
133
+ }
134
+ if (coreIdx >= 0 && parts[coreIdx + 1]) {
80
135
  framework = [normalizeFrameworkDir(parts[coreIdx + 1])];
136
+ variant = 'core-sdk';
137
+ }
138
+ // callkit 最佳实践目录:knowledge/callkit/best-practice/{platform}/{topic}.md
139
+ // 统一按 FAQ/经验类知识处理,支持 types=faq + frameworks={platform} 的精确检索。
140
+ if (parts[1] === 'callkit' && parts[2] === 'best-practice' && parts.length >= 5) {
141
+ framework = [normalizeFrameworkDir(parts[3])];
142
+ types.push('faq');
143
+ // calls 相关最佳实践既是 FAQ 也是 API 语义,避免 types=api 时被误过滤。
144
+ if (/(callengine-invitation|callkit-call-vs-calls)\.md$/i.test(fileName)) {
145
+ types.push('api');
146
+ }
147
+ }
81
148
  if (parts.includes('faq'))
82
149
  types.push('faq', 'error_code');
83
150
  if (fileName === 'api.md')
@@ -86,29 +153,87 @@ export function inferPathMeta(relativeSource) {
86
153
  types.push('api', 'feature');
87
154
  }
88
155
  else if (normalized.includes('/livekit/')) {
156
+ // livekit 目录结构:
157
+ // preset/{framework}/ → 旧结构(如 preset/vue)
158
+ // preset/{scenario}/{platform}/ → 新结构(如 preset/live/android)
159
+ // core-sdk/live/{platform}/*.md → 视频直播 core 文档(framework 标签: [live, platform],types=[core])
160
+ // core-sdk/voice/{platform}/*.md → 语聊房 core 文档(framework 标签: [voice, platform],types=[core])
161
+ // core-sdk/features/{platform}/*.md → 跨场景功能模块(framework 标签: [features, platform],types=[feature])
162
+ // core-sdk/api-reference/{platform}/*.md → 客户端 API(framework 标签: [platform],types=[api])
163
+ // 写写上"功能模块"是 video live / voice 共享节点,所以 features/ 下文档 type=feature 而非 core
89
164
  product = 'live';
90
165
  if (parts.includes('voice'))
91
166
  scenario = 'voice';
92
- if (parts.includes('/live/'))
167
+ if (parts.includes('live'))
93
168
  scenario = 'live';
94
- if (parts.includes('preset') && parts.includes('vue'))
95
- framework = ['vue'];
96
- if (parts.includes('core-sdk') && parts.length >= 4) {
97
- const fwIdx = parts.indexOf('core-sdk') + 2;
98
- if (parts[fwIdx] && !['live', 'voice'].includes(parts[fwIdx])) {
99
- framework = [normalizeFrameworkDir(parts[fwIdx])];
169
+ const presetIdx = parts.indexOf('preset');
170
+ const coreIdx = parts.indexOf('core-sdk');
171
+ if (presetIdx >= 0 && parts[presetIdx + 1]) {
172
+ const presetLevel1 = normalizeFrameworkDir(parts[presetIdx + 1]);
173
+ const presetLevel2 = parts[presetIdx + 2] ? normalizeFrameworkDir(parts[presetIdx + 2]) : undefined;
174
+ // 兼容两种 preset 目录:
175
+ // - preset/{framework}(旧)
176
+ // - preset/{scenario}/{platform}(新)
177
+ if ((presetLevel1 === 'live' || presetLevel1 === 'voice') && presetLevel2) {
178
+ scenario = presetLevel1;
179
+ framework = [presetLevel2];
180
+ }
181
+ else {
182
+ framework = [presetLevel1];
183
+ }
184
+ variant = 'preset';
185
+ types.push('feature');
186
+ }
187
+ if (coreIdx >= 0 && parts.length >= 4) {
188
+ // core-sdk 下的 4 个子目录(live/voice/features/api-reference),每个下挂 platform 子目录
189
+ const sub = parts[coreIdx + 1];
190
+ const platform = parts[coreIdx + 2];
191
+ if (sub === 'live' && platform) {
192
+ framework = ['live', normalizeFrameworkDir(platform)];
193
+ types.push('core');
194
+ if (fileName === 'integration.md') {
195
+ types.push('api', 'integration');
196
+ }
197
+ variant = 'core-sdk';
198
+ }
199
+ else if (sub === 'voice' && platform) {
200
+ framework = ['voice', normalizeFrameworkDir(platform)];
201
+ types.push('core');
202
+ if (fileName === 'integration.md') {
203
+ types.push('api', 'integration');
204
+ }
205
+ variant = 'core-sdk';
206
+ }
207
+ else if (sub === 'features' && platform) {
208
+ framework = ['features', normalizeFrameworkDir(platform)];
209
+ types.push('feature');
210
+ variant = 'core-sdk';
211
+ }
212
+ else if (sub === 'api-reference' && platform) {
213
+ // api-reference 沿用旧逻辑:framework = platform,types = api
214
+ framework = [normalizeFrameworkDir(platform)];
215
+ types.push('api');
216
+ variant = 'core-sdk';
217
+ }
218
+ else {
219
+ // 兜底(不在 4 个已知子目录下):framework = 子目录名
220
+ framework = [normalizeFrameworkDir(sub ?? '*')];
221
+ variant = 'core-sdk';
222
+ types.push('feature', 'api');
100
223
  }
101
224
  }
102
- if (parts.includes('components') || (parts.includes('features') && parts.includes('preset')))
225
+ if (parts.includes('components'))
103
226
  types.push('component');
104
- if (parts.includes('api-reference'))
105
- types.push('api');
106
- if (parts.includes('core-sdk'))
107
- types.push('feature', 'api');
108
- if (parts.includes('faq'))
109
- types.push('faq', 'error_code');
110
227
  if (fileName === 'faq.md')
111
228
  types.push('faq');
229
+ // 与 roomkit 对齐:core-sdk 下 capability-matrix.md / unsupported-features.md
230
+ // 视为能力边界文档(doc_kind + capability_status),方便检索层按 doc_kind 过滤
231
+ const docMeta = inferDocMeta(fileName);
232
+ doc_kind = docMeta.doc_kind;
233
+ capability_status = docMeta.capability_status ?? capability_status;
234
+ if (doc_kind === 'capability_matrix' || doc_kind === 'unsupported_summary' || doc_kind === 'negative_faq') {
235
+ types.push('feature', 'faq');
236
+ }
112
237
  }
113
238
  else if (normalized.includes('/roomkit/')) {
114
239
  product = 'room';
@@ -116,14 +241,26 @@ export function inferPathMeta(relativeSource) {
116
241
  const coreIdx = parts.indexOf('core-sdk');
117
242
  if (presetIdx >= 0 && parts[presetIdx + 1]) {
118
243
  framework = [normalizeFrameworkDir(parts[presetIdx + 1])];
244
+ variant = 'preset';
119
245
  }
120
246
  if (coreIdx >= 0 && parts[coreIdx + 1]) {
121
247
  framework = [normalizeFrameworkDir(parts[coreIdx + 1])];
248
+ variant = 'core-sdk';
249
+ types.push('feature');
250
+ if (framework[0] === 'vue') {
251
+ capability_status = 'supported';
252
+ }
122
253
  }
123
- if (parts.includes('features') || parts.includes('core-sdk'))
254
+ if (parts.includes('features'))
124
255
  types.push('feature');
125
256
  if (parts.includes('faq'))
126
257
  types.push('faq', 'error_code');
258
+ const docMeta = inferDocMeta(fileName);
259
+ doc_kind = docMeta.doc_kind;
260
+ capability_status = docMeta.capability_status ?? capability_status;
261
+ if (doc_kind === 'capability_matrix' || doc_kind === 'unsupported_summary' || doc_kind === 'negative_faq') {
262
+ types.push('feature', 'faq');
263
+ }
127
264
  }
128
265
  else if (normalized.startsWith('knowledge/trtc/')) {
129
266
  product = 'native_trtc_sdk';
@@ -141,25 +278,32 @@ export function inferPathMeta(relativeSource) {
141
278
  // push 结构:
142
279
  // knowledge/push/overview/{topic}.md → 跨平台综述(接入前准备/流程/选型/计费等),framework=*,types=[product]
143
280
  // knowledge/push/integration/{platform}.md → framework=平台 slug,types=[integration]
144
- // knowledge/push/config/{platform}.md → 与写写平台级配置页保持一致,framework=平台 slug,types=[integration]
281
+ // knowledge/push/config/android/{vendor}.md → framework=android(vendor 厂商靠 BM25 命中),types=[integration]
282
+ // knowledge/push/api-reference/{platform}.md → framework=平台 slug,types=[api]
145
283
  product = 'push';
146
- const category = parts[2]; // overview | integration | config
284
+ const category = parts[2]; // overview | integration | config | api-reference
147
285
  if (category === 'overview') {
148
286
  framework = ['*'];
149
287
  types.push('product');
150
288
  }
151
289
  else if (category === 'integration') {
152
- const fwSlug = fileName.replace(/\.mdx?$/, ''); // android / ios / donut / ...
290
+ const fwSlug = fileName.replace(/\.mdx?$/, '');
153
291
  if (fwSlug) {
154
292
  framework = [fwSlug];
155
293
  }
156
294
  types.push('integration');
157
295
  }
158
- else if (category === 'config') {
159
- // config/{platform}.md:与写写平台级配置页 1:1 对齐(Android 厂商信息收敛在 android.md 正文内)
160
- const platform = (parts[3] ?? fileName).replace(/\.mdx?$/, '');
296
+ else if (category === 'config' && parts[3]) {
297
+ const platform = parts[3].replace(/\.mdx?$/, '');
161
298
  framework = [platform];
162
- types.push('integration', 'config');
299
+ types.push('integration');
300
+ }
301
+ else if (category === 'api-reference') {
302
+ const fwSlug = fileName.replace(/\.mdx?$/, '');
303
+ if (fwSlug) {
304
+ framework = [fwSlug];
305
+ }
306
+ types.push('api');
163
307
  }
164
308
  else {
165
309
  types.push('integration');
@@ -174,11 +318,20 @@ export function inferPathMeta(relativeSource) {
174
318
  types = inferTypesFromFilename(fileName, types);
175
319
  if (types.length === 0)
176
320
  types = ['faq'];
321
+ const primaryFramework = framework[0];
322
+ const scope = product !== '*' && variant && primaryFramework && primaryFramework !== '*'
323
+ ? `${product}:${variant}:${primaryFramework}`
324
+ : undefined;
177
325
  return {
178
326
  product,
179
327
  framework,
180
328
  types: uniq(types),
181
329
  scenario,
182
330
  corpus,
331
+ variant,
332
+ scope,
333
+ doc_kind,
334
+ capability_status,
335
+ retrievable_scope,
183
336
  };
184
337
  }
@@ -272,6 +272,50 @@ function loadFeatureAliases() {
272
272
  }
273
273
  return result;
274
274
  }
275
+ const ROOM_CORE_SIGNAL = /atomicx\s*core|atomicxcore|atomicx|core\s*sdk|no\s*ui|custom\s*ui|self\s*implement|roomstore|store|useRoomState|useDeviceState|useLoginState|无\s*ui|自定义\s*ui|自实现/i;
276
+ const ROOM_PRESET_SIGNAL = /preset|roommainview|roommainwidget|default\s*ui|main\s*page|预制|默认\s*ui|主页面|房间主页面/i;
277
+ const ROOM_FEATURE_SPECS = [
278
+ {
279
+ fileName: 'room-chat.md',
280
+ titlePattern: /room\s*chat|in-room\s*im\s*chat|会中聊天|聊天能力|im\s*chat/i,
281
+ promptPattern: /room\s*chat|会中聊天|in[- ]room\s*(im\s*)?chat|im\s*chat|messagelist|messageinput|messagestore|聊天面板|房间聊天/i,
282
+ },
283
+ {
284
+ fileName: 'screen-share.md',
285
+ titlePattern: /screen\s*share|屏幕分享/i,
286
+ promptPattern: /screen\s*share|屏幕分享|共享屏幕|startScreenShare/i,
287
+ },
288
+ {
289
+ fileName: 'virtual-background.md',
290
+ titlePattern: /virtual\s*background|虚拟背景/i,
291
+ promptPattern: /virtual\s*background|虚拟背景|背景虚化|背景替换|initVirtualBackground/i,
292
+ },
293
+ {
294
+ fileName: 'room-view.md',
295
+ titlePattern: /roomview|room\s*view|房间主视图|视频布局/i,
296
+ promptPattern: /roomview|room\s*view|房间主视图|视频布局|画面布局|layoutTemplate/i,
297
+ },
298
+ {
299
+ fileName: 'device-detection.md',
300
+ titlePattern: /device\s*detection|设备检测|设备预览/i,
301
+ promptPattern: /device\s*detection|设备检测|设备预览|startCameraTest|startMicrophoneTest|startSpeakerTest/i,
302
+ },
303
+ {
304
+ fileName: 'device-state.md',
305
+ titlePattern: /device\s*state|设备状态|设备管理/i,
306
+ promptPattern: /device\s*state|设备状态|设备管理|摄像头|麦克风|扬声器|switchMirror|setCurrentCamera|networkInfo/i,
307
+ },
308
+ {
309
+ fileName: 'free-beauty-panel.md',
310
+ titlePattern: /free\s*beauty|美颜面板|基础美颜/i,
311
+ promptPattern: /free\s*beauty|美颜面板|基础美颜|beauty/i,
312
+ },
313
+ ];
314
+ function detectRoomFeatureHits(prompt) {
315
+ return ROOM_FEATURE_SPECS.filter((spec) => spec.promptPattern.test(prompt));
316
+ }
317
+ const LIVE_LIFECYCLE_PROMPT = /create\s*live|end\s*live|join\s*live|leave\s*live|start\s*live|stop\s*live|watch\s*live|host_streaming|audience_streaming|开播|创建直播|结束直播|停播|观看直播|退出直播|进房|离房|createLive|endLive|joinLive|leaveLive/i;
318
+ const LIVE_LIFECYCLE_APIS = ['createLive', 'endLive', 'joinLive', 'leaveLive'];
275
319
  export function runExactLookup(prompt, pool, norm) {
276
320
  const boosts = {};
277
321
  const exactHits = [];
@@ -281,6 +325,9 @@ export function runExactLookup(prompt, pool, norm) {
281
325
  if (!exactHits.includes(label))
282
326
  exactHits.push(label);
283
327
  };
328
+ const addPenalty = (chunk, amount) => {
329
+ boosts[chunk.id] = (boosts[chunk.id] ?? 0) - Math.abs(amount);
330
+ };
284
331
  // E1: error codes
285
332
  const errorMatches = [
286
333
  ...prompt.matchAll(/\b(\d{5,7})\b/g),
@@ -493,5 +540,111 @@ export function runExactLookup(prompt, pool, norm) {
493
540
  }
494
541
  }
495
542
  }
543
+ // E11: LiveKit lifecycle strong recall
544
+ if (norm.product?.includes('live') && LIVE_LIFECYCLE_PROMPT.test(prompt)) {
545
+ const queryApiHits = LIVE_LIFECYCLE_APIS.filter((api) => new RegExp(api, 'i').test(prompt));
546
+ for (const chunk of pool) {
547
+ const isLiveCoreIntegration = chunk.source.startsWith('knowledge/livekit/core-sdk/live/')
548
+ && chunk.source.endsWith('/integration.md');
549
+ const isVoiceCoreIntegration = chunk.source.startsWith('knowledge/livekit/core-sdk/voice/')
550
+ && chunk.source.endsWith('/integration.md');
551
+ if (!isLiveCoreIntegration && !isVoiceCoreIntegration)
552
+ continue;
553
+ if (norm.scenario === 'live' && !isLiveCoreIntegration)
554
+ continue;
555
+ if (norm.scenario === 'voice' && !isVoiceCoreIntegration)
556
+ continue;
557
+ addBoost(chunk, 140, 'E11:live-lifecycle-core-integration');
558
+ for (const api of queryApiHits) {
559
+ if (chunk.api_names?.some((name) => name.toLowerCase() === api.toLowerCase())) {
560
+ addBoost(chunk, 160, `E11:live-lifecycle-api:${api}`);
561
+ }
562
+ }
563
+ }
564
+ }
565
+ // E10: RoomKit Core/Preset disambiguation + unsupported feature routing
566
+ if (norm.product?.includes('room') && norm.frameworks?.length) {
567
+ const platform = norm.frameworks.find((fw) => ['android', 'ios', 'flutter', 'vue'].includes(fw));
568
+ const featureHits = detectRoomFeatureHits(prompt);
569
+ const coreIntent = ROOM_CORE_SIGNAL.test(prompt) || !ROOM_PRESET_SIGNAL.test(prompt);
570
+ const presetIntent = ROOM_PRESET_SIGNAL.test(prompt) && !ROOM_CORE_SIGNAL.test(prompt);
571
+ if (platform) {
572
+ const coreScope = `room:core-sdk:${platform}`;
573
+ const presetScope = `room:preset:${platform}`;
574
+ for (const chunk of pool) {
575
+ if (chunk.product !== 'room')
576
+ continue;
577
+ if (chunk.scope === coreScope) {
578
+ addBoost(chunk, 40, `E10:room-core-scope:${platform}`);
579
+ if (platform !== 'vue' && chunk.doc_kind === 'capability_matrix') {
580
+ addBoost(chunk, 120, `E10:room-matrix:${platform}`);
581
+ }
582
+ }
583
+ if (coreIntent && chunk.scope === presetScope) {
584
+ addPenalty(chunk, 120);
585
+ }
586
+ if (presetIntent && chunk.scope === coreScope && chunk.capability_status === 'unsupported') {
587
+ addPenalty(chunk, 180);
588
+ }
589
+ }
590
+ for (const feature of featureHits) {
591
+ for (const chunk of pool) {
592
+ if (chunk.product !== 'room')
593
+ continue;
594
+ if (platform === 'vue' && chunk.scope === coreScope && chunk.source.endsWith(feature.fileName)) {
595
+ addBoost(chunk, 220, `E10:room-vue-feature:${feature.fileName}`);
596
+ }
597
+ if (platform !== 'vue' && chunk.scope === coreScope) {
598
+ if (chunk.source.endsWith('unsupported-features.md') && feature.titlePattern.test(chunk.title)) {
599
+ addBoost(chunk, 280, `E10:room-unsupported:${platform}:${feature.fileName}`);
600
+ }
601
+ if (chunk.doc_kind === 'capability_matrix') {
602
+ addBoost(chunk, 120, `E10:room-matrix:${platform}:${feature.fileName}`);
603
+ }
604
+ }
605
+ }
606
+ }
607
+ }
608
+ }
609
+ // E12/E13: CallKit type disambiguation + calls best-practice boost
610
+ if (norm.product?.includes('call')) {
611
+ const isStatusIntent = /statuschanged|\bstatus\b|callmediatype|media\s*type|通话状态|状态回调/i.test(prompt);
612
+ const isStoreIntent = /callstatus|callrole|iuserinfo|storename\.?call|store|name\s*constant|enum\s*value|field\s*definition|字段定义/i.test(prompt);
613
+ const isEngineInvitationIntent = /tuicallengine|on_call_received|call\s*invitation|incoming\s*call|accept\(|reject\(|accept\s*call|reject\s*call|inviteid|userData|邀请|来电|接听|拒接|信令/i.test(prompt);
614
+ const isCallkitDiffIntent = /\bcall\s*vs\s*calls\b|\bcalls?\b|groupcall|tuicallkitapi\.calls|tuicallkitserver\.call|tuicallkitserver\.groupcall|\bv4(\.x)?\b|useridlist|chatgroupid|发起(单人|多人)?通话|呼叫|拨打/i.test(prompt);
615
+ const isLogIntent = /setloglevel|log\s*level|disable\s*log|console\s*log|日志级别|关闭\s*log/i.test(prompt);
616
+ for (const chunk of pool) {
617
+ if (chunk.product !== 'call')
618
+ continue;
619
+ const source = chunk.source.toLowerCase();
620
+ if (isStatusIntent && source.includes('knowledge/callkit/preset/vue/uikit-api-reference.md')) {
621
+ addBoost(chunk, 180, 'E12:callkit-vue-status');
622
+ }
623
+ if (isStoreIntent && source.includes('knowledge/callkit/core-sdk/web/')) {
624
+ addBoost(chunk, 220, 'E12:callkit-core-store');
625
+ }
626
+ if (isStoreIntent && source.includes('knowledge/callkit/preset/vue/')) {
627
+ addPenalty(chunk, 80);
628
+ }
629
+ if (isEngineInvitationIntent && source.includes('knowledge/callkit/best-practice/web/callengine-invitation.md')) {
630
+ addBoost(chunk, 300, 'E13A:callengine-invitation');
631
+ }
632
+ if (isEngineInvitationIntent && source.includes('knowledge/callkit/best-practice/web/callkit-call-vs-calls.md')) {
633
+ addPenalty(chunk, 80);
634
+ }
635
+ if (isCallkitDiffIntent && source.includes('knowledge/callkit/best-practice/web/callkit-call-vs-calls.md')) {
636
+ addBoost(chunk, 300, 'E13B:callkit-call-vs-calls');
637
+ }
638
+ if (isCallkitDiffIntent && source.includes('knowledge/callkit/best-practice/web/callengine-invitation.md')) {
639
+ addPenalty(chunk, 80);
640
+ }
641
+ if (isCallkitDiffIntent && source.includes('knowledge/callkit/preset/vue/uikit-api-reference.md')) {
642
+ addPenalty(chunk, 40);
643
+ }
644
+ if (isLogIntent && source.includes('knowledge/callkit/best-practice/web/callengine-log-control.md')) {
645
+ addBoost(chunk, 260, 'E13:callengine-log-control');
646
+ }
647
+ }
648
+ }
496
649
  return { boosts, exactHits };
497
650
  }