@bangdao-ai/acw-tools 1.3.6-beta.1 → 1.3.6-beta.2

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.
@@ -187,9 +187,10 @@ function parseCodeChanges(bubble) {
187
187
  * @param {Object} composerData - Composer数据
188
188
  * @param {Array} bubbles - 会话气泡数组
189
189
  * @param {string} markdownContent - Markdown内容(用于计算大小)
190
+ * @param {Function} debugLogger - 可选的debug日志函数,用于输出详细的bubble数据
190
191
  * @returns {Object} 返回 { additionalInfo, executionsList }
191
192
  */
192
- function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
193
+ function extractAdditionalInfo(composerData, bubbles, markdownContent = '', debugLogger = null) {
193
194
  // 计算内容大小(KB)
194
195
  const contentSizeBytes = Buffer.byteLength(markdownContent, 'utf8');
195
196
  const contentSizeKb = parseFloat((contentSizeBytes / 1024).toFixed(2));
@@ -307,11 +308,30 @@ function extractAdditionalInfo(composerData, bubbles, markdownContent = '') {
307
308
  const tokenCount = bubble.tokenCount || {};
308
309
  const modelInfo = bubble.modelInfo || {};
309
310
 
310
- // DEBUG: 输出原始 bubble.timingInfo 情况(仅在有问题时输出)
311
+ // DEBUG模式:输出完整的bubble数据用于排查timingInfo问题
311
312
  const hasRawTimingInfo = !!bubble.timingInfo;
312
313
  const hasClientRpcSendTime = !!(bubble.timingInfo && bubble.timingInfo.clientRpcSendTime);
313
314
  const hasClientSettleTime = !!(bubble.timingInfo && bubble.timingInfo.clientSettleTime);
314
315
 
316
+ // 如果没有timingInfo或缺少关键字段,输出详细日志
317
+ if (debugLogger && (!hasRawTimingInfo || !hasClientRpcSendTime || !hasClientSettleTime)) {
318
+ debugLogger('🔍 [DEBUG] AI bubble缺少timingInfo关键字段', {
319
+ bubbleId: bubble.bubbleId,
320
+ hasTimingInfo: hasRawTimingInfo,
321
+ hasClientRpcSendTime,
322
+ hasClientSettleTime,
323
+ timingInfoKeys: bubble.timingInfo ? Object.keys(bubble.timingInfo) : [],
324
+ timingInfoValues: bubble.timingInfo || null,
325
+ // 输出bubble的其他关键字段帮助排查
326
+ bubbleKeys: Object.keys(bubble),
327
+ modelName: modelInfo.modelName || null,
328
+ tokenCount: tokenCount,
329
+ createdAt: bubble.createdAt,
330
+ // 完整bubble数据(JSON字符串,便于分析)
331
+ fullBubbleJson: JSON.stringify(bubble, null, 2)
332
+ });
333
+ }
334
+
315
335
  let executionTime = 0;
316
336
  if (aiTimingInfo.clientRpcSendTime && aiTimingInfo.clientSettleTime) {
317
337
  executionTime = aiTimingInfo.clientSettleTime - aiTimingInfo.clientRpcSendTime;
@@ -578,8 +598,9 @@ function formatListDirResult(directoryTree) {
578
598
  * @param {string} composerId - Composer ID
579
599
  * @param {string} outputPath - 输出文件路径
580
600
  * @param {Object} db - 已打开的数据库连接
601
+ * @param {Function} debugLogger - 可选的debug日志函数
581
602
  */
582
- function extractConversationCore(composerId, outputPath, db) {
603
+ function extractConversationCore(composerId, outputPath, db, debugLogger = null) {
583
604
  try {
584
605
  // 1. 获取composer元数据
585
606
  const composerDataRow = db.prepare(
@@ -1413,7 +1434,7 @@ function extractConversationCore(composerId, outputPath, db) {
1413
1434
  fs.writeFileSync(outputPath, markdown, 'utf-8');
1414
1435
 
1415
1436
  // 提取附加信息和执行明细列表
1416
- const { additionalInfo, executionsList } = extractAdditionalInfo(composerData, bubbles, markdown);
1437
+ const { additionalInfo, executionsList } = extractAdditionalInfo(composerData, bubbles, markdown, debugLogger);
1417
1438
 
1418
1439
  return {
1419
1440
  success: true,
@@ -1438,8 +1459,9 @@ function extractConversationCore(composerId, outputPath, db) {
1438
1459
  * @param {string} composerId - Composer ID
1439
1460
  * @param {string} outputPath - 输出文件路径
1440
1461
  * @param {string} [customDbPath] - 自定义数据库路径(可选,默认使用系统全局数据库)
1462
+ * @param {Function} [debugLogger] - 可选的debug日志函数,用于输出详细的bubble数据
1441
1463
  */
1442
- export async function extractConversationFromGlobalDb(composerId, outputPath, customDbPath = null) {
1464
+ export async function extractConversationFromGlobalDb(composerId, outputPath, customDbPath = null, debugLogger = null) {
1443
1465
  const globalDbPath = customDbPath || getGlobalDbPath();
1444
1466
 
1445
1467
  if (!fs.existsSync(globalDbPath)) {
@@ -1451,7 +1473,7 @@ export async function extractConversationFromGlobalDb(composerId, outputPath, cu
1451
1473
  const db = new Database(globalDbPath, { readonly: true });
1452
1474
 
1453
1475
  try {
1454
- return extractConversationCore(composerId, outputPath, db);
1476
+ return extractConversationCore(composerId, outputPath, db, debugLogger);
1455
1477
  } finally {
1456
1478
  db.close();
1457
1479
  }
@@ -1462,9 +1484,10 @@ export async function extractConversationFromGlobalDb(composerId, outputPath, cu
1462
1484
  * @param {string} composerId - Composer ID
1463
1485
  * @param {string} outputPath - 输出文件路径
1464
1486
  * @param {Object} db - 已打开的数据库连接
1487
+ * @param {Function} [debugLogger] - 可选的debug日志函数,用于输出详细的bubble数据
1465
1488
  */
1466
- export function extractConversationFromGlobalDbWithConnection(composerId, outputPath, db) {
1467
- return extractConversationCore(composerId, outputPath, db);
1489
+ export function extractConversationFromGlobalDbWithConnection(composerId, outputPath, db, debugLogger = null) {
1490
+ return extractConversationCore(composerId, outputPath, db, debugLogger);
1468
1491
  }
1469
1492
 
1470
1493
  /**
package/index.js CHANGED
@@ -25,6 +25,7 @@ const RETRY_BASE_DELAY = 2000; // 重试基础延迟(2秒)
25
25
  // ==================== 压缩配置 ====================
26
26
  const COMPRESSION_ENABLED = process.env.MCP_COMPRESSION_ENABLED !== 'false'; // 默认启用
27
27
  const COMPRESSION_THRESHOLD = parseInt(process.env.MCP_COMPRESSION_THRESHOLD || '1048576', 10); // 默认1MB阈值
28
+ const DEBUG_MODE = process.env.ACW_DEBUG === 'true'; // Debug模式:输出详细的bubble日志用于排查问题
28
29
 
29
30
  // ==================== 数据库引擎加载(使用 better-sqlite3)====================
30
31
  let dbEngine = null;
@@ -241,6 +242,11 @@ function cleanOldLogs() {
241
242
  // 清理旧日志
242
243
  cleanOldLogs();
243
244
 
245
+ // 启动时记录 DEBUG 模式状态
246
+ if (DEBUG_MODE) {
247
+ logger.info('🔧 DEBUG模式已启用 - 将输出详细的bubble数据用于排查timingInfo问题');
248
+ }
249
+
244
250
  // ==================== 版本信息初始化 ====================
245
251
 
246
252
  const __filename = fileURLToPath(import.meta.url);
@@ -678,7 +684,9 @@ async function generateMarkdownFromComposerData(composerId, db) {
678
684
 
679
685
  try {
680
686
  // 调用完整的解析器(传入已打开的数据库连接)
681
- const result = parserModule.extractConversationFromGlobalDbWithConnection(composerId, tempFile, db);
687
+ // DEBUG模式下传入logger.debug用于输出详细的bubble数据
688
+ const debugLoggerFn = DEBUG_MODE ? (msg, data) => logger.debug(msg, data) : null;
689
+ const result = parserModule.extractConversationFromGlobalDbWithConnection(composerId, tempFile, db, debugLoggerFn);
682
690
 
683
691
  if (!result || !result.success) {
684
692
  logger.warn('解析器返回失败', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bangdao-ai/acw-tools",
3
- "version": "1.3.6-beta.1",
3
+ "version": "1.3.6-beta.2",
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",