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.
- package/dist/{chat-command-ZP4WJVWC.mjs → chat-command-T3Z4O4M5.mjs} +4 -4
- package/dist/{chunk-WXC6RZCX.mjs → chunk-3APSMVOM.mjs} +2 -2
- package/dist/{chunk-ILGSSXOG.mjs → chunk-6O2SW5GL.mjs} +5 -4
- package/dist/chunk-6O2SW5GL.mjs.map +1 -0
- package/dist/{chunk-SJIOPSMM.mjs → chunk-AZZYKUBR.mjs} +17 -39
- package/dist/chunk-AZZYKUBR.mjs.map +1 -0
- package/dist/{chunk-IRZRIHIT.mjs → chunk-FACKH2BR.mjs} +2 -2
- package/dist/{chunk-TC74HESZ.mjs → chunk-FAOZNMPK.mjs} +2 -2
- package/dist/{chunk-QY67NN65.mjs → chunk-GUGKY2GV.mjs} +329 -250
- package/dist/chunk-GUGKY2GV.mjs.map +1 -0
- package/dist/{chunk-UB4XBM4R.mjs → chunk-MZG2GLJR.mjs} +2 -2
- package/dist/{chunk-6G7AIF7I.mjs → chunk-SC77N66X.mjs} +9 -9
- package/dist/cli.mjs +3 -3
- package/dist/{http-J3IOFFIA.mjs → http-6LQUOYQ6.mjs} +8 -8
- package/dist/{import-POYG5LOX.mjs → import-B2MAIBAK.mjs} +4 -4
- package/dist/index.mjs +8 -8
- package/dist/{mcp-7HH7UMXT.mjs → mcp-ZMMYW46I.mjs} +4 -4
- package/dist/{stream-import-O3H3FGV2.mjs → stream-import-FHFBCEDV.mjs} +3 -3
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-CgtTQTfN.js +182 -0
- package/dist-web/assets/MessageExportModal-B8DKeSAH.js +1 -0
- package/dist-web/assets/{electron-B3DFm1cC.js → electron-C-aMus7e.js} +1 -1
- package/dist-web/assets/{electron-BMM4Nfty.js → electron-dBbXcMDB.js} +1 -1
- package/dist-web/assets/{fetch-BGfaAqO9.js → fetch-B-LdQP9s.js} +1 -1
- package/dist-web/assets/{fetch-BaJDB31c.js → fetch-B26JuD67.js} +1 -1
- package/dist-web/assets/{fetch-BjDJgdN0.js → fetch-BLKibnXa.js} +1 -1
- package/dist-web/assets/{fetch-BFtuJaa1.js → fetch-BNNqdS2B.js} +1 -1
- package/dist-web/assets/fetch-BSJY7tRo.js +1 -0
- package/dist-web/assets/{fetch-C5CLcpQW.js → fetch-CV8jezsM.js} +1 -1
- package/dist-web/assets/{fetch-DQZvdHnG.js → fetch-CvnJ4Jgf.js} +1 -1
- package/dist-web/assets/{fetch-ArMjdMcy.js → fetch-DP3yNfJM.js} +1 -1
- package/dist-web/assets/{fetch-SYrb-sZe.js → fetch-phbrO2bY.js} +1 -1
- package/dist-web/assets/{fetch-Dhfbt1BQ.js → fetch-xB6cl_1L.js} +1 -1
- package/dist-web/assets/index-8Zcs8peI.css +1 -0
- package/dist-web/assets/index-B_lOzUD8.js +2 -0
- package/dist-web/assets/index-BvWcJc3c.js +173 -0
- package/dist-web/assets/{index-D7_ch4zf.js → index-CSDI5pAA.js} +2 -2
- package/dist-web/assets/{index-CGNgUIT-.css → index-CX2FucK5.css} +1 -1
- package/dist-web/assets/{index-DK9LEEzT.js → index-DJQFNVUJ.js} +1 -1
- package/dist-web/assets/index-DZ6Szt_y.js +163 -0
- package/dist-web/assets/index-DhpclWeF.js +11 -0
- package/dist-web/assets/index-Dhql4DJr.css +1 -0
- package/dist-web/assets/{web-zEXsvoZW.js → web-DUQU-v8U.js} +1 -1
- package/dist-web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-ILGSSXOG.mjs.map +0 -1
- package/dist/chunk-QY67NN65.mjs.map +0 -1
- package/dist/chunk-SJIOPSMM.mjs.map +0 -1
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BTJxEma5.js +0 -182
- package/dist-web/assets/MessageExportModal-C7NgEL8T.js +0 -1
- package/dist-web/assets/fetch-DnEP0uyF.js +0 -1
- package/dist-web/assets/index-C3A_Rjh-.css +0 -1
- package/dist-web/assets/index-CWfkrx37.js +0 -173
- package/dist-web/assets/index-D3N4NDFx.css +0 -1
- package/dist-web/assets/index-DqDa_on9.js +0 -9
- package/dist-web/assets/index-DrN1G9bl.js +0 -2
- package/dist-web/assets/index-MdYeovYo.js +0 -163
- /package/dist/{chat-command-ZP4WJVWC.mjs.map → chat-command-T3Z4O4M5.mjs.map} +0 -0
- /package/dist/{chunk-WXC6RZCX.mjs.map → chunk-3APSMVOM.mjs.map} +0 -0
- /package/dist/{chunk-IRZRIHIT.mjs.map → chunk-FACKH2BR.mjs.map} +0 -0
- /package/dist/{chunk-TC74HESZ.mjs.map → chunk-FAOZNMPK.mjs.map} +0 -0
- /package/dist/{chunk-UB4XBM4R.mjs.map → chunk-MZG2GLJR.mjs.map} +0 -0
- /package/dist/{chunk-6G7AIF7I.mjs.map → chunk-SC77N66X.mjs.map} +0 -0
- /package/dist/{http-J3IOFFIA.mjs.map → http-6LQUOYQ6.mjs.map} +0 -0
- /package/dist/{import-POYG5LOX.mjs.map → import-B2MAIBAK.mjs.map} +0 -0
- /package/dist/{mcp-7HH7UMXT.mjs.map → mcp-ZMMYW46I.mjs.map} +0 -0
- /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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 { ...
|
|
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
|
-
...
|
|
3704
|
-
stats: { ...
|
|
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
|
-
...
|
|
3765
|
-
stats: { ...
|
|
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
|
|
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
|
|
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 = {
|
|
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) => (
|
|
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) => (
|
|
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
|
-
|
|
14321
|
-
|
|
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 =
|
|
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 = {
|
|
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({
|
|
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 = {
|
|
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({
|
|
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-
|
|
20728
|
+
//# sourceMappingURL=chunk-GUGKY2GV.mjs.map
|