chatlab-cli 0.26.0 → 0.26.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 (66) hide show
  1. package/dist/{chat-command-ZP4WJVWC.mjs → chat-command-T3Z4O4M5.mjs} +4 -4
  2. package/dist/{chunk-WXC6RZCX.mjs → chunk-3APSMVOM.mjs} +2 -2
  3. package/dist/{chunk-ILGSSXOG.mjs → chunk-6O2SW5GL.mjs} +5 -4
  4. package/dist/chunk-6O2SW5GL.mjs.map +1 -0
  5. package/dist/{chunk-SJIOPSMM.mjs → chunk-AZZYKUBR.mjs} +17 -39
  6. package/dist/chunk-AZZYKUBR.mjs.map +1 -0
  7. package/dist/{chunk-IRZRIHIT.mjs → chunk-FACKH2BR.mjs} +2 -2
  8. package/dist/{chunk-TC74HESZ.mjs → chunk-FAOZNMPK.mjs} +2 -2
  9. package/dist/{chunk-QY67NN65.mjs → chunk-GUGKY2GV.mjs} +329 -250
  10. package/dist/chunk-GUGKY2GV.mjs.map +1 -0
  11. package/dist/{chunk-UB4XBM4R.mjs → chunk-MZG2GLJR.mjs} +2 -2
  12. package/dist/{chunk-6G7AIF7I.mjs → chunk-SC77N66X.mjs} +9 -9
  13. package/dist/cli.mjs +3 -3
  14. package/dist/{http-J3IOFFIA.mjs → http-6LQUOYQ6.mjs} +8 -8
  15. package/dist/{import-POYG5LOX.mjs → import-B2MAIBAK.mjs} +4 -4
  16. package/dist/index.mjs +8 -8
  17. package/dist/{mcp-7HH7UMXT.mjs → mcp-ZMMYW46I.mjs} +4 -4
  18. package/dist/{stream-import-O3H3FGV2.mjs → stream-import-FHFBCEDV.mjs} +3 -3
  19. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-CgtTQTfN.js +182 -0
  20. package/dist-web/assets/MessageExportModal-B8DKeSAH.js +1 -0
  21. package/dist-web/assets/{electron-B3DFm1cC.js → electron-C-aMus7e.js} +1 -1
  22. package/dist-web/assets/{electron-BMM4Nfty.js → electron-dBbXcMDB.js} +1 -1
  23. package/dist-web/assets/{fetch-BGfaAqO9.js → fetch-B-LdQP9s.js} +1 -1
  24. package/dist-web/assets/{fetch-BaJDB31c.js → fetch-B26JuD67.js} +1 -1
  25. package/dist-web/assets/{fetch-BjDJgdN0.js → fetch-BLKibnXa.js} +1 -1
  26. package/dist-web/assets/{fetch-BFtuJaa1.js → fetch-BNNqdS2B.js} +1 -1
  27. package/dist-web/assets/fetch-BSJY7tRo.js +1 -0
  28. package/dist-web/assets/{fetch-C5CLcpQW.js → fetch-CV8jezsM.js} +1 -1
  29. package/dist-web/assets/{fetch-DQZvdHnG.js → fetch-CvnJ4Jgf.js} +1 -1
  30. package/dist-web/assets/{fetch-ArMjdMcy.js → fetch-DP3yNfJM.js} +1 -1
  31. package/dist-web/assets/{fetch-SYrb-sZe.js → fetch-phbrO2bY.js} +1 -1
  32. package/dist-web/assets/{fetch-Dhfbt1BQ.js → fetch-xB6cl_1L.js} +1 -1
  33. package/dist-web/assets/index-8Zcs8peI.css +1 -0
  34. package/dist-web/assets/index-B_lOzUD8.js +2 -0
  35. package/dist-web/assets/index-BvWcJc3c.js +173 -0
  36. package/dist-web/assets/{index-D7_ch4zf.js → index-CSDI5pAA.js} +2 -2
  37. package/dist-web/assets/{index-CGNgUIT-.css → index-CX2FucK5.css} +1 -1
  38. package/dist-web/assets/{index-DK9LEEzT.js → index-DJQFNVUJ.js} +1 -1
  39. package/dist-web/assets/index-DZ6Szt_y.js +163 -0
  40. package/dist-web/assets/index-DhpclWeF.js +11 -0
  41. package/dist-web/assets/index-Dhql4DJr.css +1 -0
  42. package/dist-web/assets/{web-zEXsvoZW.js → web-DUQU-v8U.js} +1 -1
  43. package/dist-web/index.html +2 -2
  44. package/package.json +1 -1
  45. package/dist/chunk-ILGSSXOG.mjs.map +0 -1
  46. package/dist/chunk-QY67NN65.mjs.map +0 -1
  47. package/dist/chunk-SJIOPSMM.mjs.map +0 -1
  48. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BTJxEma5.js +0 -182
  49. package/dist-web/assets/MessageExportModal-C7NgEL8T.js +0 -1
  50. package/dist-web/assets/fetch-DnEP0uyF.js +0 -1
  51. package/dist-web/assets/index-C3A_Rjh-.css +0 -1
  52. package/dist-web/assets/index-CWfkrx37.js +0 -173
  53. package/dist-web/assets/index-D3N4NDFx.css +0 -1
  54. package/dist-web/assets/index-DqDa_on9.js +0 -9
  55. package/dist-web/assets/index-DrN1G9bl.js +0 -2
  56. package/dist-web/assets/index-MdYeovYo.js +0 -163
  57. /package/dist/{chat-command-ZP4WJVWC.mjs.map → chat-command-T3Z4O4M5.mjs.map} +0 -0
  58. /package/dist/{chunk-WXC6RZCX.mjs.map → chunk-3APSMVOM.mjs.map} +0 -0
  59. /package/dist/{chunk-IRZRIHIT.mjs.map → chunk-FACKH2BR.mjs.map} +0 -0
  60. /package/dist/{chunk-TC74HESZ.mjs.map → chunk-FAOZNMPK.mjs.map} +0 -0
  61. /package/dist/{chunk-UB4XBM4R.mjs.map → chunk-MZG2GLJR.mjs.map} +0 -0
  62. /package/dist/{chunk-6G7AIF7I.mjs.map → chunk-SC77N66X.mjs.map} +0 -0
  63. /package/dist/{http-J3IOFFIA.mjs.map → http-6LQUOYQ6.mjs.map} +0 -0
  64. /package/dist/{import-POYG5LOX.mjs.map → import-B2MAIBAK.mjs.map} +0 -0
  65. /package/dist/{mcp-7HH7UMXT.mjs.map → mcp-ZMMYW46I.mjs.map} +0 -0
  66. /package/dist/{stream-import-O3H3FGV2.mjs.map → stream-import-FHFBCEDV.mjs.map} +0 -0
@@ -3057,188 +3057,6 @@ function deleteMember(db, memberId) {
3057
3057
  }
3058
3058
  }
3059
3059
 
3060
- // ../../packages/core/src/query/filter.ts
3061
- function emptyResult(page, pageSize) {
3062
- return {
3063
- blocks: [],
3064
- stats: { totalMessages: 0, hitMessages: 0, totalChars: 0 },
3065
- pagination: { page, pageSize, totalBlocks: 0, totalHits: 0, hasMore: false }
3066
- };
3067
- }
3068
- function filterMessagesWithContext(db, options = {}) {
3069
- const { keywords, timeFilter, senderIds, contextSize = 10, page = 1, pageSize = 50 } = options;
3070
- const lightSql = `
3071
- SELECT id, ts, sender_id as senderId, content
3072
- FROM message
3073
- ${timeFilter ? "WHERE ts >= ? AND ts <= ?" : ""}
3074
- ORDER BY ts ASC, id ASC
3075
- `;
3076
- const params = [];
3077
- if (timeFilter) {
3078
- params.push(timeFilter.startTs, timeFilter.endTs);
3079
- }
3080
- const lightRows = db.prepare(lightSql).all(...params);
3081
- const hitIndexes = [];
3082
- for (let i = 0; i < lightRows.length; i++) {
3083
- const row = lightRows[i];
3084
- let isHit = true;
3085
- if (keywords && keywords.length > 0) {
3086
- const content = (row.content || "").toLowerCase();
3087
- isHit = keywords.some((kw) => content.includes(kw.toLowerCase()));
3088
- }
3089
- if (isHit && senderIds && senderIds.length > 0) {
3090
- isHit = senderIds.includes(row.senderId);
3091
- }
3092
- if (isHit) {
3093
- hitIndexes.push(i);
3094
- }
3095
- }
3096
- if (hitIndexes.length === 0) {
3097
- return emptyResult(page, pageSize);
3098
- }
3099
- const ranges = [];
3100
- for (const hitIndex of hitIndexes) {
3101
- const start = Math.max(0, hitIndex - contextSize);
3102
- const end = Math.min(lightRows.length - 1, hitIndex + contextSize);
3103
- if (ranges.length > 0) {
3104
- const lastRange = ranges[ranges.length - 1];
3105
- if (start <= lastRange.end + 1) {
3106
- lastRange.end = Math.max(lastRange.end, end);
3107
- lastRange.hitIndexes.push(hitIndex);
3108
- continue;
3109
- }
3110
- }
3111
- ranges.push({ start, end, hitIndexes: [hitIndex] });
3112
- }
3113
- const totalBlocks = ranges.length;
3114
- const totalHits = hitIndexes.length;
3115
- const startIdx = (page - 1) * pageSize;
3116
- const endIdx = Math.min(startIdx + pageSize, totalBlocks);
3117
- const pageRanges = ranges.slice(startIdx, endIdx);
3118
- const hasMore = endIdx < totalBlocks;
3119
- if (pageRanges.length === 0) {
3120
- return {
3121
- blocks: [],
3122
- stats: { totalMessages: 0, hitMessages: totalHits, totalChars: 0 },
3123
- pagination: { page, pageSize, totalBlocks, totalHits, hasMore: false }
3124
- };
3125
- }
3126
- const blocks = [];
3127
- let totalMessages = 0;
3128
- let totalChars = 0;
3129
- for (const range of pageRanges) {
3130
- const blockSql = `
3131
- SELECT ${FULL_MSG_COLUMNS}
3132
- ${FULL_MSG_FROM}
3133
- ${timeFilter ? "WHERE msg.ts >= ? AND msg.ts <= ?" : ""}
3134
- ORDER BY msg.ts ASC, msg.id ASC
3135
- LIMIT ? OFFSET ?
3136
- `;
3137
- const blockParams = [];
3138
- if (timeFilter) {
3139
- blockParams.push(timeFilter.startTs, timeFilter.endTs);
3140
- }
3141
- blockParams.push(range.end - range.start + 1, range.start);
3142
- const rows = db.prepare(blockSql).all(...blockParams);
3143
- const mapped = rows.map(mapMessageRow);
3144
- const hitIndexSet = new Set(range.hitIndexes.map((idx) => idx - range.start));
3145
- const blockMessages = mapped.map((msg, i) => ({
3146
- ...msg,
3147
- isHit: hitIndexSet.has(i)
3148
- }));
3149
- for (const msg of mapped) {
3150
- totalChars += msg.content.length;
3151
- }
3152
- if (blockMessages.length > 0) {
3153
- blocks.push({
3154
- startTs: blockMessages[0].timestamp,
3155
- endTs: blockMessages[blockMessages.length - 1].timestamp,
3156
- messages: blockMessages,
3157
- hitCount: range.hitIndexes.length
3158
- });
3159
- totalMessages += blockMessages.length;
3160
- }
3161
- }
3162
- let estimatedTotalChars = totalChars;
3163
- if (page === 1 && totalBlocks > pageSize && blocks.length > 0) {
3164
- const avgCharsPerBlock = totalChars / blocks.length;
3165
- estimatedTotalChars = Math.round(avgCharsPerBlock * totalBlocks);
3166
- }
3167
- return {
3168
- blocks,
3169
- stats: {
3170
- totalMessages: page === 1 ? totalMessages : 0,
3171
- hitMessages: totalHits,
3172
- totalChars: page === 1 ? totalBlocks > pageSize ? estimatedTotalChars : totalChars : 0
3173
- },
3174
- pagination: { page, pageSize, totalBlocks, totalHits, hasMore }
3175
- };
3176
- }
3177
- function getMultipleSessionsMessages(db, segmentIds, page = 1, pageSize = 50) {
3178
- if (segmentIds.length === 0) {
3179
- return emptyResult(page, pageSize);
3180
- }
3181
- const sessionsSql = `
3182
- SELECT id, start_ts as startTs, end_ts as endTs, message_count as messageCount
3183
- FROM segment
3184
- WHERE id IN (${segmentIds.map(() => "?").join(",")})
3185
- ORDER BY start_ts ASC
3186
- `;
3187
- const allSessions = db.prepare(sessionsSql).all(...segmentIds);
3188
- const totalBlocks = allSessions.length;
3189
- const startIdx = (page - 1) * pageSize;
3190
- const endIdx = Math.min(startIdx + pageSize, totalBlocks);
3191
- const pageSessions = allSessions.slice(startIdx, endIdx);
3192
- const hasMore = endIdx < totalBlocks;
3193
- if (pageSessions.length === 0) {
3194
- return {
3195
- blocks: [],
3196
- stats: { totalMessages: 0, hitMessages: 0, totalChars: 0 },
3197
- pagination: { page, pageSize, totalBlocks, totalHits: 0, hasMore: false }
3198
- };
3199
- }
3200
- const blocks = [];
3201
- let totalMessages = 0;
3202
- let totalChars = 0;
3203
- const messagesSql = `
3204
- SELECT ${FULL_MSG_COLUMNS}
3205
- FROM message_context mc
3206
- JOIN message msg ON msg.id = mc.message_id
3207
- JOIN member m ON msg.sender_id = m.id
3208
- LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
3209
- LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
3210
- WHERE mc.segment_id = ?
3211
- ORDER BY msg.ts ASC
3212
- `;
3213
- for (const session of pageSessions) {
3214
- const rows = db.prepare(messagesSql).all(session.id);
3215
- const mapped = rows.map(mapMessageRow);
3216
- const blockMessages = mapped.map((msg) => ({
3217
- ...msg,
3218
- isHit: false
3219
- }));
3220
- for (const msg of mapped) {
3221
- totalChars += msg.content.length;
3222
- }
3223
- blocks.push({
3224
- startTs: session.startTs,
3225
- endTs: session.endTs,
3226
- messages: blockMessages,
3227
- hitCount: 0
3228
- });
3229
- totalMessages += rows.length;
3230
- }
3231
- return {
3232
- blocks,
3233
- stats: {
3234
- totalMessages: page === 1 ? totalMessages : 0,
3235
- hitMessages: 0,
3236
- totalChars: page === 1 ? totalChars : 0
3237
- },
3238
- pagination: { page, pageSize, totalBlocks, totalHits: 0, hasMore }
3239
- };
3240
- }
3241
-
3242
3060
  // ../../packages/core/src/query/advanced/repeat.ts
3243
3061
  function getCatchphraseAnalysis(db, filter) {
3244
3062
  const { clause, params } = buildTimeFilter(filter);
@@ -3289,7 +3107,7 @@ function getCatchphraseAnalysis(db, filter) {
3289
3107
 
3290
3108
  // ../../packages/core/src/query/advanced/social.ts
3291
3109
  function getMentionAnalysis(db, filter) {
3292
- const emptyResult2 = {
3110
+ const emptyResult = {
3293
3111
  topMentioners: [],
3294
3112
  topMentioned: [],
3295
3113
  oneWay: [],
@@ -3301,7 +3119,7 @@ function getMentionAnalysis(db, filter) {
3301
3119
  `SELECT id, platform_id as platformId, COALESCE(group_nickname, account_name, platform_id) as name
3302
3120
  FROM member WHERE COALESCE(account_name, '') != '\u7CFB\u7EDF\u6D88\u606F'`
3303
3121
  ).all();
3304
- if (members.length === 0) return emptyResult2;
3122
+ if (members.length === 0) return emptyResult;
3305
3123
  const nameToMemberId = /* @__PURE__ */ new Map();
3306
3124
  const memberIdToInfo = /* @__PURE__ */ new Map();
3307
3125
  for (const member of members) {
@@ -3346,7 +3164,7 @@ function getMentionAnalysis(db, filter) {
3346
3164
  }
3347
3165
  }
3348
3166
  }
3349
- if (totalMentions === 0) return emptyResult2;
3167
+ if (totalMentions === 0) return emptyResult;
3350
3168
  const topMentioners = [];
3351
3169
  for (const [memberId, count] of mentionerCount.entries()) {
3352
3170
  const info = memberIdToInfo.get(memberId);
@@ -3483,7 +3301,7 @@ function getMentionAnalysis(db, filter) {
3483
3301
  return { topMentioners, topMentioned, oneWay, twoWay, totalMentions, memberDetails };
3484
3302
  }
3485
3303
  function getMentionGraph(db, filter) {
3486
- const emptyResult2 = { nodes: [], links: [], maxLinkValue: 0 };
3304
+ const emptyResult = { nodes: [], links: [], maxLinkValue: 0 };
3487
3305
  const { clause, params } = buildTimeFilter(filter);
3488
3306
  const msgFilterBase = clause ? clause.replace("WHERE", "AND") : "";
3489
3307
  const msgFilterWithSystem = msgFilterBase + " AND COALESCE(m.account_name, '') != '\u7CFB\u7EDF\u6D88\u606F'";
@@ -3493,7 +3311,7 @@ function getMentionGraph(db, filter) {
3493
3311
  FROM member m LEFT JOIN message msg ON m.id = msg.sender_id ${msgFilterWithSystem}
3494
3312
  WHERE COALESCE(m.account_name, '') != '\u7CFB\u7EDF\u6D88\u606F' GROUP BY m.id`
3495
3313
  ).all(...params);
3496
- if (members.length === 0) return emptyResult2;
3314
+ if (members.length === 0) return emptyResult;
3497
3315
  const nameToMemberId = /* @__PURE__ */ new Map();
3498
3316
  const memberIdToInfo = /* @__PURE__ */ new Map();
3499
3317
  for (const member of members) {
@@ -3562,7 +3380,7 @@ function keywordToPattern(keyword) {
3562
3380
  return escaped;
3563
3381
  }
3564
3382
  function getLaughAnalysis(db, filter, keywords) {
3565
- const emptyResult2 = {
3383
+ const emptyResult = {
3566
3384
  rankByRate: [],
3567
3385
  rankByCount: [],
3568
3386
  typeDistribution: [],
@@ -3585,7 +3403,7 @@ function getLaughAnalysis(db, filter, keywords) {
3585
3403
  COALESCE(m.group_nickname, m.account_name, m.platform_id) as name
3586
3404
  FROM message msg JOIN member m ON msg.sender_id = m.id ${whereClause}`
3587
3405
  ).all(...params);
3588
- if (messages.length === 0) return emptyResult2;
3406
+ if (messages.length === 0) return emptyResult;
3589
3407
  const memberStats = /* @__PURE__ */ new Map();
3590
3408
  const typeCount = /* @__PURE__ */ new Map();
3591
3409
  let totalLaughs = 0;
@@ -3618,7 +3436,7 @@ function getLaughAnalysis(db, filter, keywords) {
3618
3436
  }
3619
3437
  }
3620
3438
  }
3621
- if (totalLaughs === 0) return emptyResult2;
3439
+ if (totalLaughs === 0) return emptyResult;
3622
3440
  const rankItems = [];
3623
3441
  for (const [memberId, stats] of memberStats.entries()) {
3624
3442
  if (stats.laughCount > 0) {
@@ -3671,7 +3489,7 @@ function clusterPairKey(aId, bId) {
3671
3489
  }
3672
3490
  function getClusterGraph(db, filter, options) {
3673
3491
  const opts = { ...DEFAULT_CLUSTER_OPTIONS, ...options };
3674
- const emptyResult2 = {
3492
+ const emptyResult = {
3675
3493
  nodes: [],
3676
3494
  links: [],
3677
3495
  maxLinkValue: 0,
@@ -3683,7 +3501,7 @@ function getClusterGraph(db, filter, options) {
3683
3501
  (SELECT COUNT(*) FROM message WHERE sender_id = member.id) as messageCount
3684
3502
  FROM member WHERE COALESCE(account_name, '') != '\u7CFB\u7EDF\u6D88\u606F'`
3685
3503
  ).all();
3686
- if (members.length < 2) return { ...emptyResult2, stats: { ...emptyResult2.stats, totalMembers: members.length } };
3504
+ if (members.length < 2) return { ...emptyResult, stats: { ...emptyResult.stats, totalMembers: members.length } };
3687
3505
  const memberInfo = /* @__PURE__ */ new Map();
3688
3506
  for (const m of members)
3689
3507
  memberInfo.set(m.id, { name: m.name, platformId: m.platformId, messageCount: m.messageCount });
@@ -3700,8 +3518,8 @@ function getClusterGraph(db, filter, options) {
3700
3518
  ).all(...params);
3701
3519
  if (messages.length < 2)
3702
3520
  return {
3703
- ...emptyResult2,
3704
- stats: { ...emptyResult2.stats, totalMembers: members.length, totalMessages: messages.length }
3521
+ ...emptyResult,
3522
+ stats: { ...emptyResult.stats, totalMembers: members.length, totalMessages: messages.length }
3705
3523
  };
3706
3524
  const memberMsgCount = /* @__PURE__ */ new Map();
3707
3525
  for (const msg of messages) memberMsgCount.set(msg.senderId, (memberMsgCount.get(msg.senderId) || 0) + 1);
@@ -3761,8 +3579,8 @@ function getClusterGraph(db, filter, options) {
3761
3579
  const keptEdges = edges.slice(0, opts.topEdges);
3762
3580
  if (keptEdges.length === 0)
3763
3581
  return {
3764
- ...emptyResult2,
3765
- stats: { ...emptyResult2.stats, totalMembers: members.length, totalMessages: messages.length }
3582
+ ...emptyResult,
3583
+ stats: { ...emptyResult.stats, totalMembers: members.length, totalMessages: messages.length }
3766
3584
  };
3767
3585
  const involvedIds = /* @__PURE__ */ new Set();
3768
3586
  for (const edge of keptEdges) {
@@ -3835,7 +3653,7 @@ var ICE_BREAK_THRESHOLD = 24 * 60 * 60;
3835
3653
  var DEFAULT_PERSEVERANCE_THRESHOLD = 300;
3836
3654
  function getRelationshipStats(db, filter, options) {
3837
3655
  const perseveranceThreshold = options?.perseveranceThreshold ?? DEFAULT_PERSEVERANCE_THRESHOLD;
3838
- const emptyResult2 = {
3656
+ const emptyResult = {
3839
3657
  months: [],
3840
3658
  members: [],
3841
3659
  totalSessions: 0,
@@ -3850,7 +3668,7 @@ function getRelationshipStats(db, filter, options) {
3850
3668
  perseveranceThreshold
3851
3669
  };
3852
3670
  const sessionCount = db.prepare("SELECT COUNT(*) as count FROM segment").get();
3853
- if (!sessionCount || sessionCount.count === 0) return emptyResult2;
3671
+ if (!sessionCount || sessionCount.count === 0) return emptyResult;
3854
3672
  const timeConditions = [];
3855
3673
  const params = [];
3856
3674
  if (filter?.startTs !== void 0) {
@@ -6675,6 +6493,14 @@ function getThinkingCompat(provider, modelId) {
6675
6493
  return compat;
6676
6494
  }
6677
6495
 
6496
+ // ../../packages/core/src/ai/tool-result-text.ts
6497
+ var MAX_PERSISTED_TOOL_RESULT_CHARS = 4e3;
6498
+ var TRUNCATION_MARKER = "\n\u2026[truncated]";
6499
+ function truncateToolResultText(text, maxChars = MAX_PERSISTED_TOOL_RESULT_CHARS) {
6500
+ if (text.length <= maxChars) return text;
6501
+ return text.slice(0, maxChars) + TRUNCATION_MARKER;
6502
+ }
6503
+
6678
6504
  // ../../packages/core/src/import/dedup.ts
6679
6505
  function fnv1a64(input) {
6680
6506
  let h0 = 2166136261;
@@ -12765,13 +12591,21 @@ var AIChatManager = class {
12765
12591
  }
12766
12592
  getAIChatTokenUsage(aiChatId) {
12767
12593
  const rows = this.getActivePathRows(aiChatId);
12768
- const result = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
12594
+ const result = {
12595
+ promptTokens: 0,
12596
+ completionTokens: 0,
12597
+ totalTokens: 0,
12598
+ cacheReadTokens: 0,
12599
+ cacheWriteTokens: 0
12600
+ };
12769
12601
  for (const row of rows) {
12770
12602
  if (row.tokenUsage) {
12771
12603
  const usage = JSON.parse(row.tokenUsage);
12772
12604
  result.promptTokens += usage.promptTokens;
12773
12605
  result.completionTokens += usage.completionTokens;
12774
12606
  result.totalTokens += usage.totalTokens;
12607
+ result.cacheReadTokens += usage.cacheReadTokens || 0;
12608
+ result.cacheWriteTokens += usage.cacheWriteTokens || 0;
12775
12609
  }
12776
12610
  }
12777
12611
  return result;
@@ -12793,7 +12627,7 @@ var AIChatManager = class {
12793
12627
  getHistoryForAgent(aiChatId, maxMessages, leafMessageId) {
12794
12628
  const messages = this.getActivePathRows(aiChatId, leafMessageId).map((row) => this.parseMessageRow(row));
12795
12629
  const validMessages = messages.filter(
12796
- (m) => (m.role === "user" || m.role === "assistant" || m.role === "summary") && m.content?.trim()
12630
+ (m) => (m.role === "user" || m.role === "assistant" || m.role === "summary") && (m.content?.trim() || m.role === "assistant" && m.contentBlocks?.some((b) => b.type === "tool"))
12797
12631
  );
12798
12632
  let summaryMsg;
12799
12633
  for (let i = validMessages.length - 1; i >= 0; i--) {
@@ -12817,10 +12651,10 @@ var AIChatManager = class {
12817
12651
  const contextMessages = bufferBoundary ? validMessages.filter((m) => m.role !== "summary" && m.timestamp >= bufferBoundary) : [];
12818
12652
  result = [
12819
12653
  { role: "summary", content: summaryMsg.content },
12820
- ...contextMessages.map((m) => ({ role: m.role, content: m.content }))
12654
+ ...contextMessages.map((m) => ({ role: m.role, content: m.content, contentBlocks: m.contentBlocks }))
12821
12655
  ];
12822
12656
  } else {
12823
- result = validMessages.map((m) => ({ role: m.role, content: m.content }));
12657
+ result = validMessages.map((m) => ({ role: m.role, content: m.content, contentBlocks: m.contentBlocks }));
12824
12658
  }
12825
12659
  if (maxMessages && result.length > maxMessages) {
12826
12660
  if (result.length > 0 && result[0].role === "summary") {
@@ -12848,10 +12682,18 @@ var AIChatManager = class {
12848
12682
  return row ? this.parseMessageRow(row) : null;
12849
12683
  }
12850
12684
  getMessagesAfterSummary(aiChatId, summaryTimestamp) {
12851
- return this.getActivePathRows(aiChatId).filter((row) => row.timestamp > summaryTimestamp && (row.role === "user" || row.role === "assistant")).map((row) => ({ role: row.role, content: row.content, timestamp: row.timestamp }));
12685
+ return this.getActivePathRows(aiChatId).filter((row) => row.timestamp > summaryTimestamp && (row.role === "user" || row.role === "assistant")).map((row) => this.toCompressionMessage(row));
12852
12686
  }
12853
12687
  getAllUserAssistantMessages(aiChatId) {
12854
- return this.getActivePathRows(aiChatId).filter((row) => row.role === "user" || row.role === "assistant").map((row) => ({ role: row.role, content: row.content, timestamp: row.timestamp }));
12688
+ return this.getActivePathRows(aiChatId).filter((row) => row.role === "user" || row.role === "assistant").map((row) => this.toCompressionMessage(row));
12689
+ }
12690
+ toCompressionMessage(row) {
12691
+ return {
12692
+ role: row.role,
12693
+ content: row.content,
12694
+ timestamp: row.timestamp,
12695
+ contentBlocks: row.contentBlocks ? JSON.parse(row.contentBlocks) : void 0
12696
+ };
12855
12697
  }
12856
12698
  getMessageCountAfterSummary(aiChatId) {
12857
12699
  const summary = this.getLatestSummary(aiChatId);
@@ -14218,6 +14060,95 @@ function wrapWithChartSchemaGate(tool, state) {
14218
14060
  };
14219
14061
  }
14220
14062
 
14063
+ // ../../packages/node-runtime/src/ai/agent/history.ts
14064
+ function createEmptyPiUsage() {
14065
+ return {
14066
+ input: 0,
14067
+ output: 0,
14068
+ cacheRead: 0,
14069
+ cacheWrite: 0,
14070
+ totalTokens: 0,
14071
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
14072
+ };
14073
+ }
14074
+ function isReplayableToolBlock(block) {
14075
+ if (block.type !== "tool") return false;
14076
+ const { toolCallId, result, status } = block.tool;
14077
+ return typeof toolCallId === "string" && toolCallId.length > 0 && typeof result === "string" && (status === "done" || status === "error");
14078
+ }
14079
+ function stripInternalParams(params) {
14080
+ if (!params) return {};
14081
+ const cleaned = {};
14082
+ for (const [key, value] of Object.entries(params)) {
14083
+ if (!key.startsWith("_")) cleaned[key] = value;
14084
+ }
14085
+ return cleaned;
14086
+ }
14087
+ function makeAssistantMessage(content, stopReason, modelInfo) {
14088
+ return {
14089
+ role: "assistant",
14090
+ content,
14091
+ api: modelInfo?.api ?? "openai-completions",
14092
+ provider: modelInfo?.provider ?? "chatlab",
14093
+ model: modelInfo?.id ?? "unknown",
14094
+ usage: createEmptyPiUsage(),
14095
+ stopReason,
14096
+ timestamp: Date.now()
14097
+ };
14098
+ }
14099
+ function replayAssistantBlocks(blocks, out, options) {
14100
+ const { modelInfo, thinkingSignature } = options ?? {};
14101
+ const replayThinking = !!thinkingSignature && blocks.some(isReplayableToolBlock);
14102
+ let content = [];
14103
+ for (const block of blocks) {
14104
+ if (block.type === "text") {
14105
+ if (block.text.trim()) content.push({ type: "text", text: block.text });
14106
+ } else if (block.type === "think" && replayThinking && block.text.trim()) {
14107
+ content.push({ type: "thinking", thinking: block.text, thinkingSignature });
14108
+ } else if (isReplayableToolBlock(block)) {
14109
+ content.push({
14110
+ type: "toolCall",
14111
+ id: block.tool.toolCallId,
14112
+ name: block.tool.name,
14113
+ arguments: stripInternalParams(block.tool.params)
14114
+ });
14115
+ out.push(makeAssistantMessage(content, "toolUse", modelInfo));
14116
+ out.push({
14117
+ role: "toolResult",
14118
+ toolCallId: block.tool.toolCallId,
14119
+ toolName: block.tool.name,
14120
+ content: [{ type: "text", text: truncateToolResultText(block.tool.result) || "(empty result)" }],
14121
+ isError: block.tool.isError ?? block.tool.status === "error",
14122
+ timestamp: Date.now()
14123
+ });
14124
+ content = [];
14125
+ }
14126
+ }
14127
+ if (content.length > 0) {
14128
+ out.push(makeAssistantMessage(content, "stop", modelInfo));
14129
+ }
14130
+ }
14131
+ function toPiHistoryMessages(messages, options) {
14132
+ const out = [];
14133
+ for (const msg of messages) {
14134
+ if (msg.role === "user") {
14135
+ out.push({
14136
+ role: "user",
14137
+ content: [{ type: "text", text: msg.content || "" }],
14138
+ timestamp: Date.now()
14139
+ });
14140
+ continue;
14141
+ }
14142
+ const replayable = msg.role === "assistant" && msg.contentBlocks?.some(isReplayableToolBlock);
14143
+ if (replayable) {
14144
+ replayAssistantBlocks(msg.contentBlocks, out, options);
14145
+ } else {
14146
+ out.push(makeAssistantMessage([{ type: "text", text: msg.content || "" }], "stop", options?.modelInfo));
14147
+ }
14148
+ }
14149
+ return out;
14150
+ }
14151
+
14221
14152
  // ../../packages/node-runtime/src/ai/compression/compressor.ts
14222
14153
  var DEFAULT_CONTEXT_WINDOW = 128e3;
14223
14154
  var INITIAL_COMPRESSION_PROMPT = `You are a context compression assistant. Compress the conversation below into a structured summary.
@@ -14285,6 +14216,9 @@ async function checkAndCompress(aiChatId, config, systemPrompt, llmAdapter, conv
14285
14216
  }
14286
14217
  for (const msg of messages) {
14287
14218
  historyForTokenCount.push({ role: msg.role, content: msg.content });
14219
+ for (const toolText of replayedToolResultTexts(msg.contentBlocks)) {
14220
+ historyForTokenCount.push({ role: "tool", content: toolText });
14221
+ }
14288
14222
  }
14289
14223
  const currentTokens = countMessagesTokens(historyForTokenCount, systemPrompt);
14290
14224
  logger.info("Compression", `Token check: ${currentTokens} / ${thresholdTokens} (${contextWindow} window)`, {
@@ -14316,10 +14250,13 @@ async function checkAndCompress(aiChatId, config, systemPrompt, llmAdapter, conv
14316
14250
  bufferBoundaryTimestamp: bufferBoundary,
14317
14251
  compressedMessageCount: messagesToCompress.length
14318
14252
  });
14319
- const afterTokenCount = [
14320
- { role: "assistant", content: summaryText },
14321
- ...bufferMessages.map((m) => ({ role: m.role, content: m.content }))
14322
- ];
14253
+ const afterTokenCount = [{ role: "assistant", content: summaryText }];
14254
+ for (const m of bufferMessages) {
14255
+ afterTokenCount.push({ role: m.role, content: m.content });
14256
+ for (const toolText of replayedToolResultTexts(m.contentBlocks)) {
14257
+ afterTokenCount.push({ role: "tool", content: toolText });
14258
+ }
14259
+ }
14323
14260
  const tokensAfter = countMessagesTokens(afterTokenCount, systemPrompt);
14324
14261
  if (tokensAfter >= thresholdTokens) {
14325
14262
  logger.warn(
@@ -14347,11 +14284,22 @@ async function checkAndCompress(aiChatId, config, systemPrompt, llmAdapter, conv
14347
14284
  return { compressed: false, reason: "error", error: String(error) };
14348
14285
  }
14349
14286
  }
14287
+ function replayedToolResultTexts(blocks) {
14288
+ if (!blocks) return [];
14289
+ return blocks.filter(isReplayableToolBlock).map((block) => truncateToolResultText(block.tool.result));
14290
+ }
14291
+ function countMessageTokensWithTools(msg) {
14292
+ let tokens = countTokens(msg.content) + 4;
14293
+ for (const toolText of replayedToolResultTexts(msg.contentBlocks)) {
14294
+ tokens += countTokens(toolText) + 4;
14295
+ }
14296
+ return tokens;
14297
+ }
14350
14298
  function splitMessagesForCompression(messages, bufferTokenBudget) {
14351
14299
  let bufferTokens = 0;
14352
14300
  let splitIndex = messages.length;
14353
14301
  for (let i = messages.length - 1; i >= 0; i--) {
14354
- const msgTokens = countTokens(messages[i].content) + 4;
14302
+ const msgTokens = countMessageTokensWithTools(messages[i]);
14355
14303
  if (bufferTokens + msgTokens > bufferTokenBudget) {
14356
14304
  splitIndex = i + 1;
14357
14305
  break;
@@ -14377,6 +14325,10 @@ ${existingSummary.content}
14377
14325
  for (const msg of messagesToCompress) {
14378
14326
  const roleLabel = msg.role === "user" ? "User" : "Assistant";
14379
14327
  parts.push(`${roleLabel}: ${msg.content}`);
14328
+ for (const block of (msg.contentBlocks ?? []).filter(isReplayableToolBlock)) {
14329
+ parts.push(`[Tool result: ${block.tool.name}]
14330
+ ${truncateToolResultText(block.tool.result)}`);
14331
+ }
14380
14332
  }
14381
14333
  return parts.join("\n\n");
14382
14334
  }
@@ -14861,6 +14813,7 @@ function formatToolResultAsText(details) {
14861
14813
  const messages = details.messages;
14862
14814
  for (const [key, value] of Object.entries(details)) {
14863
14815
  if (key === "messages") continue;
14816
+ if (key === "rawMessages") continue;
14864
14817
  if (value === void 0 || value === null) continue;
14865
14818
  if (typeof value === "object") {
14866
14819
  if ("start" in value && "end" in value) {
@@ -15002,37 +14955,6 @@ import {
15002
14955
  var DEFAULT_MAX_TOOL_ROUNDS = 20;
15003
14956
 
15004
14957
  // ../../packages/node-runtime/src/ai/agent/core.ts
15005
- function createEmptyPiUsage() {
15006
- return {
15007
- input: 0,
15008
- output: 0,
15009
- cacheRead: 0,
15010
- cacheWrite: 0,
15011
- totalTokens: 0,
15012
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
15013
- };
15014
- }
15015
- function toPiHistoryMessages(messages) {
15016
- return messages.map((msg) => {
15017
- if (msg.role === "user") {
15018
- return {
15019
- role: "user",
15020
- content: [{ type: "text", text: msg.content || "" }],
15021
- timestamp: Date.now()
15022
- };
15023
- }
15024
- return {
15025
- role: "assistant",
15026
- content: [{ type: "text", text: msg.content || "" }],
15027
- api: "openai-completions",
15028
- provider: "chatlab",
15029
- model: "unknown",
15030
- usage: createEmptyPiUsage(),
15031
- stopReason: "stop",
15032
- timestamp: Date.now()
15033
- };
15034
- });
15035
- }
15036
14958
  function isPiMessage(message) {
15037
14959
  return message.role === "user" || message.role === "assistant" || message.role === "toolResult";
15038
14960
  }
@@ -15053,7 +14975,13 @@ async function runAgentCore(options) {
15053
14975
  } = options;
15054
14976
  await initTokenizer();
15055
14977
  const resolvedStreamFn = options.streamFn ?? defaultStreamSimple;
15056
- const totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
14978
+ const totalUsage = {
14979
+ promptTokens: 0,
14980
+ completionTokens: 0,
14981
+ totalTokens: 0,
14982
+ cacheReadTokens: 0,
14983
+ cacheWriteTokens: 0
14984
+ };
15057
14985
  const toolsUsed = [];
15058
14986
  let toolRounds = 0;
15059
14987
  const addPiUsage = (usage) => {
@@ -15061,6 +14989,8 @@ async function runAgentCore(options) {
15061
14989
  totalUsage.promptTokens += usage.input || 0;
15062
14990
  totalUsage.completionTokens += usage.output || 0;
15063
14991
  totalUsage.totalTokens += usage.totalTokens || usage.input + usage.output || 0;
14992
+ totalUsage.cacheReadTokens += usage.cacheRead || 0;
14993
+ totalUsage.cacheWriteTokens += usage.cacheWrite || 0;
15064
14994
  };
15065
14995
  if (abortSignal?.aborted) {
15066
14996
  return { usage: totalUsage, finalMessages: [], toolsUsed: [], toolRounds: 0 };
@@ -15080,13 +15010,18 @@ async function runAgentCore(options) {
15080
15010
  return clampThinkingLevel(piModel, level);
15081
15011
  })();
15082
15012
  const finalThinkingLevel = resolvedThinkingLevel ?? (piModel.reasoning ? void 0 : "off");
15013
+ const thinkingFormat = piModel.compat?.thinkingFormat;
15014
+ const replayOptions = piModel.reasoning && thinkingFormat === "deepseek" ? {
15015
+ modelInfo: { api: piModel.api, provider: piModel.provider, id: piModel.id },
15016
+ thinkingSignature: "reasoning_content"
15017
+ } : void 0;
15083
15018
  const coreAgent = new PiAgentCore({
15084
15019
  initialState: {
15085
15020
  systemPrompt,
15086
15021
  model: effectiveModel,
15087
15022
  thinkingLevel: finalThinkingLevel,
15088
15023
  tools: maxToolRounds > 0 ? tools : [],
15089
- messages: toPiHistoryMessages(history)
15024
+ messages: toPiHistoryMessages(history, replayOptions)
15090
15025
  },
15091
15026
  getApiKey: () => apiKey,
15092
15027
  streamFn: resolvedStreamFn,
@@ -15146,11 +15081,18 @@ async function runAgentCore(options) {
15146
15081
  toolsUsed.push(event.toolName);
15147
15082
  onEvent({
15148
15083
  type: "tool_start",
15084
+ toolCallId: event.toolCallId,
15149
15085
  toolName: event.toolName,
15150
15086
  toolParams: event.args || {}
15151
15087
  });
15152
15088
  } else if (event.type === "tool_execution_end") {
15153
- onEvent({ type: "tool_end", toolName: event.toolName, toolResult: event.result });
15089
+ onEvent({
15090
+ type: "tool_end",
15091
+ toolCallId: event.toolCallId,
15092
+ toolName: event.toolName,
15093
+ toolResult: event.result,
15094
+ isError: event.isError
15095
+ });
15154
15096
  } else if (event.type === "turn_end") {
15155
15097
  const hadToolCalls = event.toolResults.length > 0;
15156
15098
  if (hadToolCalls) {
@@ -15835,7 +15777,13 @@ function estimateContextTokens(systemPrompt, messages, pendingUserMessage) {
15835
15777
  var AgentEventHandler = class {
15836
15778
  toolsUsed = [];
15837
15779
  toolRounds = 0;
15838
- totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
15780
+ totalUsage = {
15781
+ promptTokens: 0,
15782
+ completionTokens: 0,
15783
+ totalTokens: 0,
15784
+ cacheReadTokens: 0,
15785
+ cacheWriteTokens: 0
15786
+ };
15839
15787
  lastStatusAt = 0;
15840
15788
  onChunk;
15841
15789
  context;
@@ -15865,12 +15813,18 @@ var AgentEventHandler = class {
15865
15813
  case "tool_start": {
15866
15814
  const params = this.normalizeToolParams(event.toolName, event.toolParams);
15867
15815
  this.toolsUsed.push(event.toolName);
15868
- this.onChunk({ type: "tool_start", toolName: event.toolName, toolParams: params });
15816
+ this.onChunk({ type: "tool_start", toolCallId: event.toolCallId, toolName: event.toolName, toolParams: params });
15869
15817
  this.emitStatus("tool_running", messages, { currentTool: event.toolName, force: true });
15870
15818
  break;
15871
15819
  }
15872
15820
  case "tool_end":
15873
- this.onChunk({ type: "tool_result", toolName: event.toolName, toolResult: event.toolResult });
15821
+ this.onChunk({
15822
+ type: "tool_result",
15823
+ toolCallId: event.toolCallId,
15824
+ toolName: event.toolName,
15825
+ toolResult: event.toolResult,
15826
+ toolIsError: event.isError
15827
+ });
15874
15828
  this.emitStatus("thinking", messages, { force: true });
15875
15829
  break;
15876
15830
  case "turn_end":
@@ -15887,7 +15841,9 @@ var AgentEventHandler = class {
15887
15841
  return {
15888
15842
  promptTokens: this.totalUsage.promptTokens,
15889
15843
  completionTokens: this.totalUsage.completionTokens,
15890
- totalTokens: this.totalUsage.totalTokens
15844
+ totalTokens: this.totalUsage.totalTokens,
15845
+ cacheReadTokens: this.totalUsage.cacheReadTokens,
15846
+ cacheWriteTokens: this.totalUsage.cacheWriteTokens
15891
15847
  };
15892
15848
  }
15893
15849
  emitStatus(phase, messages, options) {
@@ -19571,6 +19527,127 @@ function exportSessionMode(db, params, writer, progress) {
19571
19527
  return { totalMessages, blockIndex };
19572
19528
  }
19573
19529
 
19530
+ // ../../packages/node-runtime/src/export/format-exporter.ts
19531
+ function queryMessages2(db, timeFilter) {
19532
+ const hasFilter = !!timeFilter;
19533
+ const sql = `
19534
+ SELECT msg.ts,
19535
+ COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
19536
+ msg.content
19537
+ FROM message msg
19538
+ JOIN member m ON msg.sender_id = m.id
19539
+ ${hasFilter ? "WHERE msg.ts >= ? AND msg.ts <= ?" : ""}
19540
+ ORDER BY msg.ts ASC, msg.id ASC
19541
+ `;
19542
+ const params = [];
19543
+ if (hasFilter) {
19544
+ params.push(timeFilter.startTs, timeFilter.endTs);
19545
+ }
19546
+ return db.prepare(sql).all(...params);
19547
+ }
19548
+ function formatTime(ts) {
19549
+ return new Date(ts * 1e3).toLocaleString();
19550
+ }
19551
+ function formatTimeShort(ts) {
19552
+ return new Date(ts * 1e3).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit", second: "2-digit" });
19553
+ }
19554
+ function exportAsTxt(messages, sessionName) {
19555
+ const lines = [`${sessionName}
19556
+ `];
19557
+ let lastDate = "";
19558
+ for (const msg of messages) {
19559
+ const date = new Date(msg.ts * 1e3).toLocaleDateString();
19560
+ if (date !== lastDate) {
19561
+ lines.push(`
19562
+ --- ${date} ---
19563
+ `);
19564
+ lastDate = date;
19565
+ }
19566
+ lines.push(`${formatTimeShort(msg.ts)} ${msg.senderName}: ${msg.content || "[non-text]"}`);
19567
+ }
19568
+ return lines.join("\n");
19569
+ }
19570
+ function exportAsJson(messages, sessionName) {
19571
+ const data = {
19572
+ sessionName,
19573
+ exportTime: (/* @__PURE__ */ new Date()).toISOString(),
19574
+ totalMessages: messages.length,
19575
+ messages: messages.map((msg) => ({
19576
+ timestamp: msg.ts,
19577
+ time: formatTime(msg.ts),
19578
+ sender: msg.senderName,
19579
+ content: msg.content || ""
19580
+ }))
19581
+ };
19582
+ return JSON.stringify(data, null, 2);
19583
+ }
19584
+ function exportAsMarkdown(messages, sessionName) {
19585
+ const lines = [`# ${sessionName}
19586
+ `, `> Export time: ${(/* @__PURE__ */ new Date()).toLocaleString()}
19587
+ `];
19588
+ let lastDate = "";
19589
+ for (const msg of messages) {
19590
+ const date = new Date(msg.ts * 1e3).toLocaleDateString();
19591
+ if (date !== lastDate) {
19592
+ lines.push(`
19593
+ ## ${date}
19594
+ `);
19595
+ lastDate = date;
19596
+ }
19597
+ lines.push(`**${formatTimeShort(msg.ts)} ${msg.senderName}**: ${msg.content || "*[non-text]*"}`);
19598
+ }
19599
+ return lines.join("\n");
19600
+ }
19601
+ var FORMAT_CONFIG = {
19602
+ txt: { ext: "txt", mime: "text/plain; charset=utf-8" },
19603
+ json: { ext: "json", mime: "application/json; charset=utf-8" },
19604
+ markdown: { ext: "md", mime: "text/markdown; charset=utf-8" }
19605
+ };
19606
+ function exportWithFormat(params, openDatabase) {
19607
+ const db = openDatabase(params.sessionId);
19608
+ if (!db) {
19609
+ return { success: false, error: "Cannot open database", totalMessages: 0, content: "", filename: "", mimeType: "" };
19610
+ }
19611
+ try {
19612
+ const messages = queryMessages2(db, params.timeFilter);
19613
+ if (messages.length === 0) {
19614
+ return {
19615
+ success: false,
19616
+ error: "No messages found in the specified range",
19617
+ totalMessages: 0,
19618
+ content: "",
19619
+ filename: "",
19620
+ mimeType: ""
19621
+ };
19622
+ }
19623
+ const { ext, mime } = FORMAT_CONFIG[params.format];
19624
+ let content;
19625
+ switch (params.format) {
19626
+ case "txt":
19627
+ content = exportAsTxt(messages, params.sessionName);
19628
+ break;
19629
+ case "json":
19630
+ content = exportAsJson(messages, params.sessionName);
19631
+ break;
19632
+ case "markdown":
19633
+ content = exportAsMarkdown(messages, params.sessionName);
19634
+ break;
19635
+ }
19636
+ const timestamp = Date.now();
19637
+ const filename = `${params.sessionName}_export_${timestamp}.${ext}`;
19638
+ return { success: true, totalMessages: messages.length, content, filename, mimeType: mime };
19639
+ } catch (error) {
19640
+ return {
19641
+ success: false,
19642
+ error: String(error),
19643
+ totalMessages: 0,
19644
+ content: "",
19645
+ filename: "",
19646
+ mimeType: ""
19647
+ };
19648
+ }
19649
+ }
19650
+
19574
19651
  // ../../packages/node-runtime/src/preferences.ts
19575
19652
  import * as fs36 from "fs";
19576
19653
  import * as path33 from "path";
@@ -20363,6 +20440,7 @@ function checkCanGenerate(adapter, sessionId, segmentIds) {
20363
20440
  // ../../packages/node-runtime/src/services/export-service.ts
20364
20441
  var export_service_exports = {};
20365
20442
  __export(export_service_exports, {
20443
+ exportFormatted: () => exportFormatted,
20366
20444
  exportMarkdown: () => exportMarkdown
20367
20445
  });
20368
20446
  function exportMarkdown(adapter, params) {
@@ -20384,6 +20462,9 @@ function exportMarkdown(adapter, params) {
20384
20462
  );
20385
20463
  return { result, content: chunks.join("") };
20386
20464
  }
20465
+ function exportFormatted(adapter, params) {
20466
+ return exportWithFormat(params, (sessionId) => adapter.openReadonly(sessionId));
20467
+ }
20387
20468
 
20388
20469
  // ../../packages/node-runtime/src/services/adapters/database-manager-adapter.ts
20389
20470
  import * as fs38 from "fs";
@@ -20536,8 +20617,6 @@ export {
20536
20617
  getMemberNameHistory,
20537
20618
  getMembersWithAliases,
20538
20619
  executeParameterizedSql,
20539
- filterMessagesWithContext,
20540
- getMultipleSessionsMessages,
20541
20620
  getCatchphraseAnalysis,
20542
20621
  getMentionAnalysis,
20543
20622
  getMentionGraph,
@@ -20646,4 +20725,4 @@ export {
20646
20725
  createDatabaseManagerAdapter,
20647
20726
  MergeSessionCache
20648
20727
  };
20649
- //# sourceMappingURL=chunk-QY67NN65.mjs.map
20728
+ //# sourceMappingURL=chunk-GUGKY2GV.mjs.map