blun-king-cli 9.1.192 → 9.1.194

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.
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const LONG_DUPLICATE_MIN_CHARS = 512;
4
+ const TELEGRAM_DELIVERY_LEDGER_LIMIT = 2_048;
4
5
 
5
6
  function userMessageText(message) {
6
7
  if (
@@ -31,6 +32,43 @@ function telegramDeliveryIdentity(text) {
31
32
  return `${chatId}:${messageId}`;
32
33
  }
33
34
 
35
+ function telegramDeliveryIdentityFromParts(input) {
36
+ if (!Array.isArray(input)) return '';
37
+ for (const part of input) {
38
+ if (part?.type !== 'text' || typeof part.text !== 'string') continue;
39
+ const identity = telegramDeliveryIdentity(part.text);
40
+ if (identity) return identity;
41
+ }
42
+ return '';
43
+ }
44
+
45
+ class TelegramDeliveryLedger {
46
+ constructor(limit = TELEGRAM_DELIVERY_LEDGER_LIMIT) {
47
+ this.limit = Math.max(1, Number.isInteger(limit) ? limit : TELEGRAM_DELIVERY_LEDGER_LIMIT);
48
+ this.identities = new Set();
49
+ }
50
+
51
+ identity(input, origin) {
52
+ if (origin?.kind !== 'user') return '';
53
+ return telegramDeliveryIdentityFromParts(input);
54
+ }
55
+
56
+ isDuplicate(input, origin) {
57
+ const identity = this.identity(input, origin);
58
+ return identity ? this.identities.has(identity) : false;
59
+ }
60
+
61
+ remember(input, origin) {
62
+ const identity = this.identity(input, origin);
63
+ if (!identity || this.identities.has(identity)) return identity;
64
+ this.identities.add(identity);
65
+ while (this.identities.size > this.limit) {
66
+ this.identities.delete(this.identities.values().next().value);
67
+ }
68
+ return identity;
69
+ }
70
+ }
71
+
34
72
  function repeatedUserMessageKey(message) {
35
73
  const text = userMessageText(message);
36
74
  if (!text) return '';
@@ -62,7 +100,10 @@ function dedupeRepeatedUserMessages(messages) {
62
100
 
63
101
  module.exports = {
64
102
  LONG_DUPLICATE_MIN_CHARS,
103
+ TELEGRAM_DELIVERY_LEDGER_LIMIT,
104
+ TelegramDeliveryLedger,
65
105
  dedupeRepeatedUserMessages,
66
106
  telegramDeliveryIdentity,
107
+ telegramDeliveryIdentityFromParts,
67
108
  userMessageText,
68
109
  };
package/blun.mjs CHANGED
@@ -234922,7 +234922,7 @@ function restoreAgentRecord(agent, input) {
234922
234922
  agent.goal.restoreForked(input);
234923
234923
  return;
234924
234924
  case "turn.prompt":
234925
- agent.turn.restorePrompt();
234925
+ agent.turn.restorePrompt(input.input, input.origin);
234926
234926
  return;
234927
234927
  case "turn.steer":
234928
234928
  agent.turn.restoreSteer(input.input, input.origin);
@@ -261209,7 +261209,7 @@ function toolResultText(result) {
261209
261209
  function abandonedToolResultOutput(ended) {
261210
261210
  return `Tool call did not complete: ${ended.reason === "cancelled" ? "the turn was cancelled" : ended.reason === "failed" ? `the turn failed${ended.error !== void 0 ? ` (${ended.error.message})` : ""}` : "the turn ended"} before its result was recorded. Do not assume the tool completed successfully.`;
261211
261211
  }
261212
- var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens, projectRecurringCronHistory, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
261212
+ var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens, projectRecurringCronHistory, TelegramDeliveryLedger, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
261213
261213
  var init_turn = __esmMin((() => {
261214
261214
  init_dist$4();
261215
261215
  init_src$4();
@@ -261228,6 +261228,7 @@ var init_turn = __esmMin((() => {
261228
261228
  init_assistant_message_offload();
261229
261229
  ({ CORE_TOOL_NAMES: BLUN_CORE_TOOL_NAMES, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens } = createRequire(import.meta.url)("./bin/turn-tool-performance-policy.cjs"));
261230
261230
  ({ projectRecurringCronHistory } = createRequire(import.meta.url)("./bin/recurring-cron-history-policy.cjs"));
261231
+ ({ TelegramDeliveryLedger } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
261231
261232
  BLUN_LEAN_TOOL_NAMES = new Set(BLUN_CORE_TOOL_NAMES);
261232
261233
  BLUN_ATTACHMENT_MARKER_RE = /\b(?:attachment_file_id|telegram-anhang|telegram attachment)\b/i;
261233
261234
  BLUN_TELEGRAM_OUTBOUND_TOOL_RE = /^mcp__[^\s]*telegram[^\s]*__(?:reply|react|edit_message)$/i;
@@ -261275,6 +261276,7 @@ var init_turn = __esmMin((() => {
261275
261276
  TurnFlow = class {
261276
261277
  agent;
261277
261278
  loadedToolNames = /* @__PURE__ */ new Set();
261279
+ telegramDeliveryLedger = new TelegramDeliveryLedger();
261278
261280
  steerBuffer = [];
261279
261281
  nextSteerSequence = 0;
261280
261282
  turnId = -1;
@@ -261298,16 +261300,25 @@ var init_turn = __esmMin((() => {
261298
261300
  return this.promptWithAcceptance(input, origin).turnId;
261299
261301
  }
261300
261302
  promptWithAcceptance(input, origin = USER_PROMPT_ORIGIN) {
261301
- this.agent.records.logRecord({
261302
- type: "turn.prompt",
261303
- input,
261304
- origin
261305
- });
261303
+ if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
261304
+ this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "prompt" });
261305
+ return {
261306
+ accepted: true,
261307
+ buffered: false,
261308
+ turnId: null
261309
+ };
261310
+ }
261306
261311
  if (this.activeTurn !== null) return {
261307
261312
  accepted: false,
261308
261313
  buffered: false,
261309
261314
  turnId: null
261310
261315
  };
261316
+ this.telegramDeliveryLedger.remember(input, origin);
261317
+ this.agent.records.logRecord({
261318
+ type: "turn.prompt",
261319
+ input,
261320
+ origin
261321
+ });
261311
261322
  const buffered = this.agent.fullCompaction.isCompacting;
261312
261323
  const turnId = this.launch(input, origin);
261313
261324
  return {
@@ -261317,6 +261328,11 @@ var init_turn = __esmMin((() => {
261317
261328
  };
261318
261329
  }
261319
261330
  steer(input, origin = USER_PROMPT_ORIGIN) {
261331
+ if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
261332
+ this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "steer" });
261333
+ return null;
261334
+ }
261335
+ this.telegramDeliveryLedger.remember(input, origin);
261320
261336
  this.agent.records.logRecord({
261321
261337
  type: "turn.steer",
261322
261338
  input,
@@ -261332,6 +261348,11 @@ var init_turn = __esmMin((() => {
261332
261348
  steerActive(input, expectedTurnId, origin = USER_PROMPT_ORIGIN) {
261333
261349
  const active = this.activeTurn;
261334
261350
  if (active === null || active === "resuming" || !active.acceptingSteers || expectedTurnId !== void 0 && expectedTurnId !== this.currentId) return null;
261351
+ if (this.telegramDeliveryLedger.isDuplicate(input, origin)) {
261352
+ this.agent.telemetry.track("telegram_delivery_duplicate_dropped", { intake: "active_steer" });
261353
+ return this.currentId;
261354
+ }
261355
+ this.telegramDeliveryLedger.remember(input, origin);
261335
261356
  this.agent.records.logRecord({
261336
261357
  type: "turn.steer",
261337
261358
  input,
@@ -261378,7 +261399,8 @@ var init_turn = __esmMin((() => {
261378
261399
  this.turnId += 1;
261379
261400
  return this.turnId;
261380
261401
  }
261381
- restorePrompt() {
261402
+ restorePrompt(input, origin) {
261403
+ this.telegramDeliveryLedger.remember(input, origin);
261382
261404
  if (this.activeTurn) return;
261383
261405
  this.turnId += 1;
261384
261406
  this.activeTurn = "resuming";
@@ -261396,6 +261418,7 @@ var init_turn = __esmMin((() => {
261396
261418
  if (Number.isInteger(turnId) && turnId > this.turnId) this.turnId = turnId;
261397
261419
  }
261398
261420
  restoreSteer(input, origin) {
261421
+ this.telegramDeliveryLedger.remember(input, origin);
261399
261422
  if (this.activeTurn) {
261400
261423
  this.bufferSteer(input, origin);
261401
261424
  return;
@@ -505287,6 +505310,7 @@ registerUiCatalogFragment({
505287
505310
  "sessionEvent.mcp.connecting": "MCP server \"{name}\" connecting…",
505288
505311
  "sessionEvent.skill.activated": "Activated skill: {skillName}",
505289
505312
  "sessionEvent.watchdog.idle": "Turn running for {minutes} min; last tool: {tool}; repeated failures: {repetitions}.",
505313
+ "sessionEvent.watchdog.timeout": "Turn stopped after {minutes} min without progress; last tool: {tool}.",
505290
505314
  "sessionEvent.watchdog.aborted": "Turn stopped after {repetitions} repeated failed calls to {tool}."
505291
505315
  },
505292
505316
  de: {
@@ -505316,6 +505340,7 @@ registerUiCatalogFragment({
505316
505340
  "sessionEvent.mcp.connecting": "MCP-Server „{name}“ wird verbunden…",
505317
505341
  "sessionEvent.skill.activated": "Skill aktiviert: {skillName}",
505318
505342
  "sessionEvent.watchdog.idle": "Zug läuft seit {minutes} Min.; letztes Werkzeug: {tool}; wiederholte Fehler: {repetitions}.",
505343
+ "sessionEvent.watchdog.timeout": "Zug nach {minutes} Min. ohne Fortschritt beendet; letztes Werkzeug: {tool}.",
505319
505344
  "sessionEvent.watchdog.aborted": "Zug nach {repetitions} wiederholten fehlgeschlagenen Aufrufen von {tool} beendet."
505320
505345
  },
505321
505346
  es: {
@@ -505345,6 +505370,7 @@ registerUiCatalogFragment({
505345
505370
  "sessionEvent.mcp.connecting": "Conectando el servidor MCP «{name}»…",
505346
505371
  "sessionEvent.skill.activated": "Skill activado: {skillName}",
505347
505372
  "sessionEvent.watchdog.idle": "El turno lleva {minutes} min en curso; última herramienta: {tool}; fallos repetidos: {repetitions}.",
505373
+ "sessionEvent.watchdog.timeout": "Turno detenido tras {minutes} min sin progreso; última herramienta: {tool}.",
505348
505374
  "sessionEvent.watchdog.aborted": "Turno detenido tras {repetitions} llamadas fallidas repetidas a {tool}."
505349
505375
  },
505350
505376
  fr: {
@@ -505374,6 +505400,7 @@ registerUiCatalogFragment({
505374
505400
  "sessionEvent.mcp.connecting": "Connexion du serveur MCP « {name} »…",
505375
505401
  "sessionEvent.skill.activated": "Skill activé : {skillName}",
505376
505402
  "sessionEvent.watchdog.idle": "Tour en cours depuis {minutes} min ; dernier outil : {tool} ; échecs répétés : {repetitions}.",
505403
+ "sessionEvent.watchdog.timeout": "Tour arrêté après {minutes} min sans progression ; dernier outil : {tool}.",
505377
505404
  "sessionEvent.watchdog.aborted": "Tour arrêté après {repetitions} appels répétés ayant échoué pour l'outil {tool}."
505378
505405
  },
505379
505406
  sv: {
@@ -505403,6 +505430,7 @@ registerUiCatalogFragment({
505403
505430
  "sessionEvent.mcp.connecting": "Ansluter MCP-servern ”{name}”…",
505404
505431
  "sessionEvent.skill.activated": "Skill aktiverad: {skillName}",
505405
505432
  "sessionEvent.watchdog.idle": "Körningen har pågått i {minutes} min. Senaste verktyg: {tool}. Upprepade fel: {repetitions}.",
505433
+ "sessionEvent.watchdog.timeout": "Körningen stoppades efter {minutes} min utan framsteg. Senaste verktyg: {tool}.",
505406
505434
  "sessionEvent.watchdog.aborted": "Körningen stoppades efter {repetitions} upprepade misslyckade anrop till {tool}."
505407
505435
  },
505408
505436
  cs: {
@@ -505432,6 +505460,7 @@ registerUiCatalogFragment({
505432
505460
  "sessionEvent.mcp.connecting": "Server MCP \"{name}\" se připojuje…",
505433
505461
  "sessionEvent.skill.activated": "Aktivována dovednost: {skillName}",
505434
505462
  "sessionEvent.watchdog.idle": "Kolo běží {minutes} min; poslední nástroj: {tool}; opakovaná selhání: {repetitions}.",
505463
+ "sessionEvent.watchdog.timeout": "Kolo bylo zastaveno po {minutes} min bez pokroku; poslední nástroj: {tool}.",
505435
505464
  "sessionEvent.watchdog.aborted": "Kolo bylo zastaveno po {repetitions} opakovaných neúspěšných voláních nástroje {tool}."
505436
505465
  }
505437
505466
  });
@@ -506583,18 +506612,22 @@ function isUserCancelledSubagentError(error) {
506583
506612
  //#endregion
506584
506613
  //#region src/tui/controllers/turn-watchdog.ts
506585
506614
  const DEFAULT_IDLE_MINUTES = 20;
506615
+ const DEFAULT_HARD_IDLE_MINUTES = 30;
506586
506616
  const DEFAULT_MAX_FAILED_REPETITIONS = 5;
506587
506617
  const MIN_IDLE_MINUTES = 1;
506588
506618
  const MAX_IDLE_MINUTES = 1440;
506589
506619
  const MIN_FAILED_REPETITIONS = 2;
506590
506620
  const MAX_FAILED_REPETITIONS = 100;
506591
506621
  const TURN_WATCHDOG_IDLE_MINUTES_ENV = "BLUN_TURN_WATCHDOG_IDLE_MINUTES";
506622
+ const TURN_WATCHDOG_HARD_IDLE_MINUTES_ENV = "BLUN_TURN_WATCHDOG_HARD_IDLE_MINUTES";
506592
506623
  const TURN_WATCHDOG_MAX_FAILED_REPETITIONS_ENV = "BLUN_TURN_WATCHDOG_MAX_FAILED_REPETITIONS";
506593
506624
  function resolveTurnWatchdogConfig(env = process.env) {
506594
506625
  const idleMinutes = parseBoundedInteger(env[TURN_WATCHDOG_IDLE_MINUTES_ENV], DEFAULT_IDLE_MINUTES, MIN_IDLE_MINUTES, MAX_IDLE_MINUTES);
506626
+ const hardIdleMinutes = parseBoundedInteger(env[TURN_WATCHDOG_HARD_IDLE_MINUTES_ENV], DEFAULT_HARD_IDLE_MINUTES, MIN_IDLE_MINUTES, MAX_IDLE_MINUTES);
506595
506627
  const maxFailedRepetitions = parseBoundedInteger(env[TURN_WATCHDOG_MAX_FAILED_REPETITIONS_ENV], DEFAULT_MAX_FAILED_REPETITIONS, MIN_FAILED_REPETITIONS, MAX_FAILED_REPETITIONS);
506596
506628
  return {
506597
506629
  idleMs: idleMinutes * 6e4,
506630
+ hardIdleMs: hardIdleMinutes * 6e4,
506598
506631
  maxFailedRepetitions
506599
506632
  };
506600
506633
  }
@@ -506644,6 +506677,7 @@ var TurnWatchdogController = class {
506644
506677
  }
506645
506678
  recordToolCall(toolCallId, name, args) {
506646
506679
  if (!this.active) return;
506680
+ this.recordProgress();
506647
506681
  this.lastToolName = name;
506648
506682
  this.toolCalls.set(toolCallId, {
506649
506683
  name,
@@ -506655,9 +506689,7 @@ var TurnWatchdogController = class {
506655
506689
  const toolCall = this.toolCalls.get(toolCallId);
506656
506690
  this.toolCalls.delete(toolCallId);
506657
506691
  if (toolCall !== void 0) this.lastToolName = toolCall.name;
506658
- this.lastProgressAtMs = this.now();
506659
- this.idleReportedForProgressAtMs = void 0;
506660
- this.scheduleIdleCheck();
506692
+ this.recordProgress();
506661
506693
  if (!isError || toolCall === void 0) {
506662
506694
  this.lastFailedKey = void 0;
506663
506695
  this.failedRepetitions = 0;
@@ -506669,14 +506701,26 @@ var TurnWatchdogController = class {
506669
506701
  this.failedRepetitions = 1;
506670
506702
  }
506671
506703
  if (this.failedRepetitions < this.config.maxFailedRepetitions) return;
506672
- const snapshot = this.snapshot();
506704
+ const snapshot = {
506705
+ ...this.snapshot(),
506706
+ reason: "repeated_failures"
506707
+ };
506673
506708
  this.stop();
506674
506709
  this.onAbort(snapshot);
506675
506710
  }
506711
+ recordProgress() {
506712
+ if (!this.active) return;
506713
+ this.lastProgressAtMs = this.now();
506714
+ this.idleReportedForProgressAtMs = void 0;
506715
+ this.scheduleIdleCheck();
506716
+ }
506676
506717
  scheduleIdleCheck() {
506677
506718
  if (!this.active) return;
506678
506719
  if (this.timer !== void 0) this.clearTimer(this.timer);
506679
- const remaining = Math.max(0, this.config.idleMs - (this.now() - this.lastProgressAtMs));
506720
+ const idleForMs = this.now() - this.lastProgressAtMs;
506721
+ const warningRemaining = this.idleReportedForProgressAtMs === this.lastProgressAtMs ? Number.POSITIVE_INFINITY : this.config.idleMs - idleForMs;
506722
+ const hardRemaining = this.config.hardIdleMs - idleForMs;
506723
+ const remaining = Math.max(0, Math.min(warningRemaining, hardRemaining));
506680
506724
  this.timer = this.setTimer(() => {
506681
506725
  this.timer = void 0;
506682
506726
  this.checkIdle();
@@ -506684,16 +506728,26 @@ var TurnWatchdogController = class {
506684
506728
  }
506685
506729
  checkIdle() {
506686
506730
  if (!this.active) return;
506687
- if (this.now() - this.lastProgressAtMs >= this.config.idleMs && this.idleReportedForProgressAtMs !== this.lastProgressAtMs) {
506731
+ const idleForMs = this.now() - this.lastProgressAtMs;
506732
+ if (idleForMs >= this.config.hardIdleMs) {
506733
+ const snapshot = {
506734
+ ...this.snapshot(),
506735
+ reason: "idle_timeout"
506736
+ };
506737
+ this.stop();
506738
+ this.onAbort(snapshot);
506739
+ return;
506740
+ }
506741
+ if (idleForMs >= this.config.idleMs && this.idleReportedForProgressAtMs !== this.lastProgressAtMs) {
506688
506742
  this.idleReportedForProgressAtMs = this.lastProgressAtMs;
506689
506743
  this.onIdle(this.snapshot());
506690
- return;
506691
506744
  }
506692
506745
  this.scheduleIdleCheck();
506693
506746
  }
506694
506747
  snapshot() {
506695
506748
  return {
506696
506749
  elapsedMinutes: Math.max(1, Math.floor((this.now() - this.startedAtMs) / 6e4)),
506750
+ idleMinutes: Math.max(1, Math.floor((this.now() - this.lastProgressAtMs) / 6e4)),
506697
506751
  lastToolName: this.lastToolName,
506698
506752
  failedRepetitions: this.failedRepetitions
506699
506753
  };
@@ -507012,6 +507066,7 @@ var SessionEventHandler = class {
507012
507066
  requestRunningUpdateAtSafeBoundary(this.host);
507013
507067
  }
507014
507068
  handleStepBegin(event) {
507069
+ this.turnWatchdog.recordProgress();
507015
507070
  this.host.commitQueuedSteerAtStepStart(event.turnId);
507016
507071
  this.host.streamingUI.flushNow();
507017
507072
  this.host.streamingUI.setStep(event.step);
@@ -507085,6 +507140,7 @@ var SessionEventHandler = class {
507085
507140
  handleThinkingDelta(event) {
507086
507141
  const { state, streamingUI } = this.host;
507087
507142
  if (event.delta.length === 0 && !streamingUI.hasThinkingDraft()) return;
507143
+ if (event.delta.length > 0) this.turnWatchdog.recordProgress();
507088
507144
  streamingUI.appendThinkingDelta(event.delta);
507089
507145
  this.host.patchLivePane({ mode: "idle" });
507090
507146
  if (state.appState.streamingPhase !== "thinking") this.host.setAppState({
@@ -507097,6 +507153,7 @@ var SessionEventHandler = class {
507097
507153
  const { state, streamingUI } = this.host;
507098
507154
  if (streamingUI.hasThinkingDraft()) streamingUI.flushThinkingToTranscript("idle");
507099
507155
  if (event.delta.trim().length > 0) {
507156
+ this.turnWatchdog.recordProgress();
507100
507157
  this.currentTurnHasAssistantText = true;
507101
507158
  this.pendingModelBlockedFallback = void 0;
507102
507159
  }
@@ -507157,6 +507214,7 @@ var SessionEventHandler = class {
507157
507214
  }
507158
507215
  handleToolCallDelta(event) {
507159
507216
  if (event.toolCallId.length === 0) return;
507217
+ if (event.argumentsPart.length > 0) this.turnWatchdog.recordProgress();
507160
507218
  const { state, streamingUI } = this.host;
507161
507219
  streamingUI.accumulateToolCallDelta(event.toolCallId, event.name, event.argumentsPart);
507162
507220
  const preview = streamingUI.getStreamingToolCallPreview(event.toolCallId);
@@ -507173,6 +507231,7 @@ var SessionEventHandler = class {
507173
507231
  streamingUI.scheduleFlush();
507174
507232
  }
507175
507233
  handleToolProgress(event) {
507234
+ this.turnWatchdog.recordProgress();
507176
507235
  if (event.update.kind === "custom" && event.update.customKind === MEDIA_PROGRESS_CUSTOM_KIND) {
507177
507236
  this.host.updateMediaActivity(event.toolCallId, event.update.customData);
507178
507237
  return;
@@ -507228,7 +507287,8 @@ var SessionEventHandler = class {
507228
507287
  this.host.sendChannelTurnStatus?.(message);
507229
507288
  }
507230
507289
  abortWatchdogLoop(snapshot) {
507231
- const message = uiText("sessionEvent.watchdog.aborted", {
507290
+ const message = uiText(snapshot.reason === "idle_timeout" ? "sessionEvent.watchdog.timeout" : "sessionEvent.watchdog.aborted", {
507291
+ minutes: snapshot.idleMinutes,
507232
507292
  tool: snapshot.lastToolName,
507233
507293
  repetitions: snapshot.failedRepetitions
507234
507294
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.192",
3
+ "version": "9.1.194",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {