blun-king-cli 9.1.191 → 9.1.193

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.
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ function buildApprovalRejectionStop(output) {
4
+ return {
5
+ syntheticResult: {
6
+ output,
7
+ isError: true,
8
+ stopTurn: true,
9
+ },
10
+ };
11
+ }
12
+
13
+ module.exports = {
14
+ buildApprovalRejectionStop,
15
+ };
@@ -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
@@ -233964,10 +233964,7 @@ var init_permission = __esmMin((() => {
233964
233964
  const resolved = result.resolveApproval?.(response);
233965
233965
  if (resolved !== void 0) return this.permissionPolicyResolutionToPrepare(resolved, context, policyName);
233966
233966
  if (response.decision === "approved") return;
233967
- return {
233968
- block: true,
233969
- reason: this.formatApprovalRejectionMessage(name, response)
233970
- };
233967
+ return buildApprovalRejectionStop(this.formatApprovalRejectionMessage(name, response));
233971
233968
  }
233972
233969
  async evaluatePolicies(context) {
233973
233970
  for (const policy of this.policies) {
@@ -234925,7 +234922,7 @@ function restoreAgentRecord(agent, input) {
234925
234922
  agent.goal.restoreForked(input);
234926
234923
  return;
234927
234924
  case "turn.prompt":
234928
- agent.turn.restorePrompt();
234925
+ agent.turn.restorePrompt(input.input, input.origin);
234929
234926
  return;
234930
234927
  case "turn.steer":
234931
234928
  agent.turn.restoreSteer(input.input, input.origin);
@@ -261212,7 +261209,7 @@ function toolResultText(result) {
261212
261209
  function abandonedToolResultOutput(ended) {
261213
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.`;
261214
261211
  }
261215
- 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;
261216
261213
  var init_turn = __esmMin((() => {
261217
261214
  init_dist$4();
261218
261215
  init_src$4();
@@ -261231,6 +261228,7 @@ var init_turn = __esmMin((() => {
261231
261228
  init_assistant_message_offload();
261232
261229
  ({ CORE_TOOL_NAMES: BLUN_CORE_TOOL_NAMES, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens } = createRequire(import.meta.url)("./bin/turn-tool-performance-policy.cjs"));
261233
261230
  ({ projectRecurringCronHistory } = createRequire(import.meta.url)("./bin/recurring-cron-history-policy.cjs"));
261231
+ ({ TelegramDeliveryLedger } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
261234
261232
  BLUN_LEAN_TOOL_NAMES = new Set(BLUN_CORE_TOOL_NAMES);
261235
261233
  BLUN_ATTACHMENT_MARKER_RE = /\b(?:attachment_file_id|telegram-anhang|telegram attachment)\b/i;
261236
261234
  BLUN_TELEGRAM_OUTBOUND_TOOL_RE = /^mcp__[^\s]*telegram[^\s]*__(?:reply|react|edit_message)$/i;
@@ -261278,6 +261276,7 @@ var init_turn = __esmMin((() => {
261278
261276
  TurnFlow = class {
261279
261277
  agent;
261280
261278
  loadedToolNames = /* @__PURE__ */ new Set();
261279
+ telegramDeliveryLedger = new TelegramDeliveryLedger();
261281
261280
  steerBuffer = [];
261282
261281
  nextSteerSequence = 0;
261283
261282
  turnId = -1;
@@ -261301,16 +261300,25 @@ var init_turn = __esmMin((() => {
261301
261300
  return this.promptWithAcceptance(input, origin).turnId;
261302
261301
  }
261303
261302
  promptWithAcceptance(input, origin = USER_PROMPT_ORIGIN) {
261304
- this.agent.records.logRecord({
261305
- type: "turn.prompt",
261306
- input,
261307
- origin
261308
- });
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
+ }
261309
261311
  if (this.activeTurn !== null) return {
261310
261312
  accepted: false,
261311
261313
  buffered: false,
261312
261314
  turnId: null
261313
261315
  };
261316
+ this.telegramDeliveryLedger.remember(input, origin);
261317
+ this.agent.records.logRecord({
261318
+ type: "turn.prompt",
261319
+ input,
261320
+ origin
261321
+ });
261314
261322
  const buffered = this.agent.fullCompaction.isCompacting;
261315
261323
  const turnId = this.launch(input, origin);
261316
261324
  return {
@@ -261320,6 +261328,11 @@ var init_turn = __esmMin((() => {
261320
261328
  };
261321
261329
  }
261322
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);
261323
261336
  this.agent.records.logRecord({
261324
261337
  type: "turn.steer",
261325
261338
  input,
@@ -261335,6 +261348,11 @@ var init_turn = __esmMin((() => {
261335
261348
  steerActive(input, expectedTurnId, origin = USER_PROMPT_ORIGIN) {
261336
261349
  const active = this.activeTurn;
261337
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);
261338
261356
  this.agent.records.logRecord({
261339
261357
  type: "turn.steer",
261340
261358
  input,
@@ -261381,7 +261399,8 @@ var init_turn = __esmMin((() => {
261381
261399
  this.turnId += 1;
261382
261400
  return this.turnId;
261383
261401
  }
261384
- restorePrompt() {
261402
+ restorePrompt(input, origin) {
261403
+ this.telegramDeliveryLedger.remember(input, origin);
261385
261404
  if (this.activeTurn) return;
261386
261405
  this.turnId += 1;
261387
261406
  this.activeTurn = "resuming";
@@ -261399,6 +261418,7 @@ var init_turn = __esmMin((() => {
261399
261418
  if (Number.isInteger(turnId) && turnId > this.turnId) this.turnId = turnId;
261400
261419
  }
261401
261420
  restoreSteer(input, origin) {
261421
+ this.telegramDeliveryLedger.remember(input, origin);
261402
261422
  if (this.activeTurn) {
261403
261423
  this.bufferSteer(input, origin);
261404
261424
  return;
@@ -416742,6 +416762,7 @@ function buildManagedUsageReportLines(options) {
416742
416762
  const errorStyle = (text) => currentTheme.fg("error", text);
416743
416763
  return buildManagedUsageSection(options.managedUsage, options.managedUsageError, accent, value, muted, errorStyle);
416744
416764
  }
416765
+ var { buildApprovalRejectionStop } = createRequire(import.meta.url)("./bin/approval-rejection-stop.cjs");
416745
416766
  var { reconcileContextBudget } = createRequire(import.meta.url)("./bin/context-budget-ledger.cjs");
416746
416767
  function buildUsageReportLines(options) {
416747
416768
  const accent = (text) => currentTheme.boldFg("primary", text);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.191",
3
+ "version": "9.1.193",
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": {