@openacp/cli 2026.327.2 → 2026.327.5

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 (42) hide show
  1. package/dist/{adapter-LC2QSDAS.js → adapter-JQFQ3JAO.js} +3 -3
  2. package/dist/{adapter-Y55NXX6I.js → adapter-UORRGHNH.js} +32 -8
  3. package/dist/adapter-UORRGHNH.js.map +1 -0
  4. package/dist/{chunk-TRXBJEZ5.js → chunk-32LVIEPW.js} +49 -19
  5. package/dist/chunk-32LVIEPW.js.map +1 -0
  6. package/dist/{chunk-UMT7RU77.js → chunk-HRKAXFWR.js} +2 -2
  7. package/dist/{chunk-36YQ44D7.js → chunk-P2G275VD.js} +2 -2
  8. package/dist/{chunk-HUWOFP2H.js → chunk-S3ZGPPXY.js} +3 -3
  9. package/dist/{chunk-LP45RCA4.js → chunk-XWDW3XBE.js} +338 -414
  10. package/dist/chunk-XWDW3XBE.js.map +1 -0
  11. package/dist/{chunk-3ASUU6WW.js → chunk-ZNSO2QVC.js} +2 -2
  12. package/dist/cli.js +60 -40
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{config-editor-3IKBPZA7.js → config-editor-7PKW42GZ.js} +2 -2
  15. package/dist/{core-plugins-ROU4GPLT.js → core-plugins-Y5US6RED.js} +4 -4
  16. package/dist/index.d.ts +92 -93
  17. package/dist/index.js +35 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/{main-UVTZ46WP.js → main-3GF3EQTE.js} +8 -8
  20. package/dist/plugin-installer-QVJP6VKV.js +42 -0
  21. package/dist/plugin-installer-QVJP6VKV.js.map +1 -0
  22. package/dist/{setup-EYAFK2WI.js → setup-A7VPW46C.js} +8 -6
  23. package/dist/setup-A7VPW46C.js.map +1 -0
  24. package/dist/{slack-37ZWBDUI.js → slack-2XNWBOWH.js} +2 -2
  25. package/dist/{telegram-2ZCCCZIY.js → telegram-E65IWFBW.js} +2 -2
  26. package/package.json +1 -1
  27. package/dist/adapter-Y55NXX6I.js.map +0 -1
  28. package/dist/chunk-LP45RCA4.js.map +0 -1
  29. package/dist/chunk-TRXBJEZ5.js.map +0 -1
  30. package/dist/plugin-installer-GQ2P3Q3E.js +0 -23
  31. package/dist/plugin-installer-GQ2P3Q3E.js.map +0 -1
  32. package/dist/setup-EYAFK2WI.js.map +0 -1
  33. /package/dist/{adapter-LC2QSDAS.js.map → adapter-JQFQ3JAO.js.map} +0 -0
  34. /package/dist/{chunk-UMT7RU77.js.map → chunk-HRKAXFWR.js.map} +0 -0
  35. /package/dist/{chunk-36YQ44D7.js.map → chunk-P2G275VD.js.map} +0 -0
  36. /package/dist/{chunk-HUWOFP2H.js.map → chunk-S3ZGPPXY.js.map} +0 -0
  37. /package/dist/{chunk-3ASUU6WW.js.map → chunk-ZNSO2QVC.js.map} +0 -0
  38. /package/dist/{config-editor-3IKBPZA7.js.map → config-editor-7PKW42GZ.js.map} +0 -0
  39. /package/dist/{core-plugins-ROU4GPLT.js.map → core-plugins-Y5US6RED.js.map} +0 -0
  40. /package/dist/{main-UVTZ46WP.js.map → main-3GF3EQTE.js.map} +0 -0
  41. /package/dist/{slack-37ZWBDUI.js.map → slack-2XNWBOWH.js.map} +0 -0
  42. /package/dist/{telegram-2ZCCCZIY.js.map → telegram-E65IWFBW.js.map} +0 -0
@@ -11,6 +11,7 @@ import {
11
11
  import {
12
12
  BaseRenderer,
13
13
  MessagingAdapter,
14
+ evaluateNoise,
14
15
  extractContentText,
15
16
  formatTokens,
16
17
  formatToolSummary,
@@ -20,7 +21,7 @@ import {
20
21
  splitMessage,
21
22
  stripCodeFences,
22
23
  truncateContent
23
- } from "./chunk-TRXBJEZ5.js";
24
+ } from "./chunk-32LVIEPW.js";
24
25
  import {
25
26
  CheckpointReader,
26
27
  DEFAULT_MAX_TOKENS
@@ -125,15 +126,7 @@ function formatToolCall(tool, verbosity = "medium") {
125
126
  return text;
126
127
  }
127
128
  function formatToolUpdate(update, verbosity = "medium") {
128
- const si = resolveToolIcon(update);
129
- const name = update.name || "Tool";
130
- const label = verbosity === "low" ? formatToolTitle(name, update.rawInput, update.displayTitle) : formatToolSummary(name, update.rawInput, update.displaySummary);
131
- let text = `${si} <b>${escapeHtml(label)}</b>`;
132
- text += formatViewerLinks(update.viewerLinks, update.viewerFilePath);
133
- if (verbosity === "high") {
134
- text += formatHighDetails(update.rawInput, update.content, 3800);
135
- }
136
- return text;
129
+ return formatToolCall(update, verbosity);
137
130
  }
138
131
  function formatHighDetails(rawInput, content, maxLen) {
139
132
  let text = "";
@@ -165,12 +158,8 @@ function formatViewerLinks(links, filePath) {
165
158
  \u{1F4DD} <a href="${escapeHtml(links.diff)}">View diff${fileName ? ` \u2014 ${escapeHtml(fileName)}` : ""}</a>`;
166
159
  return text;
167
160
  }
168
- function formatPlan(plan, verbosity = "medium") {
161
+ function formatPlan(plan) {
169
162
  const { entries } = plan;
170
- if (verbosity === "medium") {
171
- const done = entries.filter((e) => e.status === "completed").length;
172
- return `\u{1F4CB} <b>Plan:</b> ${done}/${entries.length} steps completed`;
173
- }
174
163
  const statusIcon = {
175
164
  pending: "\u2B1C",
176
165
  in_progress: "\u{1F504}",
@@ -203,6 +192,67 @@ ${bar} ${pct}%`;
203
192
  function splitMessage2(text, maxLength = 3800) {
204
193
  return splitMessage(text, maxLength);
205
194
  }
195
+ function renderToolCard(snap) {
196
+ const sections = [];
197
+ const { totalVisible, completedVisible, allComplete } = snap;
198
+ const headerCheck = allComplete ? " \u2705" : "";
199
+ if (totalVisible > 0) {
200
+ sections.push(
201
+ `<b>\u{1F4CB} Tools (${completedVisible}/${totalVisible})</b>${headerCheck}`
202
+ );
203
+ }
204
+ const visible = snap.entries.filter((e) => !e.hidden);
205
+ const completed = visible.filter(
206
+ (e) => e.status === "completed" || e.status === "done" || e.status === "failed"
207
+ );
208
+ const running = visible.filter(
209
+ (e) => e.status !== "completed" && e.status !== "done" && e.status !== "failed"
210
+ );
211
+ for (const entry of completed) {
212
+ let line = `${entry.icon} ${escapeHtml(entry.label)}`;
213
+ if (entry.viewerLinks) {
214
+ const links = [];
215
+ const fileName = entry.viewerFilePath?.split("/").pop() ?? "";
216
+ if (entry.viewerLinks.file)
217
+ links.push(
218
+ `\u{1F4C4} <a href="${escapeHtml(entry.viewerLinks.file)}">View ${escapeHtml(fileName || "file")}</a>`
219
+ );
220
+ if (entry.viewerLinks.diff)
221
+ links.push(
222
+ `\u{1F4DD} <a href="${escapeHtml(entry.viewerLinks.diff)}">View diff</a>`
223
+ );
224
+ if (links.length > 0) line += `
225
+ ${links.join(" \xB7 ")}`;
226
+ }
227
+ sections.push(line);
228
+ }
229
+ if (snap.planEntries && snap.planEntries.length > 0) {
230
+ const planDone = snap.planEntries.filter(
231
+ (e) => e.status === "completed"
232
+ ).length;
233
+ const planTotal = snap.planEntries.length;
234
+ sections.push(`\u2500\u2500 Plan: ${planDone}/${planTotal} \u2500\u2500`);
235
+ const statusIcon = {
236
+ completed: "\u2705",
237
+ in_progress: "\u{1F504}",
238
+ pending: "\u2B1C"
239
+ };
240
+ for (let i = 0; i < snap.planEntries.length; i++) {
241
+ const e = snap.planEntries[i];
242
+ const icon = statusIcon[e.status] ?? "\u2B1C";
243
+ sections.push(`${icon} ${i + 1}. ${escapeHtml(e.content)}`);
244
+ }
245
+ sections.push("\u2500\u2500\u2500\u2500");
246
+ }
247
+ for (const entry of running) {
248
+ sections.push(`${entry.icon} ${escapeHtml(entry.label)}`);
249
+ }
250
+ if (snap.usage?.tokensUsed != null) {
251
+ if (sections.length > 0) sections.push("\u2500\u2500\u2500");
252
+ sections.push(formatUsage(snap.usage, snap.verbosity));
253
+ }
254
+ return sections.join("\n");
255
+ }
206
256
 
207
257
  // src/plugins/telegram/commands/admin.ts
208
258
  import { InlineKeyboard } from "grammy";
@@ -3251,6 +3301,117 @@ function redirectToAssistant(chatId, assistantTopicId) {
3251
3301
  return `\u{1F4AC} Please use the <a href="${link}">\u{1F916} Assistant</a> topic to chat with OpenACP.`;
3252
3302
  }
3253
3303
 
3304
+ // src/core/adapter-primitives/primitives/tool-card-state.ts
3305
+ var DEBOUNCE_MS = 500;
3306
+ var ToolCardState = class {
3307
+ entries = [];
3308
+ planEntries;
3309
+ usage;
3310
+ finalized = false;
3311
+ isFirstFlush = true;
3312
+ debounceTimer;
3313
+ verbosity;
3314
+ onFlush;
3315
+ constructor(config) {
3316
+ this.verbosity = config.verbosity;
3317
+ this.onFlush = config.onFlush;
3318
+ }
3319
+ addTool(meta, kind, rawInput) {
3320
+ if (this.finalized) return;
3321
+ const hidden = this.verbosity !== "high" && evaluateNoise(meta.name, kind, rawInput) !== null;
3322
+ const entry = {
3323
+ id: meta.id,
3324
+ name: meta.name,
3325
+ kind,
3326
+ status: meta.status ?? "running",
3327
+ icon: resolveToolIcon({ status: meta.status ?? "running", kind }),
3328
+ label: formatToolSummary(meta.name, rawInput, meta.displaySummary),
3329
+ viewerLinks: meta.viewerLinks,
3330
+ viewerFilePath: meta.viewerFilePath,
3331
+ hidden
3332
+ };
3333
+ this.entries.push(entry);
3334
+ if (this.isFirstFlush) {
3335
+ this.isFirstFlush = false;
3336
+ this.flush();
3337
+ } else {
3338
+ this.scheduleFlush();
3339
+ }
3340
+ }
3341
+ updateTool(id, status, viewerLinks, viewerFilePath) {
3342
+ if (this.finalized) return;
3343
+ const entry = this.entries.find((e) => e.id === id);
3344
+ if (!entry) return;
3345
+ entry.status = status;
3346
+ entry.icon = resolveToolIcon({ status, kind: entry.kind });
3347
+ if (viewerLinks) entry.viewerLinks = viewerLinks;
3348
+ if (viewerFilePath) entry.viewerFilePath = viewerFilePath;
3349
+ this.scheduleFlush();
3350
+ }
3351
+ updatePlan(entries) {
3352
+ if (this.finalized) return;
3353
+ this.planEntries = entries;
3354
+ if (this.entries.length === 0 && this.isFirstFlush) {
3355
+ this.isFirstFlush = false;
3356
+ this.flush();
3357
+ } else {
3358
+ this.scheduleFlush();
3359
+ }
3360
+ }
3361
+ appendUsage(usage) {
3362
+ if (this.finalized) return;
3363
+ this.usage = usage;
3364
+ this.flush();
3365
+ }
3366
+ finalize() {
3367
+ if (this.finalized) return;
3368
+ this.finalized = true;
3369
+ this.clearDebounce();
3370
+ this.flush();
3371
+ }
3372
+ destroy() {
3373
+ this.finalized = true;
3374
+ this.clearDebounce();
3375
+ }
3376
+ hasContent() {
3377
+ return this.entries.length > 0 || this.planEntries !== void 0;
3378
+ }
3379
+ snapshot() {
3380
+ const visible = this.entries.filter((e) => !e.hidden);
3381
+ const completedVisible = visible.filter(
3382
+ (e) => e.status === "completed" || e.status === "done"
3383
+ ).length;
3384
+ const allComplete = visible.length > 0 && completedVisible === visible.length;
3385
+ return {
3386
+ entries: this.entries,
3387
+ planEntries: this.planEntries,
3388
+ usage: this.usage,
3389
+ visibleCount: visible.length,
3390
+ totalVisible: visible.length,
3391
+ completedVisible,
3392
+ allComplete,
3393
+ verbosity: this.verbosity
3394
+ };
3395
+ }
3396
+ flush() {
3397
+ this.clearDebounce();
3398
+ this.onFlush(this.snapshot());
3399
+ }
3400
+ scheduleFlush() {
3401
+ this.clearDebounce();
3402
+ this.debounceTimer = setTimeout(() => {
3403
+ this.debounceTimer = void 0;
3404
+ this.flush();
3405
+ }, DEBOUNCE_MS);
3406
+ }
3407
+ clearDebounce() {
3408
+ if (this.debounceTimer) {
3409
+ clearTimeout(this.debounceTimer);
3410
+ this.debounceTimer = void 0;
3411
+ }
3412
+ }
3413
+ };
3414
+
3254
3415
  // src/plugins/telegram/activity.ts
3255
3416
  var log10 = createChildLogger({ module: "telegram:activity" });
3256
3417
  var THINKING_REFRESH_MS = 15e3;
@@ -3308,20 +3469,14 @@ var ThinkingIndicator = class {
3308
3469
  }
3309
3470
  const elapsed = Math.round((Date.now() - this.showTime) / 1e3);
3310
3471
  this.sendQueue.enqueue(() => {
3311
- if (this.dismissed) return Promise.resolve(void 0);
3312
- return this.api.sendMessage(
3472
+ if (this.dismissed || !this.msgId) return Promise.resolve(void 0);
3473
+ return this.api.editMessageText(
3313
3474
  this.chatId,
3475
+ this.msgId,
3314
3476
  `\u{1F4AD} <i>Still thinking... (${elapsed}s)</i>`,
3315
- {
3316
- message_thread_id: this.threadId,
3317
- parse_mode: "HTML",
3318
- disable_notification: true
3319
- }
3477
+ { parse_mode: "HTML" }
3320
3478
  );
3321
- }).then((result) => {
3322
- if (result && !this.dismissed) {
3323
- this.msgId = result.message_id;
3324
- }
3479
+ }).then(() => {
3325
3480
  }).catch(() => {
3326
3481
  });
3327
3482
  }, THINKING_REFRESH_MS);
@@ -3333,123 +3488,52 @@ var ThinkingIndicator = class {
3333
3488
  }
3334
3489
  }
3335
3490
  };
3336
- var UsageMessage = class {
3337
- constructor(api, chatId, threadId, sendQueue) {
3491
+ var ToolCard = class {
3492
+ constructor(api, chatId, threadId, sendQueue, verbosity) {
3338
3493
  this.api = api;
3339
3494
  this.chatId = chatId;
3340
3495
  this.threadId = threadId;
3341
3496
  this.sendQueue = sendQueue;
3342
- }
3343
- msgId;
3344
- async send(usage, verbosity = "medium") {
3345
- const text = formatUsage(usage, verbosity);
3346
- try {
3347
- if (this.msgId) {
3348
- await this.sendQueue.enqueue(
3349
- () => this.api.editMessageText(this.chatId, this.msgId, text, {
3350
- parse_mode: "HTML"
3351
- })
3352
- );
3353
- } else {
3354
- const result = await this.sendQueue.enqueue(
3355
- () => this.api.sendMessage(this.chatId, text, {
3356
- message_thread_id: this.threadId,
3357
- parse_mode: "HTML",
3358
- disable_notification: true
3359
- })
3360
- );
3361
- if (result) this.msgId = result.message_id;
3497
+ this.state = new ToolCardState({
3498
+ verbosity,
3499
+ onFlush: (snapshot) => {
3500
+ this.flushPromise = this.flushPromise.then(() => this._sendOrEdit(snapshot)).catch(() => {
3501
+ });
3362
3502
  }
3363
- } catch (err) {
3364
- log10.warn({ err }, "UsageMessage.send() failed");
3365
- }
3366
- }
3367
- getMsgId() {
3368
- return this.msgId;
3369
- }
3370
- async delete() {
3371
- if (!this.msgId) return;
3372
- const id = this.msgId;
3373
- this.msgId = void 0;
3374
- try {
3375
- await this.sendQueue.enqueue(
3376
- () => this.api.deleteMessage(this.chatId, id)
3377
- );
3378
- } catch (err) {
3379
- log10.warn({ err }, "UsageMessage.delete() failed");
3380
- }
3381
- }
3382
- };
3383
- function formatPlanCard(entries, verbosity = "medium") {
3384
- if (verbosity === "medium") {
3385
- const done2 = entries.filter((e) => e.status === "completed").length;
3386
- return `\u{1F4CB} <b>Plan:</b> ${done2}/${entries.length} steps completed`;
3387
- }
3388
- const statusIcon = {
3389
- completed: "\u2705",
3390
- in_progress: "\u{1F504}",
3391
- pending: "\u2B1C",
3392
- failed: "\u274C"
3393
- };
3394
- const total = entries.length;
3395
- const done = entries.filter((e) => e.status === "completed").length;
3396
- const ratio = total > 0 ? done / total : 0;
3397
- const filled = Math.round(ratio * 10);
3398
- const bar = "\u2593".repeat(filled) + "\u2591".repeat(10 - filled);
3399
- const pct = Math.round(ratio * 100);
3400
- const header = `\u{1F4CB} <b>Plan</b>
3401
- ${bar} ${pct}% \xB7 ${done}/${total}`;
3402
- const lines = entries.map((e, i) => {
3403
- const icon = statusIcon[e.status] ?? "\u2B1C";
3404
- return `${icon} ${i + 1}. ${e.content}`;
3405
- });
3406
- return [header, ...lines].join("\n");
3407
- }
3408
- var PlanCard = class {
3409
- constructor(api, chatId, threadId, sendQueue) {
3410
- this.api = api;
3411
- this.chatId = chatId;
3412
- this.threadId = threadId;
3413
- this.sendQueue = sendQueue;
3503
+ });
3414
3504
  }
3505
+ state;
3415
3506
  msgId;
3416
- flushPromise = Promise.resolve();
3417
- latestEntries;
3418
3507
  lastSentText;
3419
- flushTimer;
3420
- verbosity = "medium";
3421
- setVerbosity(v) {
3422
- this.verbosity = v;
3508
+ flushPromise = Promise.resolve();
3509
+ addTool(meta, kind, rawInput) {
3510
+ this.state.addTool(meta, kind, rawInput);
3423
3511
  }
3424
- update(entries) {
3425
- this.latestEntries = entries;
3426
- if (this.flushTimer) clearTimeout(this.flushTimer);
3427
- this.flushTimer = setTimeout(() => {
3428
- this.flushTimer = void 0;
3429
- this.flushPromise = this.flushPromise.then(() => this._flush()).catch(() => {
3430
- });
3431
- }, 3500);
3512
+ updateTool(id, status, viewerLinks, viewerFilePath) {
3513
+ this.state.updateTool(id, status, viewerLinks, viewerFilePath);
3514
+ }
3515
+ updatePlan(entries) {
3516
+ this.state.updatePlan(entries);
3517
+ }
3518
+ appendUsage(usage) {
3519
+ this.state.appendUsage(usage);
3432
3520
  }
3433
3521
  async finalize() {
3434
- if (!this.latestEntries) return;
3435
- if (this.flushTimer) {
3436
- clearTimeout(this.flushTimer);
3437
- this.flushTimer = void 0;
3438
- }
3439
- await this.flushPromise;
3440
- this.flushPromise = this.flushPromise.then(() => this._flush()).catch(() => {
3441
- });
3522
+ this.state.finalize();
3442
3523
  await this.flushPromise;
3443
3524
  }
3444
3525
  destroy() {
3445
- if (this.flushTimer) {
3446
- clearTimeout(this.flushTimer);
3447
- this.flushTimer = void 0;
3448
- }
3526
+ this.state.destroy();
3449
3527
  }
3450
- async _flush() {
3451
- if (!this.latestEntries) return;
3452
- const text = formatPlanCard(this.latestEntries, this.verbosity);
3528
+ hasContent() {
3529
+ return this.state.hasContent();
3530
+ }
3531
+ getMsgId() {
3532
+ return this.msgId;
3533
+ }
3534
+ async _sendOrEdit(snapshot) {
3535
+ const text = renderToolCard(snapshot);
3536
+ if (!text) return;
3453
3537
  if (this.msgId && text === this.lastSentText) return;
3454
3538
  this.lastSentText = text;
3455
3539
  try {
@@ -3470,82 +3554,63 @@ var PlanCard = class {
3470
3554
  if (result) this.msgId = result.message_id;
3471
3555
  }
3472
3556
  } catch (err) {
3473
- log10.warn({ err }, "PlanCard flush failed");
3557
+ log10.warn({ err }, "[ToolCard] send/edit failed");
3474
3558
  }
3475
3559
  }
3476
3560
  };
3477
3561
  var ActivityTracker = class {
3478
- constructor(api, chatId, threadId, sendQueue) {
3562
+ constructor(api, chatId, threadId, sendQueue, verbosity = "medium") {
3479
3563
  this.api = api;
3480
3564
  this.chatId = chatId;
3481
3565
  this.threadId = threadId;
3482
3566
  this.sendQueue = sendQueue;
3483
3567
  this.thinking = new ThinkingIndicator(api, chatId, threadId, sendQueue);
3484
- this.planCard = new PlanCard(api, chatId, threadId, sendQueue);
3485
- this.usage = new UsageMessage(api, chatId, threadId, sendQueue);
3568
+ this.toolCard = new ToolCard(api, chatId, threadId, sendQueue, verbosity);
3486
3569
  }
3487
3570
  isFirstEvent = true;
3488
- hasPlanCard = false;
3489
3571
  thinking;
3490
- planCard;
3491
- usage;
3572
+ toolCard;
3492
3573
  async onNewPrompt() {
3493
3574
  this.isFirstEvent = true;
3494
- this.hasPlanCard = false;
3495
3575
  this.thinking.dismiss();
3496
3576
  this.thinking.reset();
3497
3577
  }
3498
3578
  async onThought() {
3499
- await this._firstEventGuard();
3579
+ this.isFirstEvent = false;
3500
3580
  await this.thinking.show();
3501
3581
  }
3502
- async onPlan(entries, verbosity) {
3503
- await this._firstEventGuard();
3582
+ async onTextStart() {
3583
+ this.isFirstEvent = false;
3504
3584
  this.thinking.dismiss();
3505
- this.hasPlanCard = true;
3506
- if (verbosity) this.planCard.setVerbosity(verbosity);
3507
- this.planCard.update(entries);
3508
3585
  }
3509
- async onToolCall() {
3510
- await this._firstEventGuard();
3586
+ async onToolCall(meta, kind, rawInput) {
3587
+ this.isFirstEvent = false;
3511
3588
  this.thinking.dismiss();
3512
3589
  this.thinking.reset();
3590
+ this.toolCard.addTool(meta, kind, rawInput);
3513
3591
  }
3514
- async onTextStart() {
3515
- await this._firstEventGuard();
3592
+ async onToolUpdate(id, status, viewerLinks, viewerFilePath) {
3593
+ this.toolCard.updateTool(id, status, viewerLinks, viewerFilePath);
3594
+ }
3595
+ async onPlan(entries) {
3596
+ this.isFirstEvent = false;
3516
3597
  this.thinking.dismiss();
3598
+ this.toolCard.updatePlan(entries);
3517
3599
  }
3518
- async sendUsage(data, verbosity = "medium") {
3519
- await this.usage.send(data, verbosity);
3600
+ async sendUsage(usage) {
3601
+ this.toolCard.appendUsage(usage);
3520
3602
  }
3521
3603
  getUsageMsgId() {
3522
- return this.usage.getMsgId();
3604
+ return this.toolCard.getMsgId();
3523
3605
  }
3524
- async onComplete() {
3525
- if (this.hasPlanCard) {
3526
- await this.planCard.finalize();
3527
- } else {
3528
- try {
3529
- await this.sendQueue.enqueue(
3530
- () => this.api.sendMessage(this.chatId, "\u2705 <b>Done</b>", {
3531
- message_thread_id: this.threadId,
3532
- parse_mode: "HTML",
3533
- disable_notification: true
3534
- })
3535
- );
3536
- } catch (err) {
3537
- log10.warn({ err }, "ActivityTracker.onComplete() Done send failed");
3538
- }
3539
- }
3606
+ async cleanup() {
3607
+ this.thinking.dismiss();
3608
+ await this.toolCard.finalize();
3609
+ this.toolCard.destroy();
3540
3610
  }
3541
3611
  destroy() {
3542
3612
  this.thinking.dismiss();
3543
- this.planCard.destroy();
3544
- }
3545
- async _firstEventGuard() {
3546
- if (!this.isFirstEvent) return;
3547
- this.isFirstEvent = false;
3548
- await this.usage.delete();
3613
+ this.toolCard.destroy();
3549
3614
  }
3550
3615
  };
3551
3616
 
@@ -3804,143 +3869,6 @@ function setupActionCallbacks(bot, core, chatId, getAssistantSessionId) {
3804
3869
  });
3805
3870
  }
3806
3871
 
3807
- // src/core/adapter-primitives/primitives/tool-call-tracker.ts
3808
- var ToolCallTracker = class {
3809
- sessions = /* @__PURE__ */ new Map();
3810
- track(sessionId, meta, messageId) {
3811
- if (!this.sessions.has(sessionId)) {
3812
- this.sessions.set(sessionId, /* @__PURE__ */ new Map());
3813
- }
3814
- this.sessions.get(sessionId).set(meta.id, { ...meta, messageId });
3815
- }
3816
- update(sessionId, toolId, status, patch) {
3817
- const tool = this.sessions.get(sessionId)?.get(toolId);
3818
- if (!tool) return null;
3819
- tool.status = status;
3820
- if (patch?.viewerLinks) tool.viewerLinks = patch.viewerLinks;
3821
- if (patch?.viewerFilePath) tool.viewerFilePath = patch.viewerFilePath;
3822
- if (patch?.name) tool.name = patch.name;
3823
- if (patch?.kind) tool.kind = patch.kind;
3824
- return tool;
3825
- }
3826
- getActive(sessionId) {
3827
- const session = this.sessions.get(sessionId);
3828
- return session ? [...session.values()] : [];
3829
- }
3830
- clear(sessionId) {
3831
- this.sessions.delete(sessionId);
3832
- }
3833
- clearAll() {
3834
- this.sessions.clear();
3835
- }
3836
- };
3837
-
3838
- // src/plugins/telegram/tool-call-tracker.ts
3839
- var log11 = createChildLogger({ module: "tool-call-tracker" });
3840
- var TelegramToolCallTracker = class {
3841
- constructor(bot, chatId, sendQueue) {
3842
- this.bot = bot;
3843
- this.chatId = chatId;
3844
- this.sendQueue = sendQueue;
3845
- }
3846
- tracker = new ToolCallTracker();
3847
- /** Platform-specific ready-promise per tool call, keyed by `${sessionId}:${toolId}`. */
3848
- readyMap = /* @__PURE__ */ new Map();
3849
- async trackNewCall(sessionId, threadId, meta, verbosity = "medium") {
3850
- let resolveReady;
3851
- const ready = new Promise((r) => {
3852
- resolveReady = r;
3853
- });
3854
- const key = `${sessionId}:${meta.id}`;
3855
- this.readyMap.set(key, { ready });
3856
- this.tracker.track(sessionId, meta, "0");
3857
- try {
3858
- const msg = await this.sendQueue.enqueue(
3859
- () => this.bot.api.sendMessage(this.chatId, formatToolCall(meta, verbosity), {
3860
- message_thread_id: threadId,
3861
- parse_mode: "HTML",
3862
- disable_notification: true
3863
- })
3864
- );
3865
- const tracked = this.tracker.update(sessionId, meta.id, meta.status ?? "running");
3866
- if (tracked) {
3867
- tracked.messageId = String(msg.message_id);
3868
- }
3869
- } finally {
3870
- resolveReady();
3871
- }
3872
- }
3873
- async updateCall(sessionId, meta, verbosity = "medium") {
3874
- const key = `${sessionId}:${meta.id}`;
3875
- const readyState = this.readyMap.get(key);
3876
- const tracked = this.tracker.update(sessionId, meta.id, meta.status, {
3877
- viewerLinks: meta.viewerLinks,
3878
- viewerFilePath: meta.viewerFilePath,
3879
- name: meta.name,
3880
- kind: meta.kind
3881
- });
3882
- if (!tracked) return;
3883
- const isTerminal = meta.status === "completed" || meta.status === "failed";
3884
- if (!isTerminal) return;
3885
- if (readyState) {
3886
- await readyState.ready;
3887
- }
3888
- const msgId = Number(tracked.messageId);
3889
- log11.debug(
3890
- {
3891
- toolId: meta.id,
3892
- status: meta.status,
3893
- hasViewerLinks: !!tracked.viewerLinks,
3894
- viewerLinks: tracked.viewerLinks,
3895
- name: tracked.name,
3896
- msgId
3897
- },
3898
- "Tool completed, preparing edit"
3899
- );
3900
- const merged = {
3901
- id: meta.id,
3902
- name: tracked.name,
3903
- kind: tracked.kind,
3904
- rawInput: tracked.rawInput,
3905
- viewerLinks: tracked.viewerLinks,
3906
- viewerFilePath: tracked.viewerFilePath,
3907
- displaySummary: tracked.displaySummary,
3908
- displayTitle: tracked.displayTitle,
3909
- displayKind: tracked.displayKind,
3910
- status: meta.status,
3911
- content: meta.content
3912
- };
3913
- const formattedText = formatToolUpdate(merged, verbosity);
3914
- try {
3915
- await this.sendQueue.enqueue(
3916
- () => this.bot.api.editMessageText(
3917
- this.chatId,
3918
- msgId,
3919
- formattedText,
3920
- { parse_mode: "HTML" }
3921
- )
3922
- );
3923
- } catch (err) {
3924
- log11.warn(
3925
- {
3926
- err,
3927
- msgId,
3928
- textLen: formattedText.length,
3929
- hasViewerLinks: !!merged.viewerLinks
3930
- },
3931
- "Tool update edit failed"
3932
- );
3933
- }
3934
- }
3935
- cleanup(sessionId) {
3936
- const active = this.tracker.getActive(sessionId);
3937
- for (const tool of active) {
3938
- this.readyMap.delete(`${sessionId}:${tool.id}`);
3939
- }
3940
- this.tracker.clear(sessionId);
3941
- }
3942
- };
3943
-
3944
3872
  // src/plugins/telegram/streaming.ts
3945
3873
  var FLUSH_INTERVAL = 5e3;
3946
3874
  var MessageDraft = class {
@@ -4196,7 +4124,7 @@ var DraftManager = class {
4196
4124
  };
4197
4125
 
4198
4126
  // src/plugins/telegram/skill-command-manager.ts
4199
- var log12 = createChildLogger({ module: "skill-commands" });
4127
+ var log11 = createChildLogger({ module: "skill-commands" });
4200
4128
  var SkillCommandManager = class {
4201
4129
  // sessionId → pinned msgId
4202
4130
  constructor(bot, chatId, sendQueue, sessionManager) {
@@ -4262,7 +4190,7 @@ var SkillCommandManager = class {
4262
4190
  disable_notification: true
4263
4191
  });
4264
4192
  } catch (err) {
4265
- log12.error({ err, sessionId }, "Failed to send skill commands");
4193
+ log11.error({ err, sessionId }, "Failed to send skill commands");
4266
4194
  }
4267
4195
  }
4268
4196
  async cleanup(sessionId) {
@@ -4294,22 +4222,34 @@ var SkillCommandManager = class {
4294
4222
  var TelegramRenderer = class extends BaseRenderer {
4295
4223
  renderToolCall(content, verbosity) {
4296
4224
  const meta = content.metadata ?? {};
4297
- return { body: formatToolCall(meta, verbosity), format: "html" };
4225
+ return {
4226
+ body: formatToolCall(meta, verbosity),
4227
+ format: "html"
4228
+ };
4298
4229
  }
4299
4230
  renderToolUpdate(content, verbosity) {
4300
4231
  const meta = content.metadata ?? {};
4301
- return { body: formatToolUpdate(meta, verbosity), format: "html" };
4232
+ return {
4233
+ body: formatToolUpdate(meta, verbosity),
4234
+ format: "html"
4235
+ };
4302
4236
  }
4303
- renderPlan(content, verbosity) {
4237
+ renderPlan(content) {
4304
4238
  const meta = content.metadata;
4305
- return { body: formatPlan({ entries: meta?.entries ?? [] }, verbosity), format: "html" };
4239
+ return {
4240
+ body: formatPlan({ entries: meta?.entries ?? [] }),
4241
+ format: "html"
4242
+ };
4306
4243
  }
4307
4244
  renderUsage(content, verbosity) {
4308
4245
  const meta = content.metadata;
4309
4246
  return { body: formatUsage(meta ?? {}, verbosity), format: "html" };
4310
4247
  }
4311
4248
  renderError(content) {
4312
- return { body: `\u274C <b>Error:</b> ${escapeHtml(content.text)}`, format: "html" };
4249
+ return {
4250
+ body: `\u274C <b>Error:</b> ${escapeHtml(content.text)}`,
4251
+ format: "html"
4252
+ };
4313
4253
  }
4314
4254
  renderNotification(notification) {
4315
4255
  const emoji = {
@@ -4329,19 +4269,25 @@ var TelegramRenderer = class extends BaseRenderer {
4329
4269
  }
4330
4270
  renderModeChange(content) {
4331
4271
  const modeId = content.metadata?.modeId ?? "";
4332
- return { body: `\u{1F504} <b>Mode:</b> ${escapeHtml(String(modeId))}`, format: "html" };
4272
+ return {
4273
+ body: `\u{1F504} <b>Mode:</b> ${escapeHtml(String(modeId))}`,
4274
+ format: "html"
4275
+ };
4333
4276
  }
4334
4277
  renderConfigUpdate() {
4335
4278
  return { body: "\u2699\uFE0F <b>Config updated</b>", format: "html" };
4336
4279
  }
4337
4280
  renderModelUpdate(content) {
4338
4281
  const modelId = content.metadata?.modelId ?? "";
4339
- return { body: `\u{1F916} <b>Model:</b> ${escapeHtml(String(modelId))}`, format: "html" };
4282
+ return {
4283
+ body: `\u{1F916} <b>Model:</b> ${escapeHtml(String(modelId))}`,
4284
+ format: "html"
4285
+ };
4340
4286
  }
4341
4287
  };
4342
4288
 
4343
4289
  // src/plugins/telegram/adapter.ts
4344
- var log13 = createChildLogger({ module: "telegram" });
4290
+ var log12 = createChildLogger({ module: "telegram" });
4345
4291
  function patchedFetch(input, init) {
4346
4292
  if (init?.signal && !(init.signal instanceof AbortSignal)) {
4347
4293
  const nativeController = new AbortController();
@@ -4377,7 +4323,6 @@ var TelegramAdapter = class extends MessagingAdapter {
4377
4323
  sendQueue = new SendQueue({ minInterval: 3e3 });
4378
4324
  _sessionThreadIds = /* @__PURE__ */ new Map();
4379
4325
  // Extracted managers
4380
- toolTracker;
4381
4326
  draftManager;
4382
4327
  skillManager;
4383
4328
  fileService;
@@ -4391,24 +4336,26 @@ var TelegramAdapter = class extends MessagingAdapter {
4391
4336
  }
4392
4337
  return threadId;
4393
4338
  }
4394
- getOrCreateTracker(sessionId, threadId) {
4339
+ getOrCreateTracker(sessionId, threadId, verbosity = "medium") {
4395
4340
  let tracker = this.sessionTrackers.get(sessionId);
4396
4341
  if (!tracker) {
4397
4342
  tracker = new ActivityTracker(
4398
4343
  this.bot.api,
4399
4344
  this.telegramConfig.chatId,
4400
4345
  threadId,
4401
- this.sendQueue
4346
+ this.sendQueue,
4347
+ verbosity
4402
4348
  );
4403
4349
  this.sessionTrackers.set(sessionId, tracker);
4404
4350
  }
4405
4351
  return tracker;
4406
4352
  }
4407
4353
  constructor(core, config) {
4408
- super(
4409
- { configManager: core.configManager },
4410
- { ...config, maxMessageLength: 4096, enabled: config.enabled ?? true }
4411
- );
4354
+ super({ configManager: core.configManager }, {
4355
+ ...config,
4356
+ maxMessageLength: 4096,
4357
+ enabled: config.enabled ?? true
4358
+ });
4412
4359
  this.core = core;
4413
4360
  this.telegramConfig = config;
4414
4361
  }
@@ -4420,11 +4367,6 @@ var TelegramAdapter = class extends MessagingAdapter {
4420
4367
  }
4421
4368
  });
4422
4369
  this.fileService = this.core.fileService;
4423
- this.toolTracker = new TelegramToolCallTracker(
4424
- this.bot,
4425
- this.telegramConfig.chatId,
4426
- this.sendQueue
4427
- );
4428
4370
  this.draftManager = new DraftManager(
4429
4371
  this.bot,
4430
4372
  this.telegramConfig.chatId,
@@ -4438,7 +4380,7 @@ var TelegramAdapter = class extends MessagingAdapter {
4438
4380
  );
4439
4381
  this.bot.catch((err) => {
4440
4382
  const rootCause = err.error instanceof Error ? err.error : err;
4441
- log13.error({ err: rootCause }, "Telegram bot error");
4383
+ log12.error({ err: rootCause }, "Telegram bot error");
4442
4384
  });
4443
4385
  this.bot.api.config.use(async (prev, method, payload, signal) => {
4444
4386
  const maxRetries = 3;
@@ -4456,7 +4398,7 @@ var TelegramAdapter = class extends MessagingAdapter {
4456
4398
  if (rateLimitedMethods.includes(method)) {
4457
4399
  this.sendQueue.onRateLimited();
4458
4400
  }
4459
- log13.warn(
4401
+ log12.warn(
4460
4402
  { method, retryAfter, attempt: attempt + 1 },
4461
4403
  "Rate limited by Telegram, retrying"
4462
4404
  );
@@ -4503,7 +4445,9 @@ var TelegramAdapter = class extends MessagingAdapter {
4503
4445
  this.bot.on("message:text", async (ctx, next) => {
4504
4446
  const text = ctx.message?.text;
4505
4447
  if (!text?.startsWith("/")) return next();
4506
- const registry = this.core.lifecycleManager?.serviceRegistry?.get("command-registry");
4448
+ const registry = this.core.lifecycleManager?.serviceRegistry?.get(
4449
+ "command-registry"
4450
+ );
4507
4451
  if (!registry) return next();
4508
4452
  const rawCommand = text.split(" ")[0].slice(1);
4509
4453
  const atIdx = rawCommand.indexOf("@");
@@ -4516,7 +4460,10 @@ var TelegramAdapter = class extends MessagingAdapter {
4516
4460
  const chatId = ctx.chat.id;
4517
4461
  const topicId = ctx.message.message_thread_id;
4518
4462
  try {
4519
- const sessionId = topicId != null ? this.core.sessionManager.getSessionByThread("telegram", String(topicId))?.id ?? null : null;
4463
+ const sessionId = topicId != null ? this.core.sessionManager.getSessionByThread(
4464
+ "telegram",
4465
+ String(topicId)
4466
+ )?.id ?? null : null;
4520
4467
  const response = await registry.execute(text, {
4521
4468
  raw: "",
4522
4469
  sessionId,
@@ -4526,7 +4473,11 @@ var TelegramAdapter = class extends MessagingAdapter {
4526
4473
  if (typeof content === "string") {
4527
4474
  await ctx.reply(content);
4528
4475
  } else if (typeof content === "object" && content !== null && "type" in content) {
4529
- await this.renderCommandResponse(content, chatId, topicId);
4476
+ await this.renderCommandResponse(
4477
+ content,
4478
+ chatId,
4479
+ topicId
4480
+ );
4530
4481
  }
4531
4482
  }
4532
4483
  });
@@ -4541,12 +4492,17 @@ var TelegramAdapter = class extends MessagingAdapter {
4541
4492
  this.bot.callbackQuery(/^c\//, async (ctx) => {
4542
4493
  const data = ctx.callbackQuery.data;
4543
4494
  const command = this.fromCallbackData(data);
4544
- const registry = this.core.lifecycleManager?.serviceRegistry?.get("command-registry");
4495
+ const registry = this.core.lifecycleManager?.serviceRegistry?.get(
4496
+ "command-registry"
4497
+ );
4545
4498
  if (!registry) return;
4546
4499
  const chatId = ctx.chat.id;
4547
4500
  const topicId = ctx.callbackQuery.message?.message_thread_id;
4548
4501
  try {
4549
- const sessionId = topicId != null ? this.core.sessionManager.getSessionByThread("telegram", String(topicId))?.id ?? null : null;
4502
+ const sessionId = topicId != null ? this.core.sessionManager.getSessionByThread(
4503
+ "telegram",
4504
+ String(topicId)
4505
+ )?.id ?? null : null;
4550
4506
  const response = await registry.execute(command, {
4551
4507
  raw: "",
4552
4508
  sessionId,
@@ -4666,7 +4622,7 @@ var TelegramAdapter = class extends MessagingAdapter {
4666
4622
  this.setupRoutes();
4667
4623
  this.bot.start({
4668
4624
  allowed_updates: ["message", "callback_query"],
4669
- onStart: () => log13.info(
4625
+ onStart: () => log12.info(
4670
4626
  { chatId: this.telegramConfig.chatId },
4671
4627
  "Telegram bot started"
4672
4628
  )
@@ -4690,10 +4646,10 @@ var TelegramAdapter = class extends MessagingAdapter {
4690
4646
  reply_markup: buildMenuKeyboard()
4691
4647
  });
4692
4648
  } catch (err) {
4693
- log13.warn({ err }, "Failed to send welcome message");
4649
+ log12.warn({ err }, "Failed to send welcome message");
4694
4650
  }
4695
4651
  try {
4696
- log13.info("Spawning assistant session...");
4652
+ log12.info("Spawning assistant session...");
4697
4653
  const { session, ready } = await spawnAssistant(
4698
4654
  this.core,
4699
4655
  this,
@@ -4701,19 +4657,19 @@ var TelegramAdapter = class extends MessagingAdapter {
4701
4657
  );
4702
4658
  this.assistantSession = session;
4703
4659
  this.assistantInitializing = true;
4704
- log13.info(
4660
+ log12.info(
4705
4661
  { sessionId: session.id },
4706
4662
  "Assistant session ready, system prompt running in background"
4707
4663
  );
4708
4664
  ready.then(() => {
4709
4665
  this.assistantInitializing = false;
4710
- log13.info(
4666
+ log12.info(
4711
4667
  { sessionId: session.id },
4712
4668
  "Assistant ready for user messages"
4713
4669
  );
4714
4670
  });
4715
4671
  } catch (err) {
4716
- log13.error({ err }, "Failed to spawn assistant");
4672
+ log12.error({ err }, "Failed to spawn assistant");
4717
4673
  this.bot.api.sendMessage(
4718
4674
  this.telegramConfig.chatId,
4719
4675
  `\u26A0\uFE0F <b>Failed to start assistant session.</b>
@@ -4729,7 +4685,7 @@ var TelegramAdapter = class extends MessagingAdapter {
4729
4685
  await this.assistantSession.destroy();
4730
4686
  }
4731
4687
  await this.bot.stop();
4732
- log13.info("Telegram bot stopped");
4688
+ log12.info("Telegram bot stopped");
4733
4689
  }
4734
4690
  // --- CommandRegistry response rendering ---
4735
4691
  async renderCommandResponse(response, chatId, topicId) {
@@ -4857,7 +4813,7 @@ ${lines.join("\n")}`;
4857
4813
  ctx.replyWithChatAction("typing").catch(() => {
4858
4814
  });
4859
4815
  handleAssistantMessage(this.assistantSession, forwardText).catch(
4860
- (err) => log13.error({ err }, "Assistant error")
4816
+ (err) => log12.error({ err }, "Assistant error")
4861
4817
  );
4862
4818
  return;
4863
4819
  }
@@ -4878,7 +4834,7 @@ ${lines.join("\n")}`;
4878
4834
  threadId: String(threadId),
4879
4835
  userId: String(ctx.from.id),
4880
4836
  text: forwardText
4881
- }).catch((err) => log13.error({ err }, "handleMessage error"));
4837
+ }).catch((err) => log12.error({ err }, "handleMessage error"));
4882
4838
  });
4883
4839
  this.bot.on("message:photo", async (ctx) => {
4884
4840
  const threadId = ctx.message.message_thread_id;
@@ -4957,7 +4913,7 @@ ${lines.join("\n")}`;
4957
4913
  if (session.archiving) return;
4958
4914
  const threadId = Number(session.threadId);
4959
4915
  if (!threadId || isNaN(threadId)) {
4960
- log13.warn(
4916
+ log12.warn(
4961
4917
  { sessionId, threadId: session.threadId },
4962
4918
  "Session has no valid threadId, skipping message"
4963
4919
  );
@@ -4989,15 +4945,9 @@ ${lines.join("\n")}`;
4989
4945
  async handleToolCall(sessionId, content, verbosity) {
4990
4946
  const threadId = this.getThreadId(sessionId);
4991
4947
  const meta = content.metadata ?? {};
4992
- const tracker = this.getOrCreateTracker(sessionId, threadId);
4993
- await tracker.onToolCall();
4994
- await this.draftManager.finalize(
4995
- sessionId,
4996
- this.assistantSession?.id
4997
- );
4998
- await this.toolTracker.trackNewCall(
4999
- sessionId,
5000
- threadId,
4948
+ const tracker = this.getOrCreateTracker(sessionId, threadId, verbosity);
4949
+ await this.draftManager.finalize(sessionId, this.assistantSession?.id);
4950
+ await tracker.onToolCall(
5001
4951
  {
5002
4952
  id: meta.id ?? "",
5003
4953
  name: meta.name ?? content.text ?? "Tool",
@@ -5011,52 +4961,40 @@ ${lines.join("\n")}`;
5011
4961
  displayTitle: meta.displayTitle,
5012
4962
  displayKind: meta.displayKind
5013
4963
  },
5014
- verbosity
4964
+ String(meta.kind ?? ""),
4965
+ meta.rawInput
5015
4966
  );
5016
4967
  }
5017
4968
  async handleToolUpdate(sessionId, content, verbosity) {
4969
+ const threadId = this.getThreadId(sessionId);
5018
4970
  const meta = content.metadata ?? {};
5019
- await this.toolTracker.updateCall(
5020
- sessionId,
5021
- {
5022
- id: meta.id ?? "",
5023
- name: meta.name ?? content.text ?? "",
5024
- kind: meta.kind,
5025
- status: meta.status ?? "completed",
5026
- content: meta.content,
5027
- rawInput: meta.rawInput,
5028
- viewerLinks: meta.viewerLinks,
5029
- viewerFilePath: meta.viewerFilePath,
5030
- displaySummary: meta.displaySummary,
5031
- displayTitle: meta.displayTitle,
5032
- displayKind: meta.displayKind
5033
- },
5034
- verbosity
4971
+ const tracker = this.getOrCreateTracker(sessionId, threadId, verbosity);
4972
+ await tracker.onToolUpdate(
4973
+ meta.id ?? "",
4974
+ meta.status ?? "completed",
4975
+ meta.viewerLinks,
4976
+ meta.viewerFilePath
5035
4977
  );
5036
4978
  }
5037
4979
  async handlePlan(sessionId, content, verbosity) {
5038
4980
  const threadId = this.getThreadId(sessionId);
5039
4981
  const meta = content.metadata ?? {};
5040
4982
  const entries = meta.entries ?? [];
5041
- const tracker = this.getOrCreateTracker(sessionId, threadId);
4983
+ const tracker = this.getOrCreateTracker(sessionId, threadId, verbosity);
5042
4984
  await tracker.onPlan(
5043
4985
  entries.map((e) => ({
5044
4986
  content: e.content,
5045
4987
  status: e.status,
5046
4988
  priority: e.priority ?? "medium"
5047
- })),
5048
- verbosity
4989
+ }))
5049
4990
  );
5050
4991
  }
5051
4992
  async handleUsage(sessionId, content, verbosity) {
5052
4993
  const threadId = this.getThreadId(sessionId);
5053
4994
  const meta = content.metadata;
5054
- await this.draftManager.finalize(
5055
- sessionId,
5056
- this.assistantSession?.id
5057
- );
5058
- const tracker = this.getOrCreateTracker(sessionId, threadId);
5059
- await tracker.sendUsage(meta ?? {}, verbosity);
4995
+ await this.draftManager.finalize(sessionId, this.assistantSession?.id);
4996
+ const tracker = this.getOrCreateTracker(sessionId, threadId, verbosity);
4997
+ await tracker.sendUsage(meta ?? {});
5060
4998
  if (this.notificationTopicId && sessionId !== this.assistantSession?.id) {
5061
4999
  const sess = this.core.sessionManager.getSession(sessionId);
5062
5000
  const sessionName = sess?.name || "Session";
@@ -5083,7 +5021,7 @@ Task completed.
5083
5021
  if (!content.attachment) return;
5084
5022
  const { attachment } = content;
5085
5023
  if (attachment.size > 50 * 1024 * 1024) {
5086
- log13.warn(
5024
+ log12.warn(
5087
5025
  {
5088
5026
  sessionId,
5089
5027
  fileName: attachment.fileName,
@@ -5127,7 +5065,7 @@ Task completed.
5127
5065
  );
5128
5066
  }
5129
5067
  } catch (err) {
5130
- log13.error(
5068
+ log12.error(
5131
5069
  { err, sessionId, fileName: attachment.fileName },
5132
5070
  "Failed to send attachment"
5133
5071
  );
@@ -5135,38 +5073,26 @@ Task completed.
5135
5073
  }
5136
5074
  async handleSessionEnd(sessionId, _content) {
5137
5075
  const threadId = this.getThreadId(sessionId);
5138
- await this.draftManager.finalize(
5139
- sessionId,
5140
- this.assistantSession?.id
5141
- );
5076
+ await this.draftManager.finalize(sessionId, this.assistantSession?.id);
5142
5077
  this.draftManager.cleanup(sessionId);
5143
- this.toolTracker.cleanup(sessionId);
5144
5078
  await this.skillManager.cleanup(sessionId);
5145
5079
  const tracker = this.sessionTrackers.get(sessionId);
5146
5080
  if (tracker) {
5147
- await tracker.onComplete();
5148
- tracker.destroy();
5081
+ await tracker.cleanup();
5149
5082
  this.sessionTrackers.delete(sessionId);
5150
5083
  } else {
5151
5084
  await this.sendQueue.enqueue(
5152
- () => this.bot.api.sendMessage(
5153
- this.telegramConfig.chatId,
5154
- `\u2705 <b>Done</b>`,
5155
- {
5156
- message_thread_id: threadId,
5157
- parse_mode: "HTML",
5158
- disable_notification: true
5159
- }
5160
- )
5085
+ () => this.bot.api.sendMessage(this.telegramConfig.chatId, `\u2705 <b>Done</b>`, {
5086
+ message_thread_id: threadId,
5087
+ parse_mode: "HTML",
5088
+ disable_notification: true
5089
+ })
5161
5090
  );
5162
5091
  }
5163
5092
  }
5164
5093
  async handleError(sessionId, content) {
5165
5094
  const threadId = this.getThreadId(sessionId);
5166
- await this.draftManager.finalize(
5167
- sessionId,
5168
- this.assistantSession?.id
5169
- );
5095
+ await this.draftManager.finalize(sessionId, this.assistantSession?.id);
5170
5096
  const tracker = this.sessionTrackers.get(sessionId);
5171
5097
  if (tracker) {
5172
5098
  tracker.destroy();
@@ -5199,7 +5125,7 @@ Task completed.
5199
5125
  );
5200
5126
  }
5201
5127
  async sendPermissionRequest(sessionId, request) {
5202
- log13.info({ sessionId, requestId: request.id }, "Permission request sent");
5128
+ log12.info({ sessionId, requestId: request.id }, "Permission request sent");
5203
5129
  const session = this.core.sessionManager.getSession(sessionId);
5204
5130
  if (!session) return;
5205
5131
  await this.sendQueue.enqueue(
@@ -5208,7 +5134,7 @@ Task completed.
5208
5134
  }
5209
5135
  async sendNotification(notification) {
5210
5136
  if (notification.sessionId === this.assistantSession?.id) return;
5211
- log13.info(
5137
+ log12.info(
5212
5138
  { sessionId: notification.sessionId, type: notification.type },
5213
5139
  "Notification sent"
5214
5140
  );
@@ -5246,7 +5172,7 @@ Task completed.
5246
5172
  );
5247
5173
  }
5248
5174
  async createSessionThread(sessionId, name) {
5249
- log13.info({ sessionId, name }, "Session topic created");
5175
+ log12.info({ sessionId, name }, "Session topic created");
5250
5176
  return String(
5251
5177
  await createSessionTopic(this.bot, this.telegramConfig.chatId, name)
5252
5178
  );
@@ -5270,7 +5196,7 @@ Task completed.
5270
5196
  try {
5271
5197
  await this.bot.api.deleteForumTopic(this.telegramConfig.chatId, topicId);
5272
5198
  } catch (err) {
5273
- log13.warn(
5199
+ log12.warn(
5274
5200
  { err, sessionId, topicId },
5275
5201
  "Failed to delete forum topic (may already be deleted)"
5276
5202
  );
@@ -5300,7 +5226,7 @@ Task completed.
5300
5226
  const buffer = Buffer.from(await response.arrayBuffer());
5301
5227
  return { buffer, filePath: file.file_path };
5302
5228
  } catch (err) {
5303
- log13.error({ err }, "Failed to download file from Telegram");
5229
+ log12.error({ err }, "Failed to download file from Telegram");
5304
5230
  return null;
5305
5231
  }
5306
5232
  }
@@ -5321,7 +5247,7 @@ Task completed.
5321
5247
  try {
5322
5248
  buffer = await this.fileService.convertOggToWav(buffer);
5323
5249
  } catch (err) {
5324
- log13.warn({ err }, "OGG\u2192WAV conversion failed, saving original OGG");
5250
+ log12.warn({ err }, "OGG\u2192WAV conversion failed, saving original OGG");
5325
5251
  fileName = "voice.ogg";
5326
5252
  mimeType = "audio/ogg";
5327
5253
  originalFilePath = void 0;
@@ -5352,7 +5278,7 @@ Task completed.
5352
5278
  userId: String(userId),
5353
5279
  text,
5354
5280
  attachments: [att]
5355
- }).catch((err) => log13.error({ err }, "handleMessage error"));
5281
+ }).catch((err) => log12.error({ err }, "handleMessage error"));
5356
5282
  }
5357
5283
  async cleanupSkillCommands(sessionId) {
5358
5284
  await this.skillManager.cleanup(sessionId);
@@ -5366,7 +5292,6 @@ Task completed.
5366
5292
  session.archiving = true;
5367
5293
  await this.draftManager.finalize(session.id, this.assistantSession?.id);
5368
5294
  this.draftManager.cleanup(session.id);
5369
- this.toolTracker.cleanup(session.id);
5370
5295
  await this.skillManager.cleanup(session.id);
5371
5296
  const tracker = this.sessionTrackers.get(session.id);
5372
5297
  if (tracker) {
@@ -5380,7 +5305,6 @@ Task completed.
5380
5305
  export {
5381
5306
  PRODUCT_GUIDE,
5382
5307
  SendQueue,
5383
- ToolCallTracker,
5384
5308
  TelegramAdapter
5385
5309
  };
5386
- //# sourceMappingURL=chunk-LP45RCA4.js.map
5310
+ //# sourceMappingURL=chunk-XWDW3XBE.js.map