blun-king-cli 9.1.110 → 9.1.112
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/bin/user-message-offload-policy.cjs +21 -0
- package/blun.mjs +44 -29
- package/package.json +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const USER_MESSAGE_MAX_CHARS = 200_000;
|
|
4
|
+
const HISTORICAL_USER_MESSAGE_MAX_CHARS = 4_000;
|
|
5
|
+
const USER_MESSAGE_KEEP_RECENT_MESSAGES = 20;
|
|
4
6
|
const USER_MESSAGE_PREVIEW_LINES = 5;
|
|
5
7
|
const USER_MESSAGE_PREVIEW_LINE_CHARS = 1_000;
|
|
6
8
|
const USER_MESSAGE_OFFLOAD_MARKER = '[User message offloaded]';
|
|
@@ -9,6 +11,22 @@ function shouldOffloadUserMessage(textChars) {
|
|
|
9
11
|
return Number.isSafeInteger(textChars) && textChars > USER_MESSAGE_MAX_CHARS;
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
function shouldOffloadHistoricalUserMessage(options = {}) {
|
|
15
|
+
const historyIndex = Number(options.historyIndex);
|
|
16
|
+
const historyLength = Number(options.historyLength);
|
|
17
|
+
const textChars = Number(options.textChars);
|
|
18
|
+
if (
|
|
19
|
+
!Number.isSafeInteger(historyIndex)
|
|
20
|
+
|| !Number.isSafeInteger(historyLength)
|
|
21
|
+
|| !Number.isSafeInteger(textChars)
|
|
22
|
+
|| historyIndex < 0
|
|
23
|
+
|| historyLength < 0
|
|
24
|
+
|| historyIndex >= historyLength
|
|
25
|
+
) return false;
|
|
26
|
+
const cutoff = Math.max(0, historyLength - USER_MESSAGE_KEEP_RECENT_MESSAGES);
|
|
27
|
+
return historyIndex < cutoff && textChars > HISTORICAL_USER_MESSAGE_MAX_CHARS;
|
|
28
|
+
}
|
|
29
|
+
|
|
12
30
|
function createUserMessagePreview(text) {
|
|
13
31
|
const lines = String(text).split(/\r?\n/u);
|
|
14
32
|
const render = (line, index) => `${index}: ${line.slice(0, USER_MESSAGE_PREVIEW_LINE_CHARS)}`;
|
|
@@ -28,10 +46,13 @@ function createUserMessagePreview(text) {
|
|
|
28
46
|
}
|
|
29
47
|
|
|
30
48
|
module.exports = {
|
|
49
|
+
HISTORICAL_USER_MESSAGE_MAX_CHARS,
|
|
31
50
|
USER_MESSAGE_MAX_CHARS,
|
|
51
|
+
USER_MESSAGE_KEEP_RECENT_MESSAGES,
|
|
32
52
|
USER_MESSAGE_OFFLOAD_MARKER,
|
|
33
53
|
USER_MESSAGE_PREVIEW_LINES,
|
|
34
54
|
USER_MESSAGE_PREVIEW_LINE_CHARS,
|
|
35
55
|
createUserMessagePreview,
|
|
56
|
+
shouldOffloadHistoricalUserMessage,
|
|
36
57
|
shouldOffloadUserMessage,
|
|
37
58
|
};
|
package/blun.mjs
CHANGED
|
@@ -260422,7 +260422,7 @@ async function saveUserMessage(homedir, text) {
|
|
|
260422
260422
|
function renderPersistedUserMessage(text, outputPath) {
|
|
260423
260423
|
return [
|
|
260424
260424
|
USER_MESSAGE_OFFLOAD_MARKER,
|
|
260425
|
-
|
|
260425
|
+
"The complete original was archived to keep the active context fast and remains available on disk.",
|
|
260426
260426
|
`message_size_chars: ${String(text.length)}`,
|
|
260427
260427
|
`message_size_bytes: ${String(Buffer.byteLength(text, "utf8"))}`,
|
|
260428
260428
|
`output_path: ${outputPath}`,
|
|
@@ -260432,12 +260432,13 @@ function renderPersistedUserMessage(text, outputPath) {
|
|
|
260432
260432
|
createUserMessagePreview(text)
|
|
260433
260433
|
].join("\n");
|
|
260434
260434
|
}
|
|
260435
|
-
var USER_MESSAGE_MAX_CHARS, USER_MESSAGE_OFFLOAD_MARKER, shouldOffloadUserMessage, createUserMessagePreview;
|
|
260435
|
+
var USER_MESSAGE_MAX_CHARS, USER_MESSAGE_OFFLOAD_MARKER, shouldOffloadUserMessage, shouldOffloadHistoricalUserMessage, createUserMessagePreview;
|
|
260436
260436
|
var init_user_message_offload = __esmMin((() => {
|
|
260437
260437
|
const policy = createRequire(import.meta.url)("./bin/user-message-offload-policy.cjs");
|
|
260438
260438
|
USER_MESSAGE_MAX_CHARS = policy.USER_MESSAGE_MAX_CHARS;
|
|
260439
260439
|
USER_MESSAGE_OFFLOAD_MARKER = policy.USER_MESSAGE_OFFLOAD_MARKER;
|
|
260440
260440
|
shouldOffloadUserMessage = policy.shouldOffloadUserMessage;
|
|
260441
|
+
shouldOffloadHistoricalUserMessage = policy.shouldOffloadHistoricalUserMessage;
|
|
260441
260442
|
createUserMessagePreview = policy.createUserMessagePreview;
|
|
260442
260443
|
}));
|
|
260443
260444
|
var UserMessageOffload = class {
|
|
@@ -260447,30 +260448,44 @@ var UserMessageOffload = class {
|
|
|
260447
260448
|
this.agent = agent;
|
|
260448
260449
|
}
|
|
260449
260450
|
async detect() {
|
|
260450
|
-
const
|
|
260451
|
-
|
|
260452
|
-
|
|
260453
|
-
|
|
260454
|
-
|
|
260455
|
-
|
|
260456
|
-
|
|
260457
|
-
|
|
260458
|
-
|
|
260459
|
-
|
|
260460
|
-
|
|
260461
|
-
|
|
260462
|
-
|
|
260463
|
-
|
|
260464
|
-
|
|
260465
|
-
|
|
260466
|
-
|
|
260467
|
-
|
|
260468
|
-
|
|
260469
|
-
|
|
260470
|
-
|
|
260471
|
-
|
|
260472
|
-
|
|
260473
|
-
|
|
260451
|
+
const history = this.agent.context.history;
|
|
260452
|
+
if (this.agent.homedir === void 0) return 0;
|
|
260453
|
+
let offloaded = 0;
|
|
260454
|
+
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
260455
|
+
const message = history[historyIndex];
|
|
260456
|
+
const text = persistableUserMessageText(message);
|
|
260457
|
+
if (text === void 0) continue;
|
|
260458
|
+
const immediateOversize = historyIndex === history.length - 1 && shouldOffloadUserMessage(text.length);
|
|
260459
|
+
const historicalOversize = shouldOffloadHistoricalUserMessage({
|
|
260460
|
+
historyIndex,
|
|
260461
|
+
historyLength: history.length,
|
|
260462
|
+
textChars: text.length
|
|
260463
|
+
});
|
|
260464
|
+
if (!immediateOversize && !historicalOversize) continue;
|
|
260465
|
+
const messageHash = userMessageOffloadHash(message, text);
|
|
260466
|
+
if (this.replacements.has(messageHash)) continue;
|
|
260467
|
+
const outputPath = await saveUserMessage(this.agent.homedir, text);
|
|
260468
|
+
if (outputPath === void 0) continue;
|
|
260469
|
+
const replacementText = renderPersistedUserMessage(text, outputPath);
|
|
260470
|
+
const content = [{
|
|
260471
|
+
type: "text",
|
|
260472
|
+
text: replacementText
|
|
260473
|
+
}, ...message.content.filter((part) => part.type !== "text")];
|
|
260474
|
+
this.apply({
|
|
260475
|
+
messageHash,
|
|
260476
|
+
content,
|
|
260477
|
+
outputPath
|
|
260478
|
+
});
|
|
260479
|
+
this.agent.telemetry.track("user_message_offloaded", {
|
|
260480
|
+
chars_before: text.length,
|
|
260481
|
+
chars_after: replacementText.length,
|
|
260482
|
+
chars_saved: text.length - replacementText.length,
|
|
260483
|
+
media_part_count: content.length - 1,
|
|
260484
|
+
reason: immediateOversize ? "immediate_oversize" : "historical_oversize"
|
|
260485
|
+
});
|
|
260486
|
+
offloaded++;
|
|
260487
|
+
}
|
|
260488
|
+
return offloaded;
|
|
260474
260489
|
}
|
|
260475
260490
|
apply(replacement) {
|
|
260476
260491
|
this.replacements.set(replacement.messageHash, replacement);
|
|
@@ -260584,12 +260599,12 @@ function blunFastConversationTools(tools, input, pendingMediaJobIds = []) {
|
|
|
260584
260599
|
* name through ToolSearch. The absolute cap prevents large context windows
|
|
260585
260600
|
* from turning every deferred schema into permanent request overhead.
|
|
260586
260601
|
*/
|
|
260587
|
-
function blunSelectTurnTools(tools, maxContextTokens, loadedToolNames) {
|
|
260602
|
+
function blunSelectTurnTools(tools, maxContextTokens, loadedToolNames, requiredToolNames = /* @__PURE__ */ new Set()) {
|
|
260588
260603
|
if (estimateTokensForTools(tools) <= toolSchemaBudgetTokens(maxContextTokens)) return {
|
|
260589
260604
|
tools,
|
|
260590
260605
|
deferredToolCount: 0
|
|
260591
260606
|
};
|
|
260592
|
-
const selected = tools.filter((tool) => BLUN_LEAN_TOOL_NAMES.has(tool.name) || loadedToolNames.has(tool.name));
|
|
260607
|
+
const selected = tools.filter((tool) => BLUN_LEAN_TOOL_NAMES.has(tool.name) || loadedToolNames.has(tool.name) || requiredToolNames.has(tool.name));
|
|
260593
260608
|
const selectedNames = new Set(selected.map((tool) => tool.name));
|
|
260594
260609
|
const deferred = tools.filter((tool) => !selectedNames.has(tool.name));
|
|
260595
260610
|
if (deferred.length > 0) selected.push(createDeferredToolLoader(selected, deferred, loadedToolNames));
|
|
@@ -261430,7 +261445,7 @@ var init_turn = __esmMin((() => {
|
|
|
261430
261445
|
const toolSelection = fastConversation ? {
|
|
261431
261446
|
tools: [...blunFastConversationTools(eligibleTools, input, pendingMediaJobIds)],
|
|
261432
261447
|
deferredToolCount: 0
|
|
261433
|
-
} : turnNeedsTools ? blunSelectTurnTools(eligibleTools, this.agent.config.modelCapabilities?.max_context_tokens, this.loadedToolNames) : {
|
|
261448
|
+
} : turnNeedsTools ? blunSelectTurnTools(eligibleTools, this.agent.config.modelCapabilities?.max_context_tokens, this.loadedToolNames, turnHasAttachment ? new Set(["mcp__plugin-telegram_telegram__download_attachment"]) : void 0) : {
|
|
261434
261449
|
tools: [],
|
|
261435
261450
|
deferredToolCount: 0
|
|
261436
261451
|
};
|