blun-king-cli 9.1.76 → 9.1.77
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/LIESMICH.txt +15 -1
- package/README.md +14 -0
- package/bin/micro-compaction-policy.cjs +75 -0
- package/blun.mjs +62 -3
- package/package.json +1 -1
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.77
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -72,6 +72,20 @@ parallel geprüft und eingelesen. Die Skills werden weiterhin in der
|
|
|
72
72
|
ursprünglichen, festen Reihenfolge registriert; Priorität und Verhalten bei
|
|
73
73
|
doppelten Namen bleiben unverändert.
|
|
74
74
|
|
|
75
|
+
Kontextentlastung bei langen Sitzungen
|
|
76
|
+
--------------------------------------
|
|
77
|
+
King bewahrt den vollständigen Verlauf weiterhin im Sitzungs-Wire auf. Erreicht
|
|
78
|
+
der aktive Verlauf 75 Prozent des Modellfensters, ersetzt die Modellprojektion
|
|
79
|
+
ältere große Werkzeugergebnisse durch einen kurzen Platzhalter. Die letzten 20
|
|
80
|
+
Nachrichten bleiben unverändert. Solange der Prefix-Cache warm ist, wird der
|
|
81
|
+
Schnitt höchstens nach jeweils 20 weiteren Nachrichten verschoben. Nach einer
|
|
82
|
+
Stunde ohne Modellantwort darf er sofort nachziehen.
|
|
83
|
+
|
|
84
|
+
Dabei werden keine gespeicherten Nachrichten geändert oder gelöscht. Fortsetzen,
|
|
85
|
+
Exportieren und die sichtbare Historie behalten die ursprünglichen
|
|
86
|
+
Werkzeugergebnisse. Das Telemetrieereignis `micro_compaction_finished` nennt den
|
|
87
|
+
Auslöser, den Schnitt und die geschätzte Tokenzahl vor und nach der Entlastung.
|
|
88
|
+
|
|
75
89
|
Zug-Wächter
|
|
76
90
|
-----------
|
|
77
91
|
Läuft ein Zug 20 Minuten ohne neues Werkzeugergebnis, meldet die Konsole den
|
package/README.md
CHANGED
|
@@ -94,6 +94,20 @@ parallel geprüft und eingelesen. Die Skills werden weiterhin in der
|
|
|
94
94
|
ursprünglichen, festen Reihenfolge registriert; Priorität und Verhalten bei
|
|
95
95
|
doppelten Namen bleiben unverändert.
|
|
96
96
|
|
|
97
|
+
## Kontextentlastung bei langen Sitzungen
|
|
98
|
+
|
|
99
|
+
King bewahrt den vollständigen Verlauf weiterhin im Sitzungs-Wire auf. Erreicht
|
|
100
|
+
der aktive Verlauf 75 Prozent des Modellfensters, ersetzt die Modellprojektion
|
|
101
|
+
ältere große Werkzeugergebnisse durch einen kurzen Platzhalter. Die letzten 20
|
|
102
|
+
Nachrichten bleiben unverändert. Solange der Prefix-Cache warm ist, wird der
|
|
103
|
+
Schnitt höchstens nach jeweils 20 weiteren Nachrichten verschoben. Nach einer
|
|
104
|
+
Stunde ohne Modellantwort darf er sofort nachziehen.
|
|
105
|
+
|
|
106
|
+
Dabei werden keine gespeicherten Nachrichten geändert oder gelöscht. Fortsetzen,
|
|
107
|
+
Exportieren und die sichtbare Historie behalten die ursprünglichen
|
|
108
|
+
Werkzeugergebnisse. Das Telemetrieereignis `micro_compaction_finished` nennt den
|
|
109
|
+
Auslöser, den Schnitt und die geschätzte Tokenzahl vor und nach der Entlastung.
|
|
110
|
+
|
|
97
111
|
## Zug-Wächter
|
|
98
112
|
|
|
99
113
|
Läuft ein Zug 20 Minuten ohne neues Werkzeugergebnis, meldet die Konsole den
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const MICRO_COMPACTION_PRESSURE_RATIO = 0.75;
|
|
4
|
+
const MICRO_COMPACTION_MIN_ADVANCE_MESSAGES = 20;
|
|
5
|
+
|
|
6
|
+
function selectMicroCompactionCutoff(options = {}) {
|
|
7
|
+
const historyLength = nonNegativeInteger(options.historyLength);
|
|
8
|
+
const currentCutoff = nonNegativeInteger(options.currentCutoff);
|
|
9
|
+
const keepRecentMessages = nonNegativeInteger(options.keepRecentMessages);
|
|
10
|
+
const nextCutoff = Math.max(0, historyLength - keepRecentMessages);
|
|
11
|
+
if (nextCutoff <= currentCutoff) return null;
|
|
12
|
+
|
|
13
|
+
const maxContextTokens = positiveFinite(options.maxContextTokens);
|
|
14
|
+
const contextTokens = nonNegativeFinite(options.contextTokens);
|
|
15
|
+
const contextUsageRatio = maxContextTokens === null
|
|
16
|
+
? 1
|
|
17
|
+
: contextTokens / maxContextTokens;
|
|
18
|
+
const minContextUsageRatio = nonNegativeFinite(options.minContextUsageRatio);
|
|
19
|
+
if (contextUsageRatio < minContextUsageRatio) return null;
|
|
20
|
+
|
|
21
|
+
const now = finiteOr(options.now, Date.now());
|
|
22
|
+
const lastAssistantAt = finiteOrNull(options.lastAssistantAt);
|
|
23
|
+
const cacheAgeMs = lastAssistantAt === null ? null : Math.max(0, now - lastAssistantAt);
|
|
24
|
+
const cacheMissedThresholdMs = nonNegativeFinite(options.cacheMissedThresholdMs);
|
|
25
|
+
const cacheMissed = cacheAgeMs !== null && cacheAgeMs >= cacheMissedThresholdMs;
|
|
26
|
+
const underContextPressure = maxContextTokens !== null
|
|
27
|
+
&& contextUsageRatio >= MICRO_COMPACTION_PRESSURE_RATIO;
|
|
28
|
+
if (!cacheMissed && !underContextPressure) return null;
|
|
29
|
+
|
|
30
|
+
if (
|
|
31
|
+
!cacheMissed
|
|
32
|
+
&& currentCutoff > 0
|
|
33
|
+
&& nextCutoff - currentCutoff < MICRO_COMPACTION_MIN_ADVANCE_MESSAGES
|
|
34
|
+
) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
cacheAgeMs,
|
|
40
|
+
contextUsageRatio,
|
|
41
|
+
cutoff: nextCutoff,
|
|
42
|
+
trigger: cacheMissed ? 'cache_miss' : 'context_pressure',
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function finiteOr(value, fallback) {
|
|
47
|
+
const number = Number(value);
|
|
48
|
+
return Number.isFinite(number) ? number : fallback;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function finiteOrNull(value) {
|
|
52
|
+
if (value === null || value === undefined) return null;
|
|
53
|
+
const number = Number(value);
|
|
54
|
+
return Number.isFinite(number) ? number : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function nonNegativeFinite(value) {
|
|
58
|
+
const number = Number(value);
|
|
59
|
+
return Number.isFinite(number) && number >= 0 ? number : 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function nonNegativeInteger(value) {
|
|
63
|
+
return Math.floor(nonNegativeFinite(value));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function positiveFinite(value) {
|
|
67
|
+
const number = Number(value);
|
|
68
|
+
return Number.isFinite(number) && number > 0 ? number : null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
MICRO_COMPACTION_MIN_ADVANCE_MESSAGES,
|
|
73
|
+
MICRO_COMPACTION_PRESSURE_RATIO,
|
|
74
|
+
selectMicroCompactionCutoff,
|
|
75
|
+
};
|
package/blun.mjs
CHANGED
|
@@ -75889,8 +75889,9 @@ var init_full = __esmMin((() => {
|
|
|
75889
75889
|
}));
|
|
75890
75890
|
//#endregion
|
|
75891
75891
|
//#region ../../packages/agent-core/src/agent/compaction/micro.ts
|
|
75892
|
-
var DEFAULT_CONFIG, MicroCompaction;
|
|
75892
|
+
var selectMicroCompactionCutoff, DEFAULT_CONFIG, MicroCompaction;
|
|
75893
75893
|
var init_micro = __esmMin((() => {
|
|
75894
|
+
({ selectMicroCompactionCutoff } = createRequire(import.meta.url)("./bin/micro-compaction-policy.cjs"));
|
|
75894
75895
|
init_tokens();
|
|
75895
75896
|
DEFAULT_CONFIG = {
|
|
75896
75897
|
keepRecentMessages: 20,
|
|
@@ -75920,9 +75921,67 @@ var init_micro = __esmMin((() => {
|
|
|
75920
75921
|
});
|
|
75921
75922
|
this.cutoff = cutoff;
|
|
75922
75923
|
}
|
|
75923
|
-
detect() {
|
|
75924
|
+
detect() {
|
|
75925
|
+
const config = this.config;
|
|
75926
|
+
const { history, lastAssistantAt } = this.agent.context;
|
|
75927
|
+
const maxContextTokens = this.agent.config.modelCapabilities.max_context_tokens;
|
|
75928
|
+
const contextTokens = this.agent.context.tokenCountWithPending;
|
|
75929
|
+
const selection = selectMicroCompactionCutoff({
|
|
75930
|
+
historyLength: history.length,
|
|
75931
|
+
currentCutoff: this.cutoff,
|
|
75932
|
+
keepRecentMessages: config.keepRecentMessages,
|
|
75933
|
+
contextTokens,
|
|
75934
|
+
maxContextTokens,
|
|
75935
|
+
lastAssistantAt,
|
|
75936
|
+
now: Date.now(),
|
|
75937
|
+
cacheMissedThresholdMs: config.cacheMissedThresholdMs,
|
|
75938
|
+
minContextUsageRatio: config.minContextUsageRatio
|
|
75939
|
+
});
|
|
75940
|
+
if (selection === null) return;
|
|
75941
|
+
const previousCutoff = this.cutoff;
|
|
75942
|
+
const effect = this.measureEffect(history, selection.cutoff);
|
|
75943
|
+
const previousEffect = this.measureEffect(history, previousCutoff);
|
|
75944
|
+
if (effect.truncatedToolResultCount <= previousEffect.truncatedToolResultCount) return;
|
|
75945
|
+
this.apply(selection.cutoff);
|
|
75946
|
+
const rawContextTokens = estimateTokensForMessages(history);
|
|
75947
|
+
const tokensBefore = rawContextTokens - previousEffect.truncatedToolResultTokensBefore + previousEffect.truncatedToolResultTokensAfter;
|
|
75948
|
+
const tokensAfter = rawContextTokens - effect.truncatedToolResultTokensBefore + effect.truncatedToolResultTokensAfter;
|
|
75949
|
+
this.agent.telemetry.track("micro_compaction_finished", {
|
|
75950
|
+
trigger: selection.trigger,
|
|
75951
|
+
keep_recent_messages: config.keepRecentMessages,
|
|
75952
|
+
min_content_tokens: config.minContentTokens,
|
|
75953
|
+
cache_missed_threshold_ms: config.cacheMissedThresholdMs,
|
|
75954
|
+
truncated_marker: config.truncatedMarker,
|
|
75955
|
+
min_context_usage_ratio: config.minContextUsageRatio,
|
|
75956
|
+
context_usage_ratio: selection.contextUsageRatio,
|
|
75957
|
+
truncated_tool_result_count: effect.truncatedToolResultCount,
|
|
75958
|
+
truncated_tool_result_tokens_before: effect.truncatedToolResultTokensBefore,
|
|
75959
|
+
truncated_tool_result_tokens_after: effect.truncatedToolResultTokensAfter,
|
|
75960
|
+
tokens_before: tokensBefore,
|
|
75961
|
+
tokens_after: tokensAfter,
|
|
75962
|
+
previous_cutoff: previousCutoff,
|
|
75963
|
+
cutoff: selection.cutoff,
|
|
75964
|
+
message_count: history.length,
|
|
75965
|
+
cache_age_ms: selection.cacheAgeMs,
|
|
75966
|
+
thinking_effort: this.agent.config.thinkingEffort
|
|
75967
|
+
});
|
|
75968
|
+
}
|
|
75924
75969
|
compact(messages) {
|
|
75925
|
-
|
|
75970
|
+
const config = this.config;
|
|
75971
|
+
const result = [];
|
|
75972
|
+
let i = 0;
|
|
75973
|
+
for (const msg of messages) {
|
|
75974
|
+
if (i < this.cutoff && msg.role === "tool" && msg.toolCallId !== void 0 && estimateTokensForContentParts(msg.content) >= config.minContentTokens) result.push({
|
|
75975
|
+
...msg,
|
|
75976
|
+
content: [{
|
|
75977
|
+
type: "text",
|
|
75978
|
+
text: config.truncatedMarker
|
|
75979
|
+
}]
|
|
75980
|
+
});
|
|
75981
|
+
else result.push(msg);
|
|
75982
|
+
i++;
|
|
75983
|
+
}
|
|
75984
|
+
return result;
|
|
75926
75985
|
}
|
|
75927
75986
|
measureEffect(messages, cutoff) {
|
|
75928
75987
|
let markerTokenCount;
|