blun-king-cli 9.1.498 → 9.1.500
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 +13 -0
- package/LIESMICH.txt +18 -1
- package/README.md +18 -1
- package/bin/historical-media-projection-policy.cjs +48 -0
- package/blun.mjs +50 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.1.500 - 2026-08-30 - Golden Release
|
|
4
|
+
|
|
5
|
+
- Marks the complete cross-platform BLUN King package as the Golden Release for Windows, Linux, and macOS.
|
|
6
|
+
- Keeps the runtime behavior and verified TodoList, Telegram queue, session-loop, context-efficiency, AgentSpine, and managed vision changes from 9.1.499 byte-identical.
|
|
7
|
+
- Gives the 9.1.500 heading a dedicated gold treatment in the public changelog without changing the styling of earlier releases.
|
|
8
|
+
|
|
9
|
+
## 9.1.499 - 2026-08-30
|
|
10
|
+
|
|
11
|
+
- Replaces image, audio, and video payloads older than the newest twelve conversation messages with short model-facing references while preserving the complete original session wire and every recent media attachment.
|
|
12
|
+
- Reduces Fredrik's measured repeated model input by 85,748 characters, approximately 21,437 estimated tokens per subsequent work step, without changing the current image, message text, or persisted history.
|
|
13
|
+
- Runs overdue TodoList maintenance as its own low-effort model step before the ninth work batch and exposes only TodoList during that step, preventing the normal workflow from hitting a visible red policy error first.
|
|
14
|
+
- Keeps fresh user steers ahead of TodoList housekeeping while preserving the hard policy gate as a fallback for an actually invalid update.
|
|
15
|
+
|
|
3
16
|
## 9.1.498 - 2026-08-30
|
|
4
17
|
|
|
5
18
|
- Shows prompt-cache hit rate plus cache-read and cache-write tokens per model in `/usage`.
|
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.500
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -65,6 +65,23 @@ geschriebenen Entwurf zu löschen. Das gilt auch bei
|
|
|
65
65
|
Autovervollständigung, Geistervorschlägen, Bash-Eingabe und einer offenen
|
|
66
66
|
Mehrzeileneingabe.
|
|
67
67
|
|
|
68
|
+
Version 9.1.500 ist die Golden Release fuer Windows, Linux und macOS. Sie traegt
|
|
69
|
+
den vollstaendigen Funktionsstand von 9.1.499 unveraendert und wird im
|
|
70
|
+
oeffentlichen Changelog mit einer eigenen goldenen Ueberschrift gekennzeichnet.
|
|
71
|
+
|
|
72
|
+
Version 9.1.499 ersetzt Bild-, Audio- und Videodaten ausserhalb der neuesten zwoelf
|
|
73
|
+
Gespraechsnachrichten ausschliesslich in der wiederholten Modellprojektion durch
|
|
74
|
+
kurze Verweise. Aktuelle Medien, Nachrichtentext und vollstaendiger Sitzungsrohverlauf
|
|
75
|
+
bleiben unveraendert. In Fredriks gemessenem Wiederaufnahme-Checkpoint spart der
|
|
76
|
+
Schnitt 85.748 Zeichen beziehungsweise rund 21.437 geschaetzte Eingabetoken je
|
|
77
|
+
weiterem Werkzeugschritt.
|
|
78
|
+
|
|
79
|
+
Faellige Todo-Pflege laeuft in 9.1.499 vor dem naechsten Sachwerkzeug als eigener
|
|
80
|
+
kleiner Modellschritt. In diesem Schritt bietet die Laufzeit ausschliesslich
|
|
81
|
+
TodoList an; erst nach einer gueltigen Aktualisierung werden Datei-, Such- und
|
|
82
|
+
Shell-Werkzeuge wieder freigegeben. Dadurch entsteht im normalen Ablauf kein
|
|
83
|
+
roter Zwischenfehler. Frische Benutzernachrichten behalten Vorrang.
|
|
84
|
+
|
|
68
85
|
Version 9.1.498 zeigt in /usage die gemessene Prompt-Cache-Trefferquote sowie
|
|
69
86
|
gelesene und geschriebene Cache-Token je Modell. /tokens ist ein kurzer Alias
|
|
70
87
|
fuer die bereits vorhandene detaillierte Kontextdiagnose; /offload ruft die
|
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.500
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Reproduzierbares Staging und Packen
|
|
@@ -81,6 +81,23 @@ konkurrierenden Start zurückgewiesen und bleiben an der Spitze der
|
|
|
81
81
|
FIFO-Warteschlange. Für diesen normalen Wartestatus erscheint kein
|
|
82
82
|
`turn.agent_busy`-Fehler.
|
|
83
83
|
|
|
84
|
+
Version 9.1.500 ist die Golden Release fuer Windows, Linux und macOS. Sie traegt
|
|
85
|
+
den vollstaendigen Funktionsstand von 9.1.499 unveraendert und wird im
|
|
86
|
+
oeffentlichen Changelog mit einer eigenen goldenen Ueberschrift gekennzeichnet.
|
|
87
|
+
|
|
88
|
+
Version 9.1.499 ersetzt Bild-, Audio- und Videodaten außerhalb der neuesten zwölf
|
|
89
|
+
Gesprächsnachrichten ausschließlich in der wiederholten Modellprojektion durch
|
|
90
|
+
kurze Verweise. Aktuelle Medien, Nachrichtentext und vollständiger Sitzungsrohverlauf
|
|
91
|
+
bleiben unverändert. In Fredriks gemessenem Wiederaufnahme-Checkpoint spart der
|
|
92
|
+
Schnitt 85.748 Zeichen beziehungsweise rund 21.437 geschätzte Eingabetoken je
|
|
93
|
+
weiterem Werkzeugschritt.
|
|
94
|
+
|
|
95
|
+
Faellige Todo-Pflege laeuft in 9.1.499 vor dem naechsten Sachwerkzeug als eigener
|
|
96
|
+
kleiner Modellschritt. In diesem Schritt bietet die Laufzeit ausschliesslich
|
|
97
|
+
`TodoList` an; erst nach einer gueltigen Aktualisierung werden Datei-, Such- und
|
|
98
|
+
Shell-Werkzeuge wieder freigegeben. Dadurch entsteht im normalen Ablauf kein
|
|
99
|
+
roter Zwischenfehler. Frische Benutzernachrichten behalten Vorrang.
|
|
100
|
+
|
|
84
101
|
Version 9.1.498 zeigt in `/usage` die gemessene Prompt-Cache-Trefferquote sowie
|
|
85
102
|
gelesene und geschriebene Cache-Token je Modell. `/tokens` ist ein kurzer Alias
|
|
86
103
|
fuer die bereits vorhandene detaillierte Kontextdiagnose; `/offload` ruft die
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const HISTORICAL_MEDIA_KEEP_RECENT_MESSAGES = 12;
|
|
4
|
+
const HISTORICAL_MEDIA_PLACEHOLDERS = Object.freeze({
|
|
5
|
+
image_url: '[historical image omitted from active model context; original remains in session wire]',
|
|
6
|
+
audio_url: '[historical audio omitted from active model context; original remains in session wire]',
|
|
7
|
+
video_url: '[historical video omitted from active model context; original remains in session wire]',
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
function projectHistoricalMediaParts(messages, options = {}) {
|
|
11
|
+
if (!Array.isArray(messages) || messages.length === 0) return messages;
|
|
12
|
+
const keepRecentMessages = nonNegativeInteger(
|
|
13
|
+
options.keepRecentMessages,
|
|
14
|
+
HISTORICAL_MEDIA_KEEP_RECENT_MESSAGES,
|
|
15
|
+
);
|
|
16
|
+
const historicalEnd = Math.max(0, messages.length - keepRecentMessages);
|
|
17
|
+
let changed = false;
|
|
18
|
+
|
|
19
|
+
const projected = messages.map((message, messageIndex) => {
|
|
20
|
+
if (messageIndex >= historicalEnd || !Array.isArray(message?.content)) return message;
|
|
21
|
+
let nextContent;
|
|
22
|
+
for (let partIndex = 0; partIndex < message.content.length; partIndex += 1) {
|
|
23
|
+
const part = message.content[partIndex];
|
|
24
|
+
const placeholder = HISTORICAL_MEDIA_PLACEHOLDERS[part?.type];
|
|
25
|
+
if (placeholder === undefined) {
|
|
26
|
+
nextContent?.push(part);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
nextContent ??= message.content.slice(0, partIndex);
|
|
30
|
+
nextContent.push({ type: 'text', text: placeholder });
|
|
31
|
+
changed = true;
|
|
32
|
+
}
|
|
33
|
+
return nextContent === undefined ? message : { ...message, content: nextContent };
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return changed ? projected : messages;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function nonNegativeInteger(value, fallback) {
|
|
40
|
+
const number = Number(value);
|
|
41
|
+
return Number.isInteger(number) && number >= 0 ? number : fallback;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = {
|
|
45
|
+
HISTORICAL_MEDIA_KEEP_RECENT_MESSAGES,
|
|
46
|
+
HISTORICAL_MEDIA_PLACEHOLDERS,
|
|
47
|
+
projectHistoricalMediaParts,
|
|
48
|
+
};
|
package/blun.mjs
CHANGED
|
@@ -79049,7 +79049,8 @@ var init_context$2 = __esmMin((() => {
|
|
|
79049
79049
|
project(messages, options) {
|
|
79050
79050
|
const anomalies = [];
|
|
79051
79051
|
const userOffloaded = this.agent.userMessageOffload.compact(messages);
|
|
79052
|
-
const
|
|
79052
|
+
const historicalMediaProjected = projectHistoricalMediaParts(userOffloaded);
|
|
79053
|
+
const historicalUserReferencesProjected = compactHistoricalPersistedUserMessageReferences(historicalMediaProjected);
|
|
79053
79054
|
const duplicateUserMessagesProjected = dedupeRepeatedUserMessages(historicalUserReferencesProjected);
|
|
79054
79055
|
const historicalTelegramProjected = projectHistoricalUnaddressedTelegramMessages(duplicateUserMessagesProjected);
|
|
79055
79056
|
const assistantOffloaded = this.agent.assistantMessageOffload.compact(historicalTelegramProjected);
|
|
@@ -261279,7 +261280,7 @@ function renderPersistedUserMessage(text, outputPath) {
|
|
|
261279
261280
|
createUserMessagePreview(text)
|
|
261280
261281
|
].join("\n");
|
|
261281
261282
|
}
|
|
261282
|
-
var USER_MESSAGE_MAX_CHARS, USER_MESSAGE_OFFLOAD_MARKER, shouldOffloadUserMessage, shouldOffloadHistoricalUserMessage, createUserMessagePreview, compactHistoricalPersistedUserMessageReferences;
|
|
261283
|
+
var USER_MESSAGE_MAX_CHARS, USER_MESSAGE_OFFLOAD_MARKER, shouldOffloadUserMessage, shouldOffloadHistoricalUserMessage, createUserMessagePreview, compactHistoricalPersistedUserMessageReferences, projectHistoricalMediaParts;
|
|
261283
261284
|
var init_user_message_offload = __esmMin((() => {
|
|
261284
261285
|
const policy = createRequire(import.meta.url)("./bin/user-message-offload-policy.cjs");
|
|
261285
261286
|
USER_MESSAGE_MAX_CHARS = policy.USER_MESSAGE_MAX_CHARS;
|
|
@@ -261287,8 +261288,9 @@ var init_user_message_offload = __esmMin((() => {
|
|
|
261287
261288
|
shouldOffloadUserMessage = policy.shouldOffloadUserMessage;
|
|
261288
261289
|
shouldOffloadHistoricalUserMessage = policy.shouldOffloadHistoricalUserMessage;
|
|
261289
261290
|
createUserMessagePreview = policy.createUserMessagePreview;
|
|
261290
|
-
|
|
261291
|
-
}));
|
|
261291
|
+
compactHistoricalPersistedUserMessageReferences = policy.compactHistoricalPersistedUserMessageReferences;
|
|
261292
|
+
({ projectHistoricalMediaParts } = createRequire(import.meta.url)("./bin/historical-media-projection-policy.cjs"));
|
|
261293
|
+
}));
|
|
261292
261294
|
var UserMessageOffload = class {
|
|
261293
261295
|
agent;
|
|
261294
261296
|
replacements = /* @__PURE__ */ new Map();
|
|
@@ -262784,6 +262786,24 @@ var init_turn = __esmMin((() => {
|
|
|
262784
262786
|
currentStepHadFailure = false;
|
|
262785
262787
|
const pendingSteers = this.matchingSteers(turnId);
|
|
262786
262788
|
if (pendingSteers.length === 0) {
|
|
262789
|
+
const todoMaintenanceMode = goalTodoMaintenanceMode(this.agent);
|
|
262790
|
+
if (todoMaintenanceMode !== null) {
|
|
262791
|
+
const todoTool = eligibleTools.find((tool) => tool.name === "TodoList");
|
|
262792
|
+
if (todoTool === void 0) return {
|
|
262793
|
+
block: true,
|
|
262794
|
+
reason: "TodoList maintenance is due, but the TodoList tool is unavailable."
|
|
262795
|
+
};
|
|
262796
|
+
this.agent.log.info("proactive TodoList maintenance step", {
|
|
262797
|
+
stepNumber,
|
|
262798
|
+
mode: todoMaintenanceMode,
|
|
262799
|
+
workCallsSinceRefresh: this.agent.goalTodoPolicyState?.workCallsSinceRefresh ?? 0
|
|
262800
|
+
});
|
|
262801
|
+
const todoSystemPrompt = buildGoalTodoMaintenanceSystemPrompt(this.agent, turnSystemPrompt ?? this.agent.effectiveSystemPrompt, todoMaintenanceMode);
|
|
262802
|
+
return {
|
|
262803
|
+
llm: this.agent.llmForTurn("low", todoSystemPrompt),
|
|
262804
|
+
tools: [todoTool]
|
|
262805
|
+
};
|
|
262806
|
+
}
|
|
262787
262807
|
if (workStepThinkingEffort === void 0) return;
|
|
262788
262808
|
this.agent.log.info("work step thinking effort", {
|
|
262789
262809
|
stepNumber,
|
|
@@ -423194,6 +423214,7 @@ async function handleGoalCommand(host, args) {
|
|
|
423194
423214
|
}
|
|
423195
423215
|
const IDEA_CONTRACT_MARKER = "Work as a self-directing employee:";
|
|
423196
423216
|
const IDEA_ALLOWED_CHANNELS = Object.freeze([]);
|
|
423217
|
+
const GOAL_TODO_REFRESH_WORK_CALL_LIMIT = 8;
|
|
423197
423218
|
const IDEA_TERMINAL_TODO_STATUSES = Object.freeze([
|
|
423198
423219
|
"done",
|
|
423199
423220
|
"blocked",
|
|
@@ -423221,6 +423242,30 @@ function validInitialIdeaPlan(value) {
|
|
|
423221
423242
|
}
|
|
423222
423243
|
return active === 1;
|
|
423223
423244
|
}
|
|
423245
|
+
function goalTodoMaintenanceMode(agent) {
|
|
423246
|
+
if (isIdeaGoal(agent)) return null;
|
|
423247
|
+
const todos = ideaTodos(agent);
|
|
423248
|
+
if (todos.length === 0) return agent.goal.getActiveGoal() === null ? null : "initial";
|
|
423249
|
+
const progress = agent.goalTodoPolicyState ??= {
|
|
423250
|
+
workCallsSinceRefresh: 0,
|
|
423251
|
+
refreshRequired: false
|
|
423252
|
+
};
|
|
423253
|
+
return progress.refreshRequired || progress.workCallsSinceRefresh >= GOAL_TODO_REFRESH_WORK_CALL_LIMIT ? "refresh" : null;
|
|
423254
|
+
}
|
|
423255
|
+
function buildGoalTodoMaintenanceSystemPrompt(agent, basePrompt, mode) {
|
|
423256
|
+
const todos = ideaTodos(agent);
|
|
423257
|
+
const visibleTodoList = todos.length === 0 ? "The visible TodoList is empty." : ["Current visible TodoList:", ...todos.map((todo) => `- [${String(todo?.status ?? "pending")}] ${String(todo?.title ?? "").trim()}`)].join("\n");
|
|
423258
|
+
const action = mode === "initial" ? "Create the visible task-specific TodoList now. Keep exactly one item in_progress and every later item pending." : "Update the visible TodoList now, before any more task work. Mark only evidenced steps done, keep the actual current step in_progress, and leave later steps pending. If the current title is stale, refine it to the concrete verified substep.";
|
|
423259
|
+
return `<todo-maintenance>
|
|
423260
|
+
TODO MAINTENANCE IS THE ONLY ACTION FOR THIS STEP.
|
|
423261
|
+
${action}
|
|
423262
|
+
Call TodoList as the first and only tool. Do not call a work, search, file, shell, web, messaging, or goal tool in this step. Do not merely describe the update.
|
|
423263
|
+
|
|
423264
|
+
${visibleTodoList}
|
|
423265
|
+
</todo-maintenance>
|
|
423266
|
+
|
|
423267
|
+
${basePrompt}`;
|
|
423268
|
+
}
|
|
423224
423269
|
function enforceGoalTodoPolicy(agent, context) {
|
|
423225
423270
|
if (isIdeaGoal(agent)) return;
|
|
423226
423271
|
if (TELEGRAM_DELIVERY_TOOL_RE.test(String(context.toolCall.name ?? ""))) return;
|
|
@@ -423295,7 +423340,7 @@ function enforceGoalTodoPolicy(agent, context) {
|
|
|
423295
423340
|
}
|
|
423296
423341
|
if (context.toolCall.id === context.toolCalls[0]?.id) {
|
|
423297
423342
|
progress.workCallsSinceRefresh += 1;
|
|
423298
|
-
if (progress.workCallsSinceRefresh >
|
|
423343
|
+
if (progress.workCallsSinceRefresh > GOAL_TODO_REFRESH_WORK_CALL_LIMIT) progress.refreshRequired = true;
|
|
423299
423344
|
}
|
|
423300
423345
|
if (!progress.refreshRequired) return;
|
|
423301
423346
|
return {
|