@tencentcloud/sdk-mcp 1.6.0-beta.3 → 1.6.1

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 (40) hide show
  1. package/README.md +1 -1
  2. package/cursor-setting.png +0 -0
  3. package/knowledge/build-index.js +4 -0
  4. package/knowledge/content-loader.js +3 -0
  5. package/knowledge/doc-url-resolver.js +118 -0
  6. package/knowledge/path-meta.js +4 -2
  7. package/knowledge/search/exact-lookup.js +1 -1
  8. package/knowledge/search/filter-pool.js +25 -7
  9. package/knowledge/search/product-scope-intent.js +40 -0
  10. package/knowledge/search/requires-framework.js +15 -6
  11. package/knowledge/search/search-knowledge.js +17 -6
  12. package/mcp-server-prompt.png +0 -0
  13. package/package.json +1 -1
  14. package/resource/index/component-slugs.json +1 -1
  15. package/resource/index/doc-source-urls.json +1 -0
  16. package/resource/index/manifest.json +1 -1
  17. package/resource/integration/chat/preset/uni-app/integration.md +2 -2
  18. package/resource/integration/chat/preset/vue/integration.md +12 -0
  19. package/resource/knowledge/callkit/faq/common.md +1 -1
  20. package/resource/knowledge/chat/preset/android-view/integration.md +0 -140
  21. package/resource/knowledge/chat/urls/restapi.md +0 -1
  22. package/resource/knowledge/push/config/donut.md +445 -0
  23. package/resource/knowledge/push/config/harmonyos.md +87 -0
  24. package/resource/knowledge/push/config/ios.md +341 -0
  25. package/resource/knowledge/push/config/react-native.md +205 -0
  26. package/resource/knowledge/push/config/unity.md +199 -0
  27. package/resource/knowledge/push/config/unreal-engine.md +199 -0
  28. package/resource/knowledge/push/integration/harmonyos.md +1 -1
  29. package/resource/knowledge/push/integration/uni-app.md +8 -0
  30. package/resource/knowledge/rtcengine/web/plugin/24-advanced-network-quality.md +2 -2
  31. package/server.js +14 -1
  32. package/tools/common/record_answer.js +3 -3
  33. package/tools/common/record_feedback.js +1 -1
  34. package/tools/common/search_trtc_knowledge.js +1 -1
  35. package/tools/definitions/record_answer_def.js +8 -7
  36. package/tools/definitions/record_feedback_def.js +2 -2
  37. package/tools/definitions/search_trtc_knowledge_def.js +23 -55
  38. package/utils/report-cls-client.js +4 -4
  39. package/utils/report-es-client.js +1 -1
  40. package/utils/report-runtime-error-cls-client.js +0 -90
package/README.md CHANGED
@@ -41,7 +41,7 @@ npx -y @tencentcloud/sdk-mcp
41
41
  "mcpServers": {
42
42
  "tencentcloud-sdk-mcp": {
43
43
  "command": "npx",
44
- "args": ["-y", "@tencentcloud/sdk-mcp"],
44
+ "args": ["-y", "@tencentcloud/sdk-mcp@latest"],
45
45
  "env": {
46
46
  "SDKAPPID": "YOUR_SDKAPPID",
47
47
  "SECRETKEY": "YOUR_SECRET_KEY"
Binary file
@@ -2,6 +2,7 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { chunkMarkdown, toManifestChunk } from './chunker.js';
5
+ import { buildDocSourceUrlMap } from './doc-url-resolver.js';
5
6
  import { inferPathMeta } from './path-meta.js';
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
8
  const RESOURCE_ROOT = path.resolve(__dirname, '../resource');
@@ -57,6 +58,9 @@ export function buildKnowledgeIndex() {
57
58
  const componentSlugs = collectComponentSlugs(chunks);
58
59
  fs.writeFileSync(path.join(indexDir, 'manifest.json'), JSON.stringify(manifest));
59
60
  fs.writeFileSync(path.join(indexDir, 'component-slugs.json'), JSON.stringify(componentSlugs));
61
+ const syncManifestPath = path.resolve(__dirname, '../../sync/sync-manifest.json');
62
+ const docSourceUrls = buildDocSourceUrlMap(syncManifestPath);
63
+ fs.writeFileSync(path.join(indexDir, 'doc-source-urls.json'), JSON.stringify(docSourceUrls));
60
64
  const staleSearchIndex = path.join(indexDir, 'search-index.json');
61
65
  if (fs.existsSync(staleSearchIndex)) {
62
66
  fs.unlinkSync(staleSearchIndex);
@@ -16,6 +16,9 @@ function readSourceFile(source) {
16
16
  fileCache.set(source, text);
17
17
  return text;
18
18
  }
19
+ export function getSourceFileContent(source) {
20
+ return readSourceFile(source);
21
+ }
19
22
  /** 按 build 时写入的 char 偏移从 md 源文件切片(方案 B:manifest 不存 content) */
20
23
  export function getChunkContent(chunk) {
21
24
  const full = readSourceFile(chunk.source);
@@ -0,0 +1,118 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
+ /** 控制台/购买页等不适合作为「参考文档」的链接 */
6
+ const NOISE_URL_RE = /console\.cloud\.tencent|buy\.cloud\.tencent|account\.renewal|edu\/learning/i;
7
+ const PREFERRED_DOC_HOST_RE = /cloud\.tencent\.com|web\.sdk\.qcloud\.com|github\.com\/Tencent(?:Cloud|RTC)/i;
8
+ let cachedSourceUrlMap = null;
9
+ function loadSourceUrlMap() {
10
+ if (cachedSourceUrlMap)
11
+ return cachedSourceUrlMap;
12
+ const mapPath = path.resolve(__dirname, '../resource/index/doc-source-urls.json');
13
+ if (!fs.existsSync(mapPath)) {
14
+ cachedSourceUrlMap = {};
15
+ return cachedSourceUrlMap;
16
+ }
17
+ cachedSourceUrlMap = JSON.parse(fs.readFileSync(mapPath, 'utf-8'));
18
+ return cachedSourceUrlMap;
19
+ }
20
+ function normalizeUrl(raw) {
21
+ return raw.replace(/[.,;)\]]+$/, '').trim();
22
+ }
23
+ function isUsefulDocUrl(url) {
24
+ if (!/^https?:\/\//i.test(url))
25
+ return false;
26
+ if (NOISE_URL_RE.test(url))
27
+ return false;
28
+ return true;
29
+ }
30
+ /** 从 markdown 正文中提取可参考的官网链接(优先 cloud.tencent / web.sdk.qcloud) */
31
+ export function extractUrlsFromContent(content, max = 3) {
32
+ const found = [];
33
+ const preferred = [];
34
+ for (const match of content.matchAll(/https?:\/\/[^\s`|)\]"'>]+/g)) {
35
+ const url = normalizeUrl(match[0]);
36
+ if (!isUsefulDocUrl(url))
37
+ continue;
38
+ if (PREFERRED_DOC_HOST_RE.test(url)) {
39
+ if (!preferred.includes(url))
40
+ preferred.push(url);
41
+ }
42
+ else if (!found.includes(url)) {
43
+ found.push(url);
44
+ }
45
+ }
46
+ const merged = [...preferred, ...found];
47
+ return merged.slice(0, max);
48
+ }
49
+ /** L1 URL 映射 chunk:表格行中的目标文档 URL */
50
+ export function extractUrlMappingPrimaryUrl(content) {
51
+ const row = content.match(/\|\s*[^|]+\s*\|\s*`?(https?:\/\/[^|`\s]+)`?\s*\|/);
52
+ return row?.[1] ? normalizeUrl(row[1]) : null;
53
+ }
54
+ function isUrlMappingSource(source) {
55
+ return /knowledge\/chat\/urls\/.+\.md$/i.test(source.replace(/\\/g, '/'));
56
+ }
57
+ /**
58
+ * 为检索 fragment 解析可参考的官网 URL(去重、按优先级)。
59
+ * 1. sync-manifest 落盘的 localPath → 官网 URL(rtcengine 等)
60
+ * 2. L1 URL 映射行内目标 URL
61
+ * 3. 本地文档正文中的官网链接
62
+ */
63
+ export function resolveFragmentDocUrls(source, content, fullSourceContent) {
64
+ const normalized = source.replace(/\\/g, '/');
65
+ const urls = [];
66
+ const canonical = loadSourceUrlMap()[normalized];
67
+ if (canonical)
68
+ urls.push(canonical);
69
+ if (isUrlMappingSource(normalized)) {
70
+ const primary = extractUrlMappingPrimaryUrl(content);
71
+ if (primary && !urls.includes(primary))
72
+ urls.push(primary);
73
+ return urls;
74
+ }
75
+ const collect = (text) => {
76
+ for (const url of extractUrlsFromContent(text)) {
77
+ if (!urls.includes(url))
78
+ urls.push(url);
79
+ }
80
+ };
81
+ collect(content);
82
+ if (urls.length === 0 && fullSourceContent && fullSourceContent !== content) {
83
+ collect(fullSourceContent);
84
+ }
85
+ return urls.slice(0, 3);
86
+ }
87
+ /** 从 fragments 汇总去重后的参考链接列表(按 fragment 相关度排序) */
88
+ export function buildReferences(fragments) {
89
+ const refs = [];
90
+ const seen = new Set();
91
+ for (const fragment of fragments) {
92
+ for (const url of fragment.doc_urls) {
93
+ if (seen.has(url))
94
+ continue;
95
+ seen.add(url);
96
+ refs.push({
97
+ rank: refs.length + 1,
98
+ title: fragment.title,
99
+ url,
100
+ source: fragment.source,
101
+ });
102
+ }
103
+ }
104
+ return refs;
105
+ }
106
+ /** build 时从 sync-manifest 生成 localPath → 官网 URL 映射 */
107
+ export function buildDocSourceUrlMap(syncManifestPath) {
108
+ if (!fs.existsSync(syncManifestPath))
109
+ return {};
110
+ const manifest = JSON.parse(fs.readFileSync(syncManifestPath, 'utf-8'));
111
+ const map = {};
112
+ for (const entry of Object.values(manifest.entries ?? {})) {
113
+ if (entry.nodeId?.startsWith('http') && entry.localPath) {
114
+ map[entry.localPath.replace(/\\/g, '/')] = entry.nodeId;
115
+ }
116
+ }
117
+ return map;
118
+ }
@@ -148,8 +148,10 @@ export function inferPathMeta(relativeSource) {
148
148
  types.push('integration');
149
149
  }
150
150
  else if (category === 'config' && parts[3]) {
151
- // config/{platform}/{vendor}.md:platform 决定 framework,vendor 靠关键词
152
- framework = [parts[3]];
151
+ // config/{platform}/{vendor}.md(Android 厂商)或 config/{platform}.md(非 Android 平台配置)
152
+ // platform 决定 framework,vendor 靠 BM25 命中
153
+ const platform = parts[3].replace(/\.mdx?$/, '');
154
+ framework = [platform];
153
155
  types.push('integration');
154
156
  }
155
157
  else {
@@ -248,7 +248,7 @@ export function runExactLookup(prompt, pool, norm) {
248
248
  }
249
249
  }
250
250
  }
251
- const errorCodeIntent = /错误码/i.test(prompt) || errorMatches.length > 0 || norm.types?.includes('error_code');
251
+ const errorCodeIntent = /错误码/i.test(prompt) || errorMatches.length > 0 || norm.searchIntent?.includes('error_code');
252
252
  if (errorCodeIntent) {
253
253
  for (const chunk of pool) {
254
254
  if (chunk.source.includes('knowledge/chat/urls/error-code.md')) {
@@ -1,3 +1,4 @@
1
+ import { downgradeToProductType } from './product-scope-intent.js';
1
2
  /**
2
3
  * MCP framework enum → index 中对应的 framework 值列表。
3
4
  * path-meta.ts 已通过 normalizeFrameworkDir 把目录名归一到标准 framework,
@@ -12,15 +13,31 @@ function expandFrameworks(framework) {
12
13
  return ['react', 'vue', 'web'];
13
14
  return FRAMEWORK_SEARCH_ALIASES[framework] ?? [framework];
14
15
  }
15
- /** Chat 无独立 faq.md;types 含 faq 时改为检索 knowledge/chat 全语料(feature/component/urls 等) */
16
- function resolveTypes(products, types) {
16
+ /**
17
+ * 类型别名:UIKit「组件(component)」与「feature」是同一批文档的两种叫法
18
+ * (chat preset 双标签,roomkit/live/call 仅打 feature),互相放行避免 types 硬过滤误杀。
19
+ */
20
+ const TYPE_ALIASES = {
21
+ component: ['component', 'feature'],
22
+ feature: ['feature', 'component'],
23
+ };
24
+ function expandTypeAliases(types) {
25
+ const expanded = new Set();
26
+ for (const t of types) {
27
+ for (const alias of TYPE_ALIASES[t] ?? [t])
28
+ expanded.add(alias);
29
+ }
30
+ return [...expanded];
31
+ }
32
+ /** Chat 无独立 faq.md;types 含 faq 时退化到全语料检索(feature/component/urls 等均命中) */
33
+ function resolveTypes(products, types, prompt, framework) {
17
34
  if (!types?.length)
18
35
  return undefined;
19
- let resolved = [...types];
20
- if (products?.includes('chat') && resolved.includes('faq')) {
21
- resolved = resolved.filter((t) => t !== 'faq');
36
+ if (products?.includes('chat') && types.includes('faq')) {
37
+ return undefined;
22
38
  }
23
- return resolved.length ? resolved : undefined;
39
+ const downgraded = downgradeToProductType(products, types, prompt, framework);
40
+ return expandTypeAliases(downgraded);
24
41
  }
25
42
  /** 单平台产品的隐式 framework 推断:避免对显然唯一的平台再发起询问 */
26
43
  function inferImplicitFramework(products, framework) {
@@ -34,12 +51,13 @@ export function normalizeParams(params) {
34
51
  const limit = Math.min(Math.max(params.limit ?? 8, 1), 16);
35
52
  const effectiveFramework = inferImplicitFramework(params.product, params.framework);
36
53
  const frameworks = expandFrameworks(effectiveFramework);
37
- const types = resolveTypes(params.product, params.types);
54
+ const types = resolveTypes(params.product, params.types, params.prompt, effectiveFramework);
38
55
  return {
39
56
  prompt: params.prompt,
40
57
  product: params.product,
41
58
  framework: effectiveFramework,
42
59
  frameworks,
60
+ searchIntent: params.types,
43
61
  types,
44
62
  scenario: params.scenario,
45
63
  limit,
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Product-scope intent (routes to chat/urls/product.md, type=product).
3
+ *
4
+ * These questions are about the PRODUCT / account scope — billing, packages, console settings,
5
+ * account & data capabilities configured in the console, storage/retention, usage limits.
6
+ * They are cross-platform and must NOT require a framework.
7
+ *
8
+ * Detection keys on *intent* words (console / billing / limit / product-setting), NOT on
9
+ * capability nouns alone (e.g. "relationship chain", "group management"): those nouns are
10
+ * ambiguous and can also be client-SDK feature questions on a specific platform.
11
+ * A platform / SDK / "how to implement" signal disqualifies the product-scope interpretation.
12
+ */
13
+ const PRODUCT_SCOPE_INTENT = /控制台|计费|套餐|价格|退费|续费|配额|使用限制|数量限制|存储时长|漫游.{0,4}时长|多端登录|登录策略|console|dashboard|billing|pricing|package\s*(plan|feature|difference)|quota|usage\s*limit|multi[\s-]?device\s*login|login\s*(policy|strategy)|(message\s*)?storage\s*(duration|period)|retention/i;
14
+ const CLIENT_IMPL_SIGNAL = /\b(android|ios|flutter|harmonyos|react[\s-]?native|unity|unreal(\s*engine)?|donut|uni[\s-]?app)\b|\bSDK\b|\bAPI\b|怎么(实现|调用|集成|接入|写)|如何(实现|调用|集成|接入|写)|\b(implement|integrate)\b/i;
15
+ export function isProductScopePrompt(prompt) {
16
+ if (!PRODUCT_SCOPE_INTENT.test(prompt))
17
+ return false;
18
+ if (CLIENT_IMPL_SIGNAL.test(prompt))
19
+ return false;
20
+ return true;
21
+ }
22
+ /**
23
+ * When the Agent mislabels a product-scope question as `feature` (no framework given),
24
+ * rewrite the type to `product` so filterPool can hit chat/urls/product.md.
25
+ * If a framework is present, the Agent genuinely wants a client feature — do not downgrade.
26
+ */
27
+ export function downgradeToProductType(products, types, prompt, framework) {
28
+ if (framework)
29
+ return types;
30
+ if (!types.includes('feature'))
31
+ return types;
32
+ if (!products?.includes('chat'))
33
+ return types;
34
+ if (!isProductScopePrompt(prompt))
35
+ return types;
36
+ const downgraded = types.filter((t) => t !== 'feature');
37
+ if (!downgraded.includes('product'))
38
+ downgraded.push('product');
39
+ return downgraded;
40
+ }
@@ -1,3 +1,4 @@
1
+ import { isProductScopePrompt } from './product-scope-intent.js';
1
2
  const PLATFORM_TYPES = new Set([
2
3
  'api',
3
4
  'component',
@@ -25,13 +26,19 @@ const PUSH_OVERVIEW_PROMPT = /开通|创建\s*Push|创建应用|SDKAppID|控制
25
26
  function hasProduct(norm, p) {
26
27
  return !!(norm.product?.includes(p));
27
28
  }
29
+ /** chat/urls/product.md:产品/账号级配置,非客户端 SDK feature */
30
+ function isChatProductScopeQuery(norm) {
31
+ if (!hasProduct(norm, 'chat'))
32
+ return false;
33
+ return isProductScopePrompt(norm.prompt);
34
+ }
28
35
  /** chat error-code URL 同时列了「服务端 / Web / Native」三类入口,必须先问平台才能定位 */
29
36
  function isChatErrorCodeAmbiguous(norm) {
30
37
  if (!hasProduct(norm, 'chat'))
31
38
  return false;
32
39
  if (norm.framework)
33
40
  return false;
34
- if (norm.types?.includes('error_code'))
41
+ if (norm.searchIntent?.includes('error_code'))
35
42
  return true;
36
43
  return /错误码|error\s*code|ERR_/i.test(norm.prompt);
37
44
  }
@@ -44,7 +51,7 @@ export function requiresFramework(norm) {
44
51
  return true;
45
52
  // push:判定逻辑(自上而下)
46
53
  if (hasProduct(norm, 'push')) {
47
- if (norm.types?.length && norm.types.every((t) => CROSS_PLATFORM_TYPES.has(t))) {
54
+ if (norm.searchIntent?.length && norm.searchIntent.every((t) => CROSS_PLATFORM_TYPES.has(t))) {
48
55
  return false;
49
56
  }
50
57
  if (PUSH_PLATFORM_SPECIFIC_PROMPT.test(norm.prompt))
@@ -58,13 +65,15 @@ export function requiresFramework(norm) {
58
65
  return true;
59
66
  if (CROSS_PLATFORM_PROMPT.test(norm.prompt))
60
67
  return false;
61
- if (norm.types?.length) {
62
- if (norm.types.some((t) => PLATFORM_TYPES.has(t)))
68
+ if (isChatProductScopeQuery(norm))
69
+ return false;
70
+ if (norm.searchIntent?.length) {
71
+ if (norm.searchIntent.some((t) => PLATFORM_TYPES.has(t)))
63
72
  return true;
64
- if (norm.types.every((t) => CROSS_PLATFORM_TYPES.has(t)))
73
+ if (norm.searchIntent.every((t) => CROSS_PLATFORM_TYPES.has(t)))
65
74
  return false;
66
75
  // faq / error_code 等默认可跨平台检索
67
- if (norm.types.every((t) => t === 'faq' || t === 'error_code' || CROSS_PLATFORM_TYPES.has(t))) {
76
+ if (norm.searchIntent.every((t) => t === 'faq' || t === 'error_code' || CROSS_PLATFORM_TYPES.has(t))) {
68
77
  return false;
69
78
  }
70
79
  }
@@ -1,7 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
- import { attachPoolContent } from '../content-loader.js';
4
+ import { attachPoolContent, getSourceFileContent } from '../content-loader.js';
5
+ import { buildReferences, resolveFragmentDocUrls } from '../doc-url-resolver.js';
5
6
  import { rankSubsetWithIndex } from '../bm25.js';
6
7
  import { getProductsBM25Index } from '../bm25-cache.js';
7
8
  import { filterPool, normalizeParams } from './filter-pool.js';
@@ -79,6 +80,7 @@ function postProcess(ranked, chunksById, limit) {
79
80
  title: chunk.title,
80
81
  content: chunk.content,
81
82
  source: chunk.source,
83
+ doc_urls: resolveFragmentDocUrls(chunk.source, chunk.content, getSourceFileContent(chunk.source)),
82
84
  product: chunk.product,
83
85
  framework: chunk.framework,
84
86
  types: chunk.types,
@@ -135,8 +137,11 @@ function assessConfidence(fragments, exactHits) {
135
137
  }
136
138
  return { confidence: 'low', status: 'low_confidence' };
137
139
  }
138
- function buildAgentMessage(status, fragments, confidence) {
139
- const tail = '合成答案后请调用 `record_answer`;用户反馈请调用 `record_feedback`。';
140
+ function buildAgentMessage(status, fragments, confidence, references) {
141
+ const citeTail = references?.length
142
+ ? '作答时 MUST 在答案末尾附「**参考文档**」小节,逐条列出 `meta.references`(或各 fragment 的 `doc_urls`)中的 URL,便于用户核对;禁止编造未出现的链接。'
143
+ : '若 fragments 含 `doc_urls`,作答时须在末尾附「**参考文档**」列出对应 URL;禁止编造链接。';
144
+ const tail = `${citeTail} 合成答案后请调用 \`record_answer\`;用户反馈请调用 \`record_feedback\`。`;
140
145
  if (status === 'needs_framework') {
141
146
  return '【硬规则】问题依赖具体平台实现,但未指定 framework,全平台混检信息密度低且被禁止。MUST 先调用 `present_framework_choice`(传入 product),等用户选定 android/ios/flutter/react/vue/uni-app 等后再调用本工具,并 MUST 带上 **product + framework**。禁止传空 framework 硬搜。';
142
147
  }
@@ -171,7 +176,7 @@ export function searchKnowledge(params) {
171
176
  return {
172
177
  status: 'needs_framework',
173
178
  confidence: 'none',
174
- message: buildAgentMessage('needs_framework', [], 'none'),
179
+ message: buildAgentMessage('needs_framework', [], 'none', undefined),
175
180
  query: params,
176
181
  meta: {
177
182
  pool_size: manifest.chunks.length,
@@ -183,7 +188,11 @@ export function searchKnowledge(params) {
183
188
  }
184
189
  const manifest = loadManifest();
185
190
  const allChunks = manifest.chunks;
186
- const pool = filterPool(allChunks, norm);
191
+ let pool = filterPool(allChunks, norm);
192
+ // 自愈:types 过滤导致 0 命中时,丢掉 types 再过滤一次,避免误传类型标签直接返回 empty
193
+ if (pool.length === 0 && norm.types?.length) {
194
+ pool = filterPool(allChunks, { ...norm, types: undefined });
195
+ }
187
196
  const { boosts, exactHits } = runExactLookup(norm.prompt, pool, norm);
188
197
  // P0-4:用 product 级缓存的 BM25 索引对子集打分(首次构建,后续命中缓存)
189
198
  // 索引基于该 product 全量 chunks(含 integration corpus);
@@ -195,6 +204,7 @@ export function searchKnowledge(params) {
195
204
  const ranked = rankSubsetWithIndex(norm.prompt, pool.map((chunk) => chunk.id), productIndex, boosts);
196
205
  const fragments = postProcess(ranked, chunksById, norm.limit);
197
206
  const urlMappingSources = [...new Set(fragments.map((f) => f.source).filter((source) => isUrlMappingSource(source)))];
207
+ const references = buildReferences(fragments);
198
208
  // P0-3:相对阈值评估置信度(替代原硬编码 0.5 死阈值)
199
209
  const { confidence, status } = assessConfidence(fragments, exactHits);
200
210
  const topScore = fragments[0]?.score;
@@ -202,13 +212,14 @@ export function searchKnowledge(params) {
202
212
  return {
203
213
  status,
204
214
  confidence,
205
- message: buildAgentMessage(status, fragments, confidence),
215
+ message: buildAgentMessage(status, fragments, confidence, references),
206
216
  query: params,
207
217
  meta: {
208
218
  pool_size: allChunks.length,
209
219
  filtered_size: pool.length,
210
220
  exact_hits: exactHits,
211
221
  ...(urlMappingSources.length ? { url_mapping_sources: urlMappingSources } : {}),
222
+ ...(references.length ? { references } : {}),
212
223
  ...(topScore !== undefined ? { top_score: Number(topScore.toFixed(2)) } : {}),
213
224
  ...(secondScore !== undefined ? { second_score: Number(secondScore.toFixed(2)) } : {}),
214
225
  },
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tencentcloud/sdk-mcp",
3
- "version": "1.6.0-beta.3",
3
+ "version": "1.6.1",
4
4
  "description": "Tencent Cloud MCP Server for SDK",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1 +1 @@
1
- {"chat-setting":["chat-setting","chatsetting","chat_setting"],"contact-list":["contact-list","contactlist","contact_list"],"conversation-actions":["conversation-actions","conversationactions","conversation_actions"],"conversation-list":["conversation-list","conversationlist","conversation_list"],"conversation-preview":["conversation-preview","conversationpreview","conversation_preview"],"conversation-search":["conversation-search","conversationsearch","conversation_search"],"message-input":["message-input","messageinput","message_input"],"message-list":["message-list","messagelist","message_list"],"search":["search","search","search"],"theme":["theme","theme","theme"],"chat-header":["chat-header","chatheader","chat_header"]}
1
+ {}
@@ -0,0 +1 @@
1
+ {"knowledge/rtcengine/web/how_to_run_web_sdk_demo.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-10-basic-get-started-with-demo.md","knowledge/rtcengine/web/plugin/20-advanced-customized-capture-rendering.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-20-advanced-customized-capture-rendering.md","knowledge/rtcengine/web/plugin/21-advanced-auto-play-policy.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-21-advanced-auto-play-policy.md","knowledge/rtcengine/web/plugin/22-advanced-audio-mixer.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-22-advanced-audio-mixer.md","knowledge/rtcengine/web/plugin/23-advanced-support-detection.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-23-advanced-support-detection.md","knowledge/rtcengine/web/plugin/24-advanced-network-quality.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-24-advanced-network-quality.md","knowledge/rtcengine/web/plugin/25-advanced-device-change.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-25-advanced-device-change.md","knowledge/rtcengine/web/plugin/26-advanced-publish-cdn-stream.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-26-advanced-publish-cdn-stream.md","knowledge/rtcengine/web/plugin/27-advanced-small-stream.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-27-advanced-small-stream.md","knowledge/rtcengine/web/plugin/28-advanced-beauty.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-28-advanced-beauty.md","knowledge/rtcengine/web/plugin/29-advanced-water-mark.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-29-advanced-water-mark.md","knowledge/rtcengine/web/plugin/30-advanced-cross-room-link.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-30-advanced-cross-room-link.md","knowledge/rtcengine/web/plugin/31-advanced-plugins-overview.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-31-advanced-plugins-overview.md","knowledge/rtcengine/web/plugin/34-advanced-proxy.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-34-advanced-proxy.md","knowledge/rtcengine/web/plugin/35-advanced-ai-denoiser.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-35-advanced-ai-denoiser.md","knowledge/rtcengine/web/plugin/36-advanced-virtual-background.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-36-advanced-virtual-background.md","knowledge/rtcengine/web/plugin/37-advanced-voice-changer.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-37-advanced-voice-changer.md","knowledge/rtcengine/web/plugin/38-advanced-basic-beauty.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-38-advanced-basic-beauty.md","knowledge/rtcengine/web/plugin/39-advanced-video-decoder.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-39-advanced-video-decoder.md","knowledge/rtcengine/web/plugin/40-advanced-video-mixer.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-40-advanced-video-mixer.md","knowledge/rtcengine/web/plugin/41-advanced-small-stream-auto-switcher.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-41-advanced-small-stream-auto-switcher.md","knowledge/rtcengine/web/plugin/42-advanced-realtime-transcriber.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-42-advanced-realtime-transcriber.md","knowledge/rtcengine/web/plugin/43-advanced-face-detection.md":"https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/tutorial-43-advanced-face-detection.md"}