@bangdao-ai/acw-tools 1.3.0 → 1.3.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.
@@ -41,7 +41,13 @@ function decompressData(data) {
41
41
  return data;
42
42
  } catch (error) {
43
43
  // 如果解压失败,尝试直接返回字符串
44
- return data.toString('utf-8');
44
+ console.error('[decompressData] 解压失败,尝试直接返回字符串:', error.message);
45
+ try {
46
+ return data.toString('utf-8');
47
+ } catch (e) {
48
+ console.error('[decompressData] 转换字符串也失败:', e.message);
49
+ return null;
50
+ }
45
51
  }
46
52
  }
47
53
 
@@ -354,25 +360,41 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
354
360
  // 计算平均执行时间、最大执行时间和最小执行时间(只统计type='ai'且executionTime>0的)
355
361
  let validAiExecutionCount = 0;
356
362
  let validTotalExecutionTime = 0;
363
+ let aiExecutionsWithTimingInfo = 0;
364
+ let aiExecutionsWithoutTimingInfo = 0;
357
365
 
358
366
  // 遍历executions计算平均值、最大值和最小值(只统计type='ai'且executionTime>0的)
359
367
  for (const execution of additionalInfo.performance.executions) {
360
- if (execution.type === 'ai' && execution.executionTime > 0) {
361
- validAiExecutionCount++;
362
- validTotalExecutionTime += execution.executionTime;
363
-
364
- // 更新最大值
365
- if (execution.executionTime > additionalInfo.performance.maxExecutionTime) {
366
- additionalInfo.performance.maxExecutionTime = execution.executionTime;
368
+ if (execution.type === 'ai') {
369
+ // 统计 timingInfo 情况
370
+ if (execution.timingInfo) {
371
+ aiExecutionsWithTimingInfo++;
372
+ } else {
373
+ aiExecutionsWithoutTimingInfo++;
367
374
  }
368
375
 
369
- // 更新最小值
370
- if (execution.executionTime < additionalInfo.performance.minExecutionTime) {
371
- additionalInfo.performance.minExecutionTime = execution.executionTime;
376
+ if (execution.executionTime > 0) {
377
+ validAiExecutionCount++;
378
+ validTotalExecutionTime += execution.executionTime;
379
+
380
+ // 更新最大值
381
+ if (execution.executionTime > additionalInfo.performance.maxExecutionTime) {
382
+ additionalInfo.performance.maxExecutionTime = execution.executionTime;
383
+ }
384
+
385
+ // 更新最小值
386
+ if (execution.executionTime < additionalInfo.performance.minExecutionTime) {
387
+ additionalInfo.performance.minExecutionTime = execution.executionTime;
388
+ }
372
389
  }
373
390
  }
374
391
  }
375
392
 
393
+ // 输出 timingInfo 统计日志(帮助排查问题)
394
+ if (aiExecutionsWithoutTimingInfo > 0) {
395
+ console.error(`[timingInfo统计] AI执行总数: ${additionalInfo.performance.aiExecutionCount}, 有timingInfo: ${aiExecutionsWithTimingInfo}, 无timingInfo: ${aiExecutionsWithoutTimingInfo}, 有效executionTime: ${validAiExecutionCount}`);
396
+ }
397
+
376
398
  // 计算平均执行时间
377
399
  if (validAiExecutionCount > 0) {
378
400
  additionalInfo.performance.averageExecutionTime = validTotalExecutionTime / validAiExecutionCount;
@@ -605,32 +627,40 @@ function extractConversationCore(composerId, outputPath, db) {
605
627
 
606
628
  for (const row of bubbleRows) {
607
629
  if (row.value) {
608
- const decompressed = decompressData(row.value);
609
- const data = JSON.parse(decompressed);
610
-
611
- // 只处理在 fullConversationHeadersOnly 中的bubble
612
- if (!validBubbleIds.has(data.bubbleId)) {
613
- skippedNotInHeaderBubbles++;
614
- continue;
615
- }
616
-
617
- // 过滤掉完全空的bubble(没有text、没有toolResults、没有其他有用信息)
618
- const hasText = data.text && data.text.trim().length > 0;
619
- const hasToolResults = data.toolResults && data.toolResults.length > 0;
620
- const hasSuggestedCode = data.suggestedCodeBlocks && data.suggestedCodeBlocks.length > 0;
621
- const hasDiffs = data.assistantSuggestedDiffs && data.assistantSuggestedDiffs.length > 0;
622
- const hasRichText = data.richText && data.richText.trim && data.richText.trim().length > 0;
623
- const hasToolFormerData = data.toolFormerData && Object.keys(data.toolFormerData).length > 0;
624
-
625
- // 保留有完整timingInfo的bubble(即使没有内容,也包含性能数据)
626
- const hasCompleteTimingInfo = data.timingInfo &&
627
- data.timingInfo.clientRpcSendTime &&
628
- data.timingInfo.clientSettleTime;
629
-
630
- if (hasText || hasToolResults || hasSuggestedCode || hasDiffs || hasRichText || hasToolFormerData || hasCompleteTimingInfo) {
631
- bubbles.push(data);
632
- } else {
633
- skippedEmptyBubbles++;
630
+ try {
631
+ const decompressed = decompressData(row.value);
632
+ if (!decompressed) {
633
+ console.error(`[bubble解析] 解压失败,跳过 key: ${row.key}`);
634
+ continue;
635
+ }
636
+ const data = JSON.parse(decompressed);
637
+
638
+ // 只处理在 fullConversationHeadersOnly 中的bubble
639
+ if (!validBubbleIds.has(data.bubbleId)) {
640
+ skippedNotInHeaderBubbles++;
641
+ continue;
642
+ }
643
+
644
+ // 过滤掉完全空的bubble(没有text、没有toolResults、没有其他有用信息)
645
+ const hasText = data.text && data.text.trim().length > 0;
646
+ const hasToolResults = data.toolResults && data.toolResults.length > 0;
647
+ const hasSuggestedCode = data.suggestedCodeBlocks && data.suggestedCodeBlocks.length > 0;
648
+ const hasDiffs = data.assistantSuggestedDiffs && data.assistantSuggestedDiffs.length > 0;
649
+ const hasRichText = data.richText && data.richText.trim && data.richText.trim().length > 0;
650
+ const hasToolFormerData = data.toolFormerData && Object.keys(data.toolFormerData).length > 0;
651
+
652
+ // 保留有完整timingInfo的bubble(即使没有内容,也包含性能数据)
653
+ const hasCompleteTimingInfo = data.timingInfo &&
654
+ data.timingInfo.clientRpcSendTime &&
655
+ data.timingInfo.clientSettleTime;
656
+
657
+ if (hasText || hasToolResults || hasSuggestedCode || hasDiffs || hasRichText || hasToolFormerData || hasCompleteTimingInfo) {
658
+ bubbles.push(data);
659
+ } else {
660
+ skippedEmptyBubbles++;
661
+ }
662
+ } catch (parseError) {
663
+ console.error(`[bubble解析] JSON解析失败,跳过 key: ${row.key}`, parseError.message);
634
664
  }
635
665
  }
636
666
  }
package/index.js CHANGED
@@ -209,8 +209,16 @@ function log(level, message, data = null) {
209
209
  // 便捷的日志方法
210
210
  const logger = {
211
211
  info: (message, data) => log('INFO', message, data),
212
- warn: (message, data) => log('WARN', message, data),
213
- error: (message, data) => log('ERROR', message, data),
212
+ warn: (message, data) => {
213
+ log('WARN', message, data);
214
+ // WARN 级别也输出到 stderr,方便用户在控制台看到警告
215
+ console.error(`[WARN] ${message}`, data ? JSON.stringify(data) : '');
216
+ },
217
+ error: (message, data) => {
218
+ log('ERROR', message, data);
219
+ // ERROR 级别输出到 stderr,方便用户在控制台看到错误
220
+ console.error(`[ERROR] ${message}`, data ? JSON.stringify(data) : '');
221
+ },
214
222
  debug: (message, data) => log('DEBUG', message, data)
215
223
  };
216
224
 
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ACW工具集",
3
3
  "description": "ACW平台工具集:智能下载规则到项目、初始化Common Admin模板项目",
4
- "version": "1.3.0",
4
+ "version": "1.3.1",
5
5
  "author": "邦道科技 - 产品技术中心",
6
6
  "homepage": "https://www.npmjs.com/package/@bangdao-ai/acw-tools",
7
7
  "repository": "https://www.npmjs.com/package/@bangdao-ai/acw-tools?activeTab=readme",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bangdao-ai/acw-tools",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "description": "MCP (Model Context Protocol) tools for ACW - download rules and initialize Common Admin projects",
6
6
  "main": "index.js",