blun-king-cli 9.1.488 → 9.1.490
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.
- package/CHANGELOG.md +25 -0
- package/LIESMICH.txt +6 -4
- package/README.md +6 -4
- package/bin/launcher-runtime.js +34 -1
- package/bin/repeated-user-message-projection.cjs +6 -0
- package/bin/turn-tool-performance-policy.cjs +1 -0
- package/blun.mjs +94 -7
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 9.1.490 - 2026-08-30
|
|
4
|
+
|
|
5
|
+
- Corrects the packaged release history by recording the unpublished 9.1.487 build and replacing the incomplete 9.1.488 summary with the changes verified from the release commits.
|
|
6
|
+
- Carries forward the TodoList, queue-control, Telegram-delivery, AgentSpine profile bootstrap, and managed RTX image-reading repairs from 9.1.489 without runtime changes.
|
|
7
|
+
|
|
8
|
+
## 9.1.489 - 2026-08-30
|
|
9
|
+
|
|
10
|
+
- Restores the visible TodoList as a core tool and requires active goals to keep it truthful from first action through completion.
|
|
11
|
+
- Makes Ctrl+S release the current queue batch exactly once and Escape release one queued message per press before cancelling an empty-queue run.
|
|
12
|
+
- Defers Telegram acknowledgement until real execution starts, restores unexpectedly cancelled pre-step work, and prevents duplicate queue execution or rendering.
|
|
13
|
+
- Installs and enables the bundled AgentSpine plugin for every existing local BLUN profile, including Fredrik, Werner, and Manfred profiles on the same installation.
|
|
14
|
+
- Routes image understanding through the managed BLUN media service on RTX infrastructure before any optional experimental local reader.
|
|
15
|
+
|
|
16
|
+
## 9.1.488 - 2026-08-30
|
|
17
|
+
|
|
18
|
+
- Published the managed AgentSpine core-plugin bundle prepared in the 9.1.487 build.
|
|
19
|
+
- Advanced returning relationship status, kept telemetry disabled when no endpoint is configured, and preserved the selected reasoning effort across successful tool steps.
|
|
20
|
+
- Cleared duplicate Telegram ghost turns and added regression coverage for Telegram intake, reload queues, session resume, and effort preservation.
|
|
21
|
+
|
|
22
|
+
## 9.1.487 - 2026-08-30 (not published)
|
|
23
|
+
|
|
24
|
+
- Prepared AgentSpine as a managed core plugin in the BLUN King package and installer.
|
|
25
|
+
- This version was never published to npm; 9.1.488 was the next public package after 9.1.486.
|
package/LIESMICH.txt
CHANGED
|
@@ -9,7 +9,7 @@ Installation
|
|
|
9
9
|
------------
|
|
10
10
|
Die geprüfte Version exakt global installieren:
|
|
11
11
|
|
|
12
|
-
npm install -g blun-king-cli@9.1.
|
|
12
|
+
npm install -g blun-king-cli@9.1.490
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -63,12 +63,14 @@ ab, ohne den geschriebenen Entwurf zu löschen. Das gilt auch bei
|
|
|
63
63
|
Autovervollständigung, Geistervorschlägen, Bash-Eingabe und einer offenen
|
|
64
64
|
Mehrzeileneingabe.
|
|
65
65
|
|
|
66
|
-
Version 9.1.
|
|
66
|
+
Version 9.1.490 stellt außerdem die interne Todo-Liste wieder her. Deutsche
|
|
67
67
|
Aufgabenlisten-Befehle wählen wieder TodoList statt der getrennten TaskList für
|
|
68
68
|
Hintergrundprozesse. Lesen, Ersetzen, Aktualisieren und Leeren funktionieren in
|
|
69
69
|
derselben Sitzung; eine vollständig erledigte Liste wird aus der Anzeige
|
|
70
|
-
entfernt.
|
|
71
|
-
|
|
70
|
+
entfernt. AgentSpine wird beim Start in allen vorhandenen lokalen Profilen
|
|
71
|
+
installiert und aktiviert. Bilder laufen vorrangig über den verwalteten
|
|
72
|
+
BLUN-Bildlesedienst auf der RTX-Infrastruktur; ein lokaler experimenteller
|
|
73
|
+
Leser ist nur noch ein Fallback, wenn kein verwalteter Mediadienst existiert.
|
|
72
74
|
|
|
73
75
|
Telegram-Nachrichten, die bei bereits aktivem Kernzug eintreffen, werden ohne
|
|
74
76
|
konkurrierenden Start zurückgewiesen und bleiben an der Spitze der
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Voraussetzung ist Node.js 24.15 oder neuer. Die geprüfte Version wird exakt
|
|
|
9
9
|
installiert:
|
|
10
10
|
|
|
11
11
|
```powershell
|
|
12
|
-
npm install -g blun-king-cli@9.1.
|
|
12
|
+
npm install -g blun-king-cli@9.1.490
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Reproduzierbares Staging und Packen
|
|
@@ -79,12 +79,14 @@ konkurrierenden Start zurückgewiesen und bleiben an der Spitze der
|
|
|
79
79
|
FIFO-Warteschlange. Für diesen normalen Wartestatus erscheint kein
|
|
80
80
|
`turn.agent_busy`-Fehler.
|
|
81
81
|
|
|
82
|
-
Version 9.1.
|
|
82
|
+
Version 9.1.490 stellt außerdem die interne Todo-Liste wieder her. Deutsche
|
|
83
83
|
Aufgabenlisten-Befehle wählen wieder TodoList statt der getrennten TaskList für
|
|
84
84
|
Hintergrundprozesse. Lesen, Ersetzen, Aktualisieren und Leeren funktionieren in
|
|
85
85
|
derselben Sitzung; eine vollständig erledigte Liste wird aus der Anzeige
|
|
86
|
-
entfernt.
|
|
87
|
-
|
|
86
|
+
entfernt. AgentSpine wird beim Start in allen vorhandenen lokalen Profilen
|
|
87
|
+
installiert und aktiviert. Bilder laufen vorrangig über den verwalteten
|
|
88
|
+
BLUN-Bildlesedienst auf der RTX-Infrastruktur; ein lokaler experimenteller
|
|
89
|
+
Leser ist nur noch ein Fallback, wenn kein verwalteter Mediadienst existiert.
|
|
88
90
|
|
|
89
91
|
Ab BLUN King 9.1.416 bleiben alle Ergebnisse des jüngsten Werkzeugaufrufs bis
|
|
90
92
|
zur nächsten Assistentenantwort vollständig im Modellkontext. Das gilt auch für
|
package/bin/launcher-runtime.js
CHANGED
|
@@ -282,6 +282,38 @@ function installAgentSpineForProfile(packageRoot, blunDir) {
|
|
|
282
282
|
installManagedAgentSpinePlugin({ packageRoot, blunDir });
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
function installAgentSpineForExistingProfiles(packageRoot, sharedHome, currentProfileHome) {
|
|
286
|
+
const profileRoot = path.join(sharedHome, 'profile');
|
|
287
|
+
const profileHomes = new Map();
|
|
288
|
+
const addProfileHome = (profileHome) => {
|
|
289
|
+
const resolved = path.resolve(profileHome);
|
|
290
|
+
const key = process.platform === 'win32' ? resolved.toLowerCase() : resolved;
|
|
291
|
+
profileHomes.set(key, resolved);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
addProfileHome(currentProfileHome);
|
|
295
|
+
if (fs.existsSync(profileRoot)) {
|
|
296
|
+
for (const entry of fs.readdirSync(profileRoot, { withFileTypes: true })) {
|
|
297
|
+
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
298
|
+
let profileHome;
|
|
299
|
+
try {
|
|
300
|
+
profileHome = resolveProfilePaths(sharedHome, entry.name).home;
|
|
301
|
+
} catch {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
const stat = fs.lstatSync(profileHome);
|
|
305
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) continue;
|
|
306
|
+
addProfileHome(profileHome);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
for (const profileHome of profileHomes.values()) {
|
|
311
|
+
ensurePrivateDirectory(profileHome);
|
|
312
|
+
installAgentSpineForProfile(packageRoot, profileHome);
|
|
313
|
+
}
|
|
314
|
+
return [...profileHomes.values()];
|
|
315
|
+
}
|
|
316
|
+
|
|
285
317
|
function createManagedNodeEnvironment(binary, env = process.env, platform = process.platform) {
|
|
286
318
|
const pathImpl = platform === 'win32' ? path.win32 : path.posix;
|
|
287
319
|
const separator = platform === 'win32' ? path.win32.delimiter : path.posix.delimiter;
|
|
@@ -511,7 +543,7 @@ async function runLauncher(options = {}) {
|
|
|
511
543
|
});
|
|
512
544
|
seedConfiguredMnemoMcp({ blunDir, env: process.env });
|
|
513
545
|
seedStandardSkills({ packageRoot: PKG, blunDir: privatePaths.sharedHome });
|
|
514
|
-
|
|
546
|
+
installAgentSpineForExistingProfiles(PKG, privatePaths.sharedHome, blunDir);
|
|
515
547
|
if (mode === LAUNCHER_MODES.KING) installTelegramForProfile(PKG, blunDir);
|
|
516
548
|
|
|
517
549
|
const nativeModules = repairConfiguredNativeModules({
|
|
@@ -555,6 +587,7 @@ async function runLauncher(options = {}) {
|
|
|
555
587
|
module.exports = {
|
|
556
588
|
clearStartupUpdateViewport,
|
|
557
589
|
createManagedNodeEnvironment,
|
|
590
|
+
installAgentSpineForExistingProfiles,
|
|
558
591
|
resolveLauncherPrivatePaths,
|
|
559
592
|
runLauncher,
|
|
560
593
|
shouldResumeAfterStartupUpdate,
|
|
@@ -68,6 +68,12 @@ class TelegramDeliveryLedger {
|
|
|
68
68
|
return identity;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
forget(input, origin) {
|
|
72
|
+
const identity = this.identity(input, origin);
|
|
73
|
+
if (!identity) return false;
|
|
74
|
+
return this.identities.delete(identity);
|
|
75
|
+
}
|
|
76
|
+
|
|
71
77
|
snapshot() {
|
|
72
78
|
return [...this.identities];
|
|
73
79
|
}
|
package/blun.mjs
CHANGED
|
@@ -30516,7 +30516,7 @@ var init_input_schema = __esmMin((() => {
|
|
|
30516
30516
|
var todo_list_default;
|
|
30517
30517
|
var init_todo_list$1 = __esmMin((() => {
|
|
30518
30518
|
todo_list_default = "Use this tool to maintain a structured TODO list as you work through a multi-step task. Use it proactively and often when progress tracking helps the current work. This is especially useful in long-running investigations and implementation tasks with several tool calls; in plan mode, write the plan to the plan file rather than tracking it here.\n\n**When to use:**\n- Multi-step tasks that span several tool calls\n- Tracking investigation progress across a large codebase search\n- Planning a sequence of edits before making them\n- After receiving new multi-step instructions, capture the requirements as todos\n- Before starting a tracked task, mark exactly one item as `in_progress`\n- Immediately after finishing a tracked task, record its truthful terminal state; do not batch completions at the end\n\n**When NOT to use:**\n- Single-shot answers that complete in one or two tool calls\n- Trivial requests where tracking adds no clarity\n- Purely conversational or informational replies\n\n**Avoid churn:**\n- Do not re-call this tool when nothing meaningful has changed since the last call — update the list only after real progress.\n- When unsure of the current state, call query mode first (omit `todos`) to check the list before deciding what to update.\n- If no available tool can move any task forward, tell the user where you are stuck instead of repeatedly re-ordering the same todos.\n\n**How to use:**\n- Call with `todos: [...]` to replace the full list. Statuses: pending / in_progress / done / blocked / waiting_approval / aborted.\n- Call with no `todos` argument to retrieve the current list without changing it.\n- Call with `todos: []` to clear the list.\n- Keep titles short and actionable (e.g. \"Read session-control.ts\", \"Add planMode flag to TurnManager\").\n- Update statuses as you make progress.\n- When work is underway, keep exactly one task `in_progress`.\n- Use `done` only when fully accomplished. Use `blocked` with the reason and the action that would unblock it, `waiting_approval` with the prepared result that awaits approval, and `aborted` with the last reached state.\n- Never mark a task `done` if tests are failing, implementation is partial, unresolved errors remain, or required files/dependencies could not be found.\n";
|
|
30519
|
-
todo_list_default = "Maintain
|
|
30519
|
+
todo_list_default = "Maintain the agent's visible BLUN TUI task/TODO list as you work through a multi-step task. This is the Aufgaben/Task/Todo panel shown by the interface, not a file, Cron job, scheduled task, or background-agent list. Use it proactively for investigations and implementation work spanning several tool calls; skip it only for conversation or a genuinely single-shot task. In plan mode, use the plan file instead.\n\nStart multi-step work by replacing the list with the real requirements. Keep exactly one item `in_progress`, update it immediately after real progress, and move the next item to `in_progress` instead of batching status changes at the end. Call with `todos: [...]` to replace the full list. Statuses are `pending`, `in_progress`, `done`, `blocked`, `waiting_approval`, and `aborted`. Omit `todos` to query the current list; use `todos: []` to clear a finished non-goal list.\n\nKeep titles short and actionable. Use `done` only for fully verified work. A `blocked` item names the reason and the action that can unblock it; `waiting_approval` names the prepared result awaiting approval; `aborted` records the last reached state. Before finishing, reconcile every tracked item truthfully. If no available tool can move the work forward, report the blocker to the user instead of churning the list.";
|
|
30520
30520
|
}));
|
|
30521
30521
|
//#endregion
|
|
30522
30522
|
//#region ../../packages/agent-core/src/tools/builtin/state/todo-list.ts
|
|
@@ -261582,7 +261582,7 @@ function blunPendingMediaSystemPrompt(systemPrompt, pendingMediaJobIds) {
|
|
|
261582
261582
|
function blunFastConversationTools(tools, input, pendingMediaJobIds = [], requiredToolNames = /* @__PURE__ */ new Set()) {
|
|
261583
261583
|
const telegramTurn = BLUN_TELEGRAM_CHANNEL_RE.test(blunExtractText(input));
|
|
261584
261584
|
const mediaPending = pendingMediaJobIds.length > 0;
|
|
261585
|
-
return tools.filter((tool) => telegramTurn && BLUN_TELEGRAM_OUTBOUND_TOOL_RE.test(tool.name) || mediaPending && tool.name === "GetMedia" || requiredToolNames.has(tool.name));
|
|
261585
|
+
return tools.filter((tool) => tool.name === "TodoList" || telegramTurn && BLUN_TELEGRAM_OUTBOUND_TOOL_RE.test(tool.name) || mediaPending && tool.name === "GetMedia" || requiredToolNames.has(tool.name));
|
|
261586
261586
|
}
|
|
261587
261587
|
/**
|
|
261588
261588
|
* Keep frequently used native tools resident and expose every other tool by
|
|
@@ -262474,6 +262474,9 @@ var init_turn = __esmMin((() => {
|
|
|
262474
262474
|
this.agent.usage.endTurn();
|
|
262475
262475
|
this.flushCognitiveToolEvidence(turnId, true);
|
|
262476
262476
|
this.recordCognitiveStage("endTurn", { turnId, reason: ended.reason, durationMs: ended.durationMs ?? 0 });
|
|
262477
|
+
if (ended.reason === "cancelled" && (this.currentStepByTurn.get(turnId) ?? 0) === 0) {
|
|
262478
|
+
this.telegramDeliveryLedger.forget(input, origin);
|
|
262479
|
+
}
|
|
262477
262480
|
this.agent.emitEvent(ended);
|
|
262478
262481
|
return ended;
|
|
262479
262482
|
}
|
|
@@ -262856,6 +262859,8 @@ var init_turn = __esmMin((() => {
|
|
|
262856
262859
|
return { continue: false };
|
|
262857
262860
|
},
|
|
262858
262861
|
prepareToolExecution: async (ctx) => {
|
|
262862
|
+
const goalTodoPolicy = enforceGoalTodoPolicy(this.agent, ctx);
|
|
262863
|
+
if (goalTodoPolicy !== void 0) return goalTodoPolicy;
|
|
262859
262864
|
const ideaPolicy = enforceIdeaToolPolicy(this.agent, ctx);
|
|
262860
262865
|
if (ideaPolicy !== void 0) return ideaPolicy;
|
|
262861
262866
|
const cached = deduper.checkSameStep(ctx.toolCall.id, ctx.toolCall.name, ctx.args);
|
|
@@ -263186,6 +263191,7 @@ var init_update_goal = __esmMin((() => {
|
|
|
263186
263191
|
}
|
|
263187
263192
|
if (args.status === "complete") {
|
|
263188
263193
|
const completed = await goal.markComplete({}, "model");
|
|
263194
|
+
if (completed !== null) this.agent.tools.updateStore(TODO_STORE_KEY, []);
|
|
263189
263195
|
if (completed !== null) this.agent.context.appendSystemReminder(buildGoalCompletionSummaryPrompt(completed), {
|
|
263190
263196
|
kind: "system_trigger",
|
|
263191
263197
|
name: GOAL_COMPLETION_REMINDER_NAME
|
|
@@ -265806,6 +265812,7 @@ var init_agent = __esmMin((() => {
|
|
|
265806
265812
|
|
|
265807
265813
|
- Answer the user's current conversational message directly and concisely.
|
|
265808
265814
|
- Use the language of the user's latest conversational message unless the persona or current session specifies a language override.
|
|
265815
|
+
- When the user assigns multi-step work, start and maintain the visible BLUN TodoList before doing the work; update it after real progress and reconcile it before finishing. TodoList is not Cron, a file, or a background-task list.
|
|
265809
265816
|
- Do not claim to have inspected files, run commands, used tools, or checked current external state.
|
|
265810
265817
|
- If the message actually requires work or live information, say that plainly instead of inventing a result.`].filter((block) => block.length > 0).join("\n\n");
|
|
265811
265818
|
}
|
|
@@ -297715,7 +297722,7 @@ var init_session$1 = __esmMin((() => {
|
|
|
297715
297722
|
this.log = this.logHandle?.logger ?? (options.id === void 0 ? log : log.createChild({ sessionId: options.id }));
|
|
297716
297723
|
this.rpc = options.rpc;
|
|
297717
297724
|
this.experimentalFlags = options.experimentalFlags ?? new FlagResolver();
|
|
297718
|
-
this.visionReader = (this.experimentalFlags.enabled("vision_reader") ? createVisionReader(options.config?.services?.visionReader) : void 0)
|
|
297725
|
+
this.visionReader = createManagedMediaVisionReader(options.toolServices?.media) ?? (this.experimentalFlags.enabled("vision_reader") ? createVisionReader(options.config?.services?.visionReader) : void 0);
|
|
297719
297726
|
this.hookEngine = new HookEngine(options.hooks, {
|
|
297720
297727
|
cwd: options.kaos.getcwd(),
|
|
297721
297728
|
sessionId: options.id
|
|
@@ -423194,6 +423201,31 @@ function validInitialIdeaPlan(value) {
|
|
|
423194
423201
|
}
|
|
423195
423202
|
return active === 1;
|
|
423196
423203
|
}
|
|
423204
|
+
function enforceGoalTodoPolicy(agent, context) {
|
|
423205
|
+
if (isIdeaGoal(agent) || agent.goal.getActiveGoal() === null) return;
|
|
423206
|
+
const todos = ideaTodos(agent);
|
|
423207
|
+
if (todos.length === 0) {
|
|
423208
|
+
const firstCall = context.toolCalls[0];
|
|
423209
|
+
if (context.toolCall.id !== firstCall?.id || context.toolCall.name !== "TodoList") return {
|
|
423210
|
+
block: true,
|
|
423211
|
+
reason: "Active multi-step goals require TodoList to be the first tool call. Publish and maintain the visible task list before research or action."
|
|
423212
|
+
};
|
|
423213
|
+
if (!validInitialIdeaPlan(context.args?.todos)) return {
|
|
423214
|
+
block: true,
|
|
423215
|
+
reason: "The first goal TodoList must contain at least one item, exactly one in_progress item, and only pending items otherwise."
|
|
423216
|
+
};
|
|
423217
|
+
return;
|
|
423218
|
+
}
|
|
423219
|
+
if (context.toolCall.name !== "UpdateGoal" || context.args?.status !== "complete" && context.args?.status !== "blocked") return;
|
|
423220
|
+
if (todos.some((todo) => !IDEA_TERMINAL_TODO_STATUSES.includes(todo.status))) return {
|
|
423221
|
+
block: true,
|
|
423222
|
+
reason: "The goal cannot finish while a visible TodoList item has no truthful terminal status. Reconcile the list first."
|
|
423223
|
+
};
|
|
423224
|
+
if (context.args.status === "complete" && todos.some((todo) => todo.status !== "done")) return {
|
|
423225
|
+
block: true,
|
|
423226
|
+
reason: "The goal can complete only when every visible TodoList item is done. Use blocked when an item is blocked, waiting_approval, or aborted."
|
|
423227
|
+
};
|
|
423228
|
+
}
|
|
423197
423229
|
function ideaOutboundChannel(toolName, args) {
|
|
423198
423230
|
if (toolName === "Bash") {
|
|
423199
423231
|
const command = typeof args?.command === "string" ? args.command : "";
|
|
@@ -505490,6 +505522,7 @@ var EditorKeyboardController = class {
|
|
|
505490
505522
|
this.clearPendingUndoEsc();
|
|
505491
505523
|
return;
|
|
505492
505524
|
}
|
|
505525
|
+
host.markCurrentRunCancelledByUser();
|
|
505493
505526
|
this.cancelCurrentStream();
|
|
505494
505527
|
this.clearPendingUndoEsc();
|
|
505495
505528
|
return;
|
|
@@ -505508,6 +505541,7 @@ var EditorKeyboardController = class {
|
|
|
505508
505541
|
this.clearPendingUndoEsc();
|
|
505509
505542
|
return;
|
|
505510
505543
|
}
|
|
505544
|
+
host.markCurrentRunCancelledByUser();
|
|
505511
505545
|
this.cancelCurrentStream();
|
|
505512
505546
|
this.clearPendingUndoEsc();
|
|
505513
505547
|
return;
|
|
@@ -508774,6 +508808,7 @@ var SessionEventHandler = class {
|
|
|
508774
508808
|
this.clearModelRetryHint();
|
|
508775
508809
|
this.turnWatchdog.stop();
|
|
508776
508810
|
this.host.restoreQueuedSteerAtTurnEnd(event.turnId);
|
|
508811
|
+
this.host.settleChannelPromptAtTurnEnd(event.turnId, event.reason);
|
|
508777
508812
|
const sessionId = this.host.session?.id;
|
|
508778
508813
|
if (sessionId !== void 0) finishPersonalMemoryRememberIntentTurn(sessionId, event.turnId);
|
|
508779
508814
|
this.host.streamingUI.flushNow();
|
|
@@ -508800,6 +508835,7 @@ var SessionEventHandler = class {
|
|
|
508800
508835
|
this.turnWatchdog.recordProgress();
|
|
508801
508836
|
this.clearModelRetryHint();
|
|
508802
508837
|
this.host.commitQueuedSteerAtStepStart(event.turnId);
|
|
508838
|
+
this.host.commitChannelPromptAtStepStart(event.turnId);
|
|
508803
508839
|
this.host.streamingUI.flushNow();
|
|
508804
508840
|
this.host.streamingUI.setStep(event.step);
|
|
508805
508841
|
this.host.streamingUI.resetToolUi();
|
|
@@ -509110,6 +509146,7 @@ var SessionEventHandler = class {
|
|
|
509110
509146
|
const { state } = this.host;
|
|
509111
509147
|
if (change.kind === "completion" && event.snapshot !== null) {
|
|
509112
509148
|
this.pendingModelBlockedFallback = void 0;
|
|
509149
|
+
this.host.streamingUI.setTodoList([]);
|
|
509113
509150
|
this.goalCompletionAwaitingClear = true;
|
|
509114
509151
|
this.goalCompletionTurnEnded = false;
|
|
509115
509152
|
this.host.appendTranscriptEntry({
|
|
@@ -517555,7 +517592,7 @@ var BlunTUI = class {
|
|
|
517555
517592
|
sessionId: this.session?.id ?? "",
|
|
517556
517593
|
goal: this.state.appState.goal,
|
|
517557
517594
|
permissionMode: this.state.appState.permissionMode,
|
|
517558
|
-
idle: this.session !== void 0 && !this.isShuttingDown && !this.aborted && !this.queueCommandRunning && this.queueSteerInFlight === void 0 && !this.editorReplacementActive && !this.deferUserMessages && !this.streamingUI.hasActiveTurn() && this.state.appState.streamingPhase === "idle" && !this.state.appState.isCompacting && this.state.queuedMessages.length === 0
|
|
517595
|
+
idle: this.session !== void 0 && !this.isShuttingDown && !this.aborted && !this.queueCommandRunning && this.queueSteerInFlight === void 0 && this.channelPromptInFlight === void 0 && !this.editorReplacementActive && !this.deferUserMessages && !this.streamingUI.hasActiveTurn() && this.state.appState.streamingPhase === "idle" && !this.state.appState.isCompacting && this.state.queuedMessages.length === 0
|
|
517559
517596
|
};
|
|
517560
517597
|
}
|
|
517561
517598
|
syncGoalTimeTrigger() {
|
|
@@ -517894,6 +517931,7 @@ var BlunTUI = class {
|
|
|
517894
517931
|
telegramRemoteCommandContext;
|
|
517895
517932
|
queueFlushBatchRemaining = 0;
|
|
517896
517933
|
queueSteerInFlight;
|
|
517934
|
+
channelPromptInFlight;
|
|
517897
517935
|
editorReplacementActive = false;
|
|
517898
517936
|
editorReplacement;
|
|
517899
517937
|
editorReplacementGeneration = 0;
|
|
@@ -518064,14 +518102,38 @@ var BlunTUI = class {
|
|
|
518064
518102
|
this.state.ui.requestRender();
|
|
518065
518103
|
return true;
|
|
518066
518104
|
}
|
|
518105
|
+
markCurrentRunCancelledByUser() {
|
|
518106
|
+
if (this.channelPromptInFlight !== void 0) this.channelPromptInFlight.userCancelled = true;
|
|
518107
|
+
if (this.queueSteerInFlight !== void 0) this.queueSteerInFlight.userCancelled = true;
|
|
518108
|
+
}
|
|
518067
518109
|
restoreQueuedSteerAtTurnEnd(turnId) {
|
|
518068
518110
|
const turnKey = String(turnId);
|
|
518069
518111
|
const inFlight = this.queueSteerInFlight;
|
|
518070
518112
|
if (inFlight === void 0 || inFlight.turnId !== turnKey) return;
|
|
518071
518113
|
inFlight.turnEnded = true;
|
|
518072
|
-
if (inFlight.stepStarted) this.commitQueuedSteer(inFlight);
|
|
518114
|
+
if (inFlight.stepStarted || inFlight.userCancelled === true) this.commitQueuedSteer(inFlight);
|
|
518073
518115
|
else if (inFlight.accepted) this.restoreQueuedSteer(inFlight);
|
|
518074
518116
|
}
|
|
518117
|
+
commitChannelPromptAtStepStart(turnId) {
|
|
518118
|
+
const inFlight = this.channelPromptInFlight;
|
|
518119
|
+
if (inFlight === void 0 || inFlight.turnId !== String(turnId)) return;
|
|
518120
|
+
this.channelPromptInFlight = void 0;
|
|
518121
|
+
inFlight.acknowledge();
|
|
518122
|
+
}
|
|
518123
|
+
settleChannelPromptAtTurnEnd(turnId, reason) {
|
|
518124
|
+
const inFlight = this.channelPromptInFlight;
|
|
518125
|
+
if (inFlight === void 0 || inFlight.turnId !== String(turnId)) return;
|
|
518126
|
+
this.channelPromptInFlight = void 0;
|
|
518127
|
+
if (reason !== "cancelled" || inFlight.userCancelled === true) {
|
|
518128
|
+
inFlight.acknowledge();
|
|
518129
|
+
return;
|
|
518130
|
+
}
|
|
518131
|
+
inFlight.onRestore?.();
|
|
518132
|
+
this.state.queuedMessages = [inFlight.item, ...this.state.queuedMessages];
|
|
518133
|
+
this.syncChannelQueueDeadline();
|
|
518134
|
+
this.updateQueueDisplay();
|
|
518135
|
+
this.state.ui.requestRender();
|
|
518136
|
+
}
|
|
518075
518137
|
commitQueuedSteerIfReady(inFlight) {
|
|
518076
518138
|
if (this.queueSteerInFlight !== inFlight || !inFlight.accepted || !inFlight.stepStarted || inFlight.turnEnded) return;
|
|
518077
518139
|
this.commitQueuedSteer(inFlight);
|
|
@@ -518181,7 +518243,7 @@ var BlunTUI = class {
|
|
|
518181
518243
|
canDrainQueue() {
|
|
518182
518244
|
const head = this.state.queuedMessages[0];
|
|
518183
518245
|
const directWork = head?.channelDirect === true || head?.channelUrgent === true || head?.mode === "channel-command" && /^[1-9]\d*$/u.test(String(head.channelChatId ?? ""));
|
|
518184
|
-
return !this.isShuttingDown && !this.queueCommandRunning && this.queueSteerInFlight === void 0 && !this.editorReplacementActive && !this.deferUserMessages && !this.streamingUI.hasActiveTurn() && this.state.appState.streamingPhase === "idle" && !this.state.appState.isCompacting && (!this.directFocusController.isPaused() || directWork);
|
|
518246
|
+
return !this.isShuttingDown && !this.queueCommandRunning && this.queueSteerInFlight === void 0 && this.channelPromptInFlight === void 0 && !this.editorReplacementActive && !this.deferUserMessages && !this.streamingUI.hasActiveTurn() && this.state.appState.streamingPhase === "idle" && !this.state.appState.isCompacting && (!this.directFocusController.isPaused() || directWork);
|
|
518185
518247
|
}
|
|
518186
518248
|
scheduleQueueDrain() {
|
|
518187
518249
|
if (this.queueDrainTimer !== void 0 || !this.canDrainQueue()) return;
|
|
@@ -518585,7 +518647,32 @@ var BlunTUI = class {
|
|
|
518585
518647
|
return;
|
|
518586
518648
|
}
|
|
518587
518649
|
if (result.accepted) {
|
|
518588
|
-
acknowledge
|
|
518650
|
+
if (acknowledge !== void 0 && result.turnId !== null && result.turnId !== void 0) {
|
|
518651
|
+
this.channelPromptInFlight = {
|
|
518652
|
+
turnId: String(result.turnId),
|
|
518653
|
+
acknowledge,
|
|
518654
|
+
item: {
|
|
518655
|
+
text: modelInput,
|
|
518656
|
+
displayText,
|
|
518657
|
+
origin,
|
|
518658
|
+
agentId: this.harness.interactiveAgentId,
|
|
518659
|
+
mode: "channel",
|
|
518660
|
+
channelChatId,
|
|
518661
|
+
channelReportSources: channelReportSources,
|
|
518662
|
+
channelContextOnly: contextOnly,
|
|
518663
|
+
channelTranscriptRendered: true,
|
|
518664
|
+
channelAcknowledge: acknowledge,
|
|
518665
|
+
...channelFocusId === void 0 ? {} : { channelFocusId, channelAddressed: true },
|
|
518666
|
+
...channelAttention === true ? { channelAttention: true } : {},
|
|
518667
|
+
...channelDirect === true ? { channelDirect: true, channelDirectResume } : {},
|
|
518668
|
+
...queueKey === void 0 ? {} : { queueKey },
|
|
518669
|
+
...channelImagePath === void 0 ? {} : { channelImagePath }
|
|
518670
|
+
},
|
|
518671
|
+
onRestore: () => {
|
|
518672
|
+
if (installedGuard !== void 0 && this.pendingChannelReplyGuard === installedGuard) this.pendingChannelReplyGuard = previousGuard;
|
|
518673
|
+
}
|
|
518674
|
+
};
|
|
518675
|
+
} else acknowledge?.();
|
|
518589
518676
|
return;
|
|
518590
518677
|
}
|
|
518591
518678
|
if (installedGuard !== void 0 && this.pendingChannelReplyGuard === installedGuard) this.pendingChannelReplyGuard = previousGuard;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blun-king-cli",
|
|
3
|
-
"version": "9.1.
|
|
3
|
+
"version": "9.1.490",
|
|
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": {
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"standard-tools/",
|
|
40
40
|
"agent-spine-plugin/",
|
|
41
41
|
"telegram-plugin/",
|
|
42
|
+
"CHANGELOG.md",
|
|
42
43
|
"LIESMICH.txt"
|
|
43
44
|
],
|
|
44
45
|
"keywords": [
|