blun-king-cli 9.1.376 → 9.1.377

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 (2) hide show
  1. package/blun.mjs +72 -3
  2. package/package.json +1 -1
package/blun.mjs CHANGED
@@ -419329,6 +419329,8 @@ const OWNERSHIP_SETTLE_MS = 50;
419329
419329
  const OWNERSHIP_HANDOFF_WARNING_MS = 5e3;
419330
419330
  const BRIDGE_STOP_TIMEOUT_MS = 2500;
419331
419331
  const BRIDGE_FORCE_STOP_TIMEOUT_MS = 500;
419332
+ const CHANNEL_STEER_CONFIRM_TIMEOUT_MS = 15e3;
419333
+ const CHANNEL_DELIVERY_MAX_FAILURES = 3;
419332
419334
  const BLUN_NODE_FALLBACK_SUBCOMMAND = "__plugin_run_node";
419333
419335
  function isBlunNativeBinary(execPath) {
419334
419336
  return !basename(execPath).toLowerCase().startsWith("node");
@@ -517296,9 +517298,16 @@ var BlunTUI = class {
517296
517298
  try {
517297
517299
  const result = await this.harness.withInteractiveAgent(item.agentId ?? "main", () => session.steerActive(input, expectedTurnId === void 0 ? {} : { expectedTurnId }));
517298
517300
  if (!result.accepted) return this.recoverRejectedActiveSteer(inFlight);
517301
+ inFlight.turnId = String(result.turnId);
517299
517302
  inFlight.accepted = true;
517300
517303
  if (result.duplicate === true) return this.commitQueuedSteer(inFlight);
517301
517304
  if (inFlight.turnEnded) return restoreHead();
517305
+ if (!inFlight.stepStarted) {
517306
+ inFlight.confirmationTimer = setTimeout(() => {
517307
+ if (this.queueSteerInFlight === inFlight && inFlight.accepted && !inFlight.stepStarted) restoreHead(new Error("channel steer confirmation timed out"));
517308
+ }, CHANNEL_STEER_CONFIRM_TIMEOUT_MS);
517309
+ inFlight.confirmationTimer.unref?.();
517310
+ }
517302
517311
  this.commitQueuedSteerIfReady(inFlight);
517303
517312
  } catch (error) {
517304
517313
  return restoreHead(error);
@@ -517341,6 +517350,7 @@ var BlunTUI = class {
517341
517350
  }
517342
517351
  commitQueuedSteer(inFlight) {
517343
517352
  if (this.queueSteerInFlight !== inFlight) return;
517353
+ if (inFlight.confirmationTimer !== void 0) clearTimeout(inFlight.confirmationTimer);
517344
517354
  this.queueSteerInFlight = void 0;
517345
517355
  inFlight.onCommit();
517346
517356
  this.updateQueueDisplay();
@@ -517357,11 +517367,64 @@ var BlunTUI = class {
517357
517367
  }
517358
517368
  return restored;
517359
517369
  }
517370
+ quarantineQueuedSteer(inFlight, error) {
517371
+ if (this.queueSteerInFlight !== inFlight) return false;
517372
+ if (inFlight.confirmationTimer !== void 0) clearTimeout(inFlight.confirmationTimer);
517373
+ this.queueSteerInFlight = void 0;
517374
+ inFlight.onRestore?.();
517375
+ const record = {
517376
+ version: 1,
517377
+ quarantinedAt: new Date().toISOString(),
517378
+ reason: String(error?.code ?? error?.name ?? "channel_delivery_failed"),
517379
+ attempts: CHANNEL_DELIVERY_MAX_FAILURES,
517380
+ items: inFlight.items.map((item) => ({
517381
+ text: item.text,
517382
+ displayText: item.displayText,
517383
+ origin: item.origin,
517384
+ mode: item.mode,
517385
+ agentId: item.agentId,
517386
+ chatId: item.channelChatId,
517387
+ queueKey: item.queueKey,
517388
+ contextOnly: item.channelContextOnly === true,
517389
+ attention: item.channelAttention === true,
517390
+ urgent: item.channelUrgent === true,
517391
+ direct: item.channelDirect === true,
517392
+ addressed: item.channelAddressed === true,
517393
+ imagePath: item.channelImagePath
517394
+ }))
517395
+ };
517396
+ try {
517397
+ appendFileSync(join(telegramStateDir(), "inbound-queue-quarantine.jsonl"), `${JSON.stringify(record)}\n`, { encoding: "utf8", mode: 384 });
517398
+ } catch (archiveError) {
517399
+ this.state.queuedMessages = [...inFlight.items.map((item) => ({
517400
+ ...item,
517401
+ channelDeliveryFailures: CHANNEL_DELIVERY_MAX_FAILURES - 1
517402
+ })), ...this.state.queuedMessages];
517403
+ this.showError(uiText("blunTui.steer.failed", { error: formatErrorMessage$2(archiveError) }));
517404
+ this.updateQueueDisplay();
517405
+ this.state.ui.requestRender();
517406
+ this.scheduleQueueDrain();
517407
+ return false;
517408
+ }
517409
+ for (const item of inFlight.items) item.channelAcknowledge?.();
517410
+ if (this.queueFlushBatchRemaining > 0) this.queueFlushBatchRemaining = Math.max(0, this.queueFlushBatchRemaining - inFlight.items.length);
517411
+ this.track("channel_queue_quarantined", { count: inFlight.items.length, attempts: CHANNEL_DELIVERY_MAX_FAILURES });
517412
+ this.updateQueueDisplay();
517413
+ this.state.ui.requestRender();
517414
+ this.scheduleQueueDrain();
517415
+ return false;
517416
+ }
517360
517417
  restoreQueuedSteer(inFlight, error) {
517361
517418
  if (this.queueSteerInFlight !== inFlight) return false;
517419
+ if (inFlight.confirmationTimer !== void 0) clearTimeout(inFlight.confirmationTimer);
517420
+ const failureCount = Math.max(0, ...inFlight.items.map((item) => Number(item.channelDeliveryFailures) || 0)) + 1;
517421
+ if (failureCount >= CHANNEL_DELIVERY_MAX_FAILURES) return this.quarantineQueuedSteer(inFlight, error);
517362
517422
  this.queueSteerInFlight = void 0;
517363
517423
  inFlight.onRestore?.();
517364
- this.state.queuedMessages = [...inFlight.items, ...this.state.queuedMessages];
517424
+ this.state.queuedMessages = [...inFlight.items.map((item) => ({
517425
+ ...item,
517426
+ channelDeliveryFailures: failureCount
517427
+ })), ...this.state.queuedMessages];
517365
517428
  if (error !== void 0) this.showError(uiText("blunTui.steer.failed", { error: formatErrorMessage$2(error) }));
517366
517429
  this.updateQueueDisplay();
517367
517430
  this.state.ui.requestRender();
@@ -517437,7 +517500,7 @@ var BlunTUI = class {
517437
517500
  for (const item of items) this.appendTranscriptEntry({
517438
517501
  id: nextTranscriptId(),
517439
517502
  kind: "user",
517440
- turnId,
517503
+ turnId: inFlight.turnId,
517441
517504
  renderMode: "plain",
517442
517505
  content: item.text.trim()
517443
517506
  });
@@ -517449,6 +517512,7 @@ var BlunTUI = class {
517449
517512
  if (this.queueSteerInFlight !== inFlight) return;
517450
517513
  if (!result.accepted) this.recoverRejectedActiveSteer(inFlight);
517451
517514
  else {
517515
+ inFlight.turnId = String(result.turnId);
517452
517516
  inFlight.accepted = true;
517453
517517
  if (inFlight.turnEnded) this.restoreQueuedSteer(inFlight);
517454
517518
  else this.commitQueuedSteerIfReady(inFlight);
@@ -517635,6 +517699,10 @@ var BlunTUI = class {
517635
517699
  this.state.ui.requestRender();
517636
517700
  return;
517637
517701
  }
517702
+ if (command.name === "loop" && activeTurn && !this.queueCommandRunning) {
517703
+ this.runTelegramRemoteCommand(item);
517704
+ return;
517705
+ }
517638
517706
  const busy = this.session === void 0 || this.state.appState.model.trim().length === 0 || this.state.queuedMessages.length > 0 || this.queueSteerInFlight !== void 0 || this.pendingChannelReplyGuard !== void 0 || this.deferUserMessages || this.streamingUI.hasActiveTurn() || this.state.appState.streamingPhase !== "idle" || this.state.appState.isCompacting;
517639
517707
  if (busy) {
517640
517708
  this.state.queuedMessages.push(item);
@@ -517671,7 +517739,8 @@ var BlunTUI = class {
517671
517739
  if (this.telegramRemoteCommandContext === context) this.telegramRemoteCommandContext = void 0;
517672
517740
  if (!context.sentModelTurn) {
517673
517741
  const response = context.responses.at(-1) ?? item.displayText ?? item.text;
517674
- if (await sendReplyFallback(item.channelChatId, response, false)) item.channelAcknowledge?.();
517742
+ if (!await sendReplyFallback(item.channelChatId, response, false)) this.track("telegram_command_reply_failed", { command: item.telegramCommandName });
517743
+ item.channelAcknowledge?.();
517675
517744
  }
517676
517745
  this.queueCommandRunning = false;
517677
517746
  if (!this.editorReplacementActive) this.preserveQueueAcrossSessionReset = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.376",
3
+ "version": "9.1.377",
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": {