blun-king-cli 9.1.341 → 9.1.343

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.
@@ -7,6 +7,12 @@ const {
7
7
  const DEFAULT_MAX_CHARS = 3_000;
8
8
  const DEFAULT_MAX_SECTIONS = 5;
9
9
  const RECENT_USER_MESSAGES = 4;
10
+ const NON_ACTIONABLE_USER_ORIGINS = new Set([
11
+ 'background_task',
12
+ 'compaction_summary',
13
+ 'injection',
14
+ 'skill_activation',
15
+ ]);
10
16
  const STOP_WORDS = new Set([
11
17
  'aber', 'alle', 'alles', 'auch', 'eine', 'einem', 'einen', 'einer', 'eines',
12
18
  'fuer', 'haben', 'hier', 'immer', 'jetzt', 'kann', 'machen', 'mehr', 'mich',
@@ -35,10 +41,16 @@ function textFromMessage(message) {
35
41
  .join('\n');
36
42
  }
37
43
 
44
+ function isActionableMistakeInput(message) {
45
+ if (message?.role !== 'user') return false;
46
+ const originKind = String(message?.origin?.kind || '').trim();
47
+ return !NON_ACTIONABLE_USER_ORIGINS.has(originKind);
48
+ }
49
+
38
50
  function recentUserText(history, limit = RECENT_USER_MESSAGES) {
39
51
  if (!Array.isArray(history)) return '';
40
52
  return history
41
- .filter((message) => message?.role === 'user')
53
+ .filter(isActionableMistakeInput)
42
54
  .map(textFromMessage)
43
55
  .filter(Boolean)
44
56
  .slice(-Math.max(1, Number(limit) || RECENT_USER_MESSAGES))
@@ -47,7 +59,7 @@ function recentUserText(history, limit = RECENT_USER_MESSAGES) {
47
59
 
48
60
  function isLowInformationMistakeTurn(history) {
49
61
  if (!Array.isArray(history)) return false;
50
- const message = history.findLast((entry) => entry?.role === 'user');
62
+ const message = history.findLast(isActionableMistakeInput);
51
63
  if (message === undefined) return false;
52
64
  if (typeof message.content === 'string') {
53
65
  return isLowInformationPersonalMemoryQuery(message.content);
@@ -8,6 +8,8 @@ const DEFAULT_SILENCE_MS = 60_000;
8
8
  const RESUME_APPROVAL = /^(?:ja|yes|weiter|mach(?:e)? weiter|du kannst weiter(?:machen)?|bitte weiter|fortsetzen|resume|go)(?:[\s.!?,].*)?$/iu;
9
9
  const CONVERSATION_CLOSE = /^(?:danke(?: dir)?|dankesch(?:oe|\u00f6)n|alles klar|ok(?:ay)?|passt|das war(?:'s| es| alles)|mehr nicht|fertig)(?:[\s.!?,].*)?$/iu;
10
10
  const EXPLICIT_PAUSE = /^(?:(?:bitte\s+)?(?:pause|pausier(?:e)?|stop|stopp|warte|halt(?:e)?\s+an|nicht\s+weiter(?:machen)?))(?:[\s.!?,].*)?$/iu;
11
+ const DIRECT_TELEGRAM_CHANNEL = /<channel\b(?=[^>]*\bsource=["']telegram["'])(?=[^>]*\bpriority=["']direct["'])[^>]*>/iu;
12
+ const TELEGRAM_REPLY_TOOL = /^mcp__[^\s]*telegram[^\s]*__reply$/iu;
11
13
 
12
14
  function isPrivateTelegramChat(chatId) {
13
15
  return /^[1-9]\d*$/u.test(String(chatId ?? '').trim());
@@ -53,6 +55,20 @@ function isExplicitPauseRequest(text) {
53
55
  return EXPLICIT_PAUSE.test(String(text ?? '').trim());
54
56
  }
55
57
 
58
+ function createDirectReplyTurnStop(inputText) {
59
+ const direct = DIRECT_TELEGRAM_CHANNEL.test(String(inputText ?? ''));
60
+ let delivered = false;
61
+ return {
62
+ noteToolResult(toolName, isError) {
63
+ if (direct && isError !== true && TELEGRAM_REPLY_TOOL.test(String(toolName ?? ''))) {
64
+ delivered = true;
65
+ }
66
+ return delivered;
67
+ },
68
+ shouldStop: () => delivered,
69
+ };
70
+ }
71
+
56
72
  function createDirectFocusController(options = {}) {
57
73
  const setTimer = options.setTimer ?? setTimeout;
58
74
  const clearTimer = options.clearTimer ?? clearTimeout;
@@ -213,6 +229,7 @@ function readDirectFocusCheckpoint(env = process.env) {
213
229
  module.exports = {
214
230
  DEFAULT_SILENCE_MS,
215
231
  createDirectFocusController,
232
+ createDirectReplyTurnStop,
216
233
  directFocusCheckpointPath,
217
234
  enqueueTelegramDirect,
218
235
  isConversationClose,
package/blun.mjs CHANGED
@@ -262140,6 +262140,7 @@ var init_turn = __esmMin((() => {
262140
262140
  async runStepLoop(turnId, signal, input, origin) {
262141
262141
  let stopHookContinuationUsed = false;
262142
262142
  let goalOutcomeMessageContinuationUsed = false;
262143
+ const directReplyTurnStop = createDirectReplyTurnStop(blunExtractText(input));
262143
262144
  const deduper = new ToolCallDeduplicator({ telemetry: this.agent.telemetry });
262144
262145
  if (blunTurnNeedsInitialMcp(input, origin)) await this.agent.mcp?.waitForInitialLoad(signal);
262145
262146
  const personalMemoryRecall = await this.agent.injection.injectPersonalMemoryForTurn(turnId, input, origin, signal);
@@ -262275,7 +262276,7 @@ var init_turn = __esmMin((() => {
262275
262276
  await this.agent.fullCompaction.afterStep(signal);
262276
262277
  if (compactConversationTool !== void 0 && this.agent.fullCompaction.isProactiveCompactionEligible() && !selectedTools.includes(compactConversationTool)) selectedTools.push(compactConversationTool);
262277
262278
  deduper.endStep();
262278
- return stopForGoalBudget ? { stopTurn: true } : void 0;
262279
+ return stopForGoalBudget || directReplyTurnStop.shouldStop() ? { stopTurn: true } : void 0;
262279
262280
  },
262280
262281
  shouldContinueAfterStop: async (ctx) => {
262281
262282
  const { signal } = ctx;
@@ -262343,6 +262344,7 @@ var init_turn = __esmMin((() => {
262343
262344
  const { isError, output } = finalResult;
262344
262345
  currentStepHadTool = true;
262345
262346
  if (isError === true) currentStepHadFailure = true;
262347
+ directReplyTurnStop.noteToolResult(ctx.toolCall.name, isError);
262346
262348
  const event = isError === true ? "PostToolUseFailure" : "PostToolUse";
262347
262349
  this.agent.hooks?.fireAndForgetTrigger(event, {
262348
262350
  matcherValue: ctx.toolCall.name,
@@ -419037,7 +419039,7 @@ registerUiCatalogFragment({
419037
419039
  */
419038
419040
  var { projectUnaddressedTelegramContext } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs");
419039
419041
  var { enqueueTelegramUrgent, rewriteTelegramUrgentEnvelope, telegramUrgentMessage } = createRequire(import.meta.url)("./bin/telegram-urgent-policy.cjs");
419040
- var { createDirectFocusController, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
419042
+ var { createDirectFocusController, createDirectReplyTurnStop, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
419041
419043
  var { removeQueuedReloadCommands, removeQueuedSlashCommands } = createRequire(import.meta.url)("./bin/reload-queue-policy.cjs");
419042
419044
  const MAX_BUFFERED_CONTEXT_MESSAGES = 20;
419043
419045
  const MAX_BUFFERED_CONTEXT_CHARS = 24e3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.341",
3
+ "version": "9.1.343",
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": {