blun-king-cli 9.1.82 → 9.1.84
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
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.84
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -74,17 +74,9 @@ doppelten Namen bleiben unverändert.
|
|
|
74
74
|
|
|
75
75
|
Kontextentlastung bei langen Sitzungen
|
|
76
76
|
--------------------------------------
|
|
77
|
-
King bewahrt den vollständigen Verlauf weiterhin im Sitzungs-Wire auf. Erreicht
|
|
78
|
-
|
|
79
|
-
|
|
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.
|
|
77
|
+
King bewahrt den vollständigen Verlauf weiterhin im Sitzungs-Wire auf. Erreicht der aktive Verlauf 75 Prozent des Modellfensters, ersetzt die Modellprojektion ältere große Werkzeugergebnisse sowie große Argumente abgeschlossener Werkzeugaufrufe durch kurze Platzhalter. Werkzeugargumente werden nur entlastet, wenn ein zugehöriges Werkzeugergebnis vorliegt und die gespeicherten Argumente gültiges JSON sind. Die letzten 20 Nachrichten bleiben unverändert. Solange der Prefix-Cache warm ist, wird der Schnitt höchstens nach jeweils 20 weiteren Nachrichten verschoben. Nach einer Stunde ohne Modellantwort darf er sofort nachziehen.
|
|
78
|
+
|
|
79
|
+
Dabei werden keine gespeicherten Nachrichten geändert oder gelöscht. Fortsetzen, Exportieren und die sichtbare Historie behalten die ursprünglichen Werkzeugergebnisse und Werkzeugargumente. Das Telemetrieereignis `micro_compaction_finished` nennt den Auslöser, den Schnitt und die geschätzte Tokenzahl vor und nach der Entlastung. Außerdem zählt es getrennt, wie viele Werkzeugergebnisse und Werkzeugargumente entlastet wurden. Der Sitzungsinspektor summiert zusätzlich die eingesparten Argument-Token, ohne Inhalte offenzulegen. Beispiel: Ein früherer `Write`-Aufruf mit einem vollständigen Dateiinhalt bleibt im Wire erhalten; die Modellprojektion trägt nur noch einen Platzhalter, sobald für diesen `Write`-Aufruf ein zugehöriges Ergebnis vorliegt.
|
|
88
80
|
|
|
89
81
|
## Große Werkzeugausgaben und isolierte Teilagenten
|
|
90
82
|
|
|
@@ -235,6 +227,13 @@ sodass auch kurze Schritte wie Rendern und Speichern in der Produktionskette
|
|
|
235
227
|
sichtbar sind. Aktualisierte Vorschaubilder werden erneuert; Medienpfade und
|
|
236
228
|
Webadressen sind als Terminalverweise anklickbar.
|
|
237
229
|
|
|
230
|
+
Gestufte Verdichtung für große Sitzungen
|
|
231
|
+
-----------------------------------------
|
|
232
|
+
|
|
233
|
+
Eine Vollverdichtung verwendet jetzt pro Zusammenfassungsstufe höchstens 64.000 geschätzte Eingabe-Token als Zielwert. Die feste Sicherheitsgrenze des aktiven Modells bleibt unverändert. King teilt den älteren Verlauf an gültigen Nachrichtengrenzen, fasst jeden chronologischen Abschnitt zusammen und übernimmt diese Zusammenfassung in die nächste Stufe. Dabei wird kein noch nicht zusammengefasster Verlauf verworfen. Ist eine einzelne unteilbare Nachricht größer als der Stufenzielwert, bleibt die bestehende feste Sicherheitsgrenze der Rückfallweg.
|
|
234
|
+
|
|
235
|
+
Beispiel: Ein auf 256.000 Token geschätzter Verdichtungsauftrag wird in mehreren kleineren Stufen verarbeitet, statt als eine einzige große Anbieteranfrage. Die genaue Stufenzahl hängt von den Nachrichtengrenzen und den erzeugten Zwischenzusammenfassungen ab. Der Protokolleintrag `compaction stage request` nennt `targetInputTokens`; das Telemetrieereignis `compaction_finished` nennt `stage_count`. Das private Verlaufsarchiv und der ursprüngliche Sitzungs-Wire bleiben vollständig.
|
|
236
|
+
|
|
238
237
|
Wiederauffindbarer Verdichtungsverlauf
|
|
239
238
|
--------------------------------------
|
|
240
239
|
|
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.84
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Reproduzierbares Staging und Packen
|
|
@@ -96,17 +96,9 @@ doppelten Namen bleiben unverändert.
|
|
|
96
96
|
|
|
97
97
|
## Kontextentlastung bei langen Sitzungen
|
|
98
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.
|
|
99
|
+
King bewahrt den vollständigen Verlauf weiterhin im Sitzungs-Wire auf. Erreicht der aktive Verlauf 75 Prozent des Modellfensters, ersetzt die Modellprojektion ältere große Werkzeugergebnisse sowie große Argumente abgeschlossener Werkzeugaufrufe durch kurze Platzhalter. Werkzeugargumente werden nur entlastet, wenn ein zugehöriges Werkzeugergebnis vorliegt und die gespeicherten Argumente gültiges JSON sind. Die letzten 20 Nachrichten bleiben unverändert. Solange der Prefix-Cache warm ist, wird der Schnitt höchstens nach jeweils 20 weiteren Nachrichten verschoben. Nach einer Stunde ohne Modellantwort darf er sofort nachziehen.
|
|
105
100
|
|
|
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.
|
|
101
|
+
Dabei werden keine gespeicherten Nachrichten geändert oder gelöscht. Fortsetzen, Exportieren und die sichtbare Historie behalten die ursprünglichen Werkzeugergebnisse und Werkzeugargumente. Das Telemetrieereignis `micro_compaction_finished` nennt den Auslöser, den Schnitt und die geschätzte Tokenzahl vor und nach der Entlastung. Außerdem zählt es getrennt, wie viele Werkzeugergebnisse und Werkzeugargumente entlastet wurden. Der Sitzungsinspektor summiert zusätzlich die eingesparten Argument-Token, ohne Inhalte offenzulegen. Beispiel: Ein früherer `Write`-Aufruf mit einem vollständigen Dateiinhalt bleibt im Wire erhalten; die Modellprojektion trägt nur noch einen Platzhalter, sobald für diesen `Write`-Aufruf ein zugehöriges Ergebnis vorliegt.
|
|
110
102
|
|
|
111
103
|
## Große Werkzeugausgaben und isolierte Teilagenten
|
|
112
104
|
|
|
@@ -263,6 +255,12 @@ sodass auch kurze Schritte wie Rendern und Speichern in der Produktionskette
|
|
|
263
255
|
sichtbar sind. Aktualisierte Vorschaubilder werden erneuert; Medienpfade und
|
|
264
256
|
Webadressen sind als Terminalverweise anklickbar.
|
|
265
257
|
|
|
258
|
+
## Gestufte Verdichtung für große Sitzungen
|
|
259
|
+
|
|
260
|
+
Eine Vollverdichtung verwendet jetzt pro Zusammenfassungsstufe höchstens 64.000 geschätzte Eingabe-Token als Zielwert. Die feste Sicherheitsgrenze des aktiven Modells bleibt unverändert. King teilt den älteren Verlauf an gültigen Nachrichtengrenzen, fasst jeden chronologischen Abschnitt zusammen und übernimmt diese Zusammenfassung in die nächste Stufe. Dabei wird kein noch nicht zusammengefasster Verlauf verworfen. Ist eine einzelne unteilbare Nachricht größer als der Stufenzielwert, bleibt die bestehende feste Sicherheitsgrenze der Rückfallweg.
|
|
261
|
+
|
|
262
|
+
Beispiel: Ein auf 256.000 Token geschätzter Verdichtungsauftrag wird in mehreren kleineren Stufen verarbeitet, statt als eine einzige große Anbieteranfrage. Die genaue Stufenzahl hängt von den Nachrichtengrenzen und den erzeugten Zwischenzusammenfassungen ab. Der Protokolleintrag `compaction stage request` nennt `targetInputTokens`; das Telemetrieereignis `compaction_finished` nennt `stage_count`. Das private Verlaufsarchiv und der ursprüngliche Sitzungs-Wire bleiben vollständig.
|
|
263
|
+
|
|
266
264
|
## Wiederauffindbarer Verdichtungsverlauf
|
|
267
265
|
|
|
268
266
|
Bevor eine erfolgreiche Vollverdichtung ältere Nachrichten ersetzt, schreibt King den verdrängten Verlauf in ein privates Markdown-Archiv unter `~/.blun/conversation-history/`. Die Verdichtungszusammenfassung enthält den genauen `history_path`, sodass der Agent mit `Read` Einzelheiten wiederfinden kann, die nicht in der Zusammenfassung stehen.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const DEFAULT_COMPACTION_STAGE_MAX_TOKENS = 64_000;
|
|
4
|
+
|
|
5
|
+
function capCompactionStageTarget(safeRequestLimitTokens) {
|
|
6
|
+
if (!Number.isFinite(safeRequestLimitTokens) || safeRequestLimitTokens <= 0) return 0;
|
|
7
|
+
return Math.min(Math.floor(safeRequestLimitTokens), DEFAULT_COMPACTION_STAGE_MAX_TOKENS);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
DEFAULT_COMPACTION_STAGE_MAX_TOKENS,
|
|
12
|
+
capCompactionStageTarget,
|
|
13
|
+
};
|
package/blun.mjs
CHANGED
|
@@ -75237,9 +75237,10 @@ function extractCompactionSummary(response) {
|
|
|
75237
75237
|
if (summary.trim().length === 0) throw new APIEmptyResponseError("The compaction response did not contain a non-empty summary.");
|
|
75238
75238
|
return summary;
|
|
75239
75239
|
}
|
|
75240
|
-
var archiveCompactionHistory, buildCompactionArchiveNotice, DEFAULT_COMPACTION_MAX_COMPLETION_TOKENS, COMPACTION_THINKING_EFFORT, COMPACTION_SUMMARY_RESERVE_RATIO, MAX_HIERARCHICAL_COMPACTION_PASSES, HIERARCHICAL_COMPACTION_PREFIX, CompactionTruncatedError, CompactionStallError, COMPACTION_STALL_MEASUREMENT_MULTIPLIER, REBUILT_AFTER_COMPACTION_INJECTION_VARIANTS, FullCompaction, MAX_COMPACTION_OVERFLOW_SHRINK_ATTEMPTS, COMPACTION_OVERFLOW_SHRINK_RATIOS;
|
|
75240
|
+
var archiveCompactionHistory, buildCompactionArchiveNotice, capCompactionStageTarget, DEFAULT_COMPACTION_MAX_COMPLETION_TOKENS, COMPACTION_THINKING_EFFORT, COMPACTION_SUMMARY_RESERVE_RATIO, MAX_HIERARCHICAL_COMPACTION_PASSES, HIERARCHICAL_COMPACTION_PREFIX, CompactionTruncatedError, CompactionStallError, COMPACTION_STALL_MEASUREMENT_MULTIPLIER, REBUILT_AFTER_COMPACTION_INJECTION_VARIANTS, FullCompaction, MAX_COMPACTION_OVERFLOW_SHRINK_ATTEMPTS, COMPACTION_OVERFLOW_SHRINK_RATIOS;
|
|
75241
75241
|
var init_full = __esmMin((() => {
|
|
75242
75242
|
({ archiveCompactionHistory, buildCompactionArchiveNotice } = createRequire(import.meta.url)("./bin/compaction-history-archive.cjs"));
|
|
75243
|
+
({ capCompactionStageTarget } = createRequire(import.meta.url)("./bin/compaction-stage-policy.cjs"));
|
|
75243
75244
|
init_errors$8();
|
|
75244
75245
|
init_src$4();
|
|
75245
75246
|
init_errors$4();
|
|
@@ -75578,14 +75579,15 @@ var init_full = __esmMin((() => {
|
|
|
75578
75579
|
while (true) {
|
|
75579
75580
|
const compactionRequestLimit = this.getEffectiveMaxContextTokens();
|
|
75580
75581
|
const safeCompactionRequestLimit = compactionRequestLimit > 0 ? Math.max(1, Math.floor(compactionRequestLimit * (1 - COMPACTION_SUMMARY_RESERVE_RATIO))) : compactionRequestLimit;
|
|
75582
|
+
const targetCompactionRequestLimit = capCompactionStageTarget(safeCompactionRequestLimit);
|
|
75581
75583
|
let messages = buildRequestMessages(historyForModel, instruction);
|
|
75582
75584
|
let estimatedCompactionRequestTokens = this.estimateRequestTokens(messages, this.agent.effectiveSystemPrompt, compactionTools);
|
|
75583
75585
|
initialCompactionRequestTokens ??= estimatedCompactionRequestTokens;
|
|
75584
75586
|
let hierarchicalChunkEnd;
|
|
75585
|
-
if (
|
|
75587
|
+
if (targetCompactionRequestLimit > 0 && estimatedCompactionRequestTokens >= targetCompactionRequestLimit) {
|
|
75586
75588
|
if (historyForModel.length > 1) {
|
|
75587
75589
|
const chunkInstruction = `${instruction}\n\nThis request contains only the oldest chronological segment. Summarize every fact needed by a later merge pass. Do not assume later messages are visible.`;
|
|
75588
|
-
const chunk = selectHierarchicalCompactionChunk(historyForModel,
|
|
75590
|
+
const chunk = selectHierarchicalCompactionChunk(historyForModel, targetCompactionRequestLimit, safeCompactionRequestLimit, (candidate) => {
|
|
75589
75591
|
const candidateMessages = buildRequestMessages(candidate, chunkInstruction);
|
|
75590
75592
|
return {
|
|
75591
75593
|
messages: candidateMessages,
|
|
@@ -75598,7 +75600,7 @@ var init_full = __esmMin((() => {
|
|
|
75598
75600
|
estimatedCompactionRequestTokens = chunk.estimatedTokens;
|
|
75599
75601
|
}
|
|
75600
75602
|
}
|
|
75601
|
-
if (hierarchicalChunkEnd === void 0) throw new BlunError(ErrorCodes.CONTEXT_OVERFLOW, `Compaction stopped before upload: the conversation (${String(tokensBefore)} tokens) could not be divided into a request below the active model window (${String(compactionRequestLimit)} tokens).`, { details: {
|
|
75603
|
+
if (hierarchicalChunkEnd === void 0 && estimatedCompactionRequestTokens >= safeCompactionRequestLimit) throw new BlunError(ErrorCodes.CONTEXT_OVERFLOW, `Compaction stopped before upload: the conversation (${String(tokensBefore)} tokens) could not be divided into a request below the active model window (${String(compactionRequestLimit)} tokens).`, { details: {
|
|
75602
75604
|
contextBrakeBlocked: true,
|
|
75603
75605
|
estimatedRequestTokens: estimatedCompactionRequestTokens,
|
|
75604
75606
|
maxContextTokens: compactionRequestLimit,
|
|
@@ -75623,6 +75625,7 @@ var init_full = __esmMin((() => {
|
|
|
75623
75625
|
activeContextTokens: this.estimateProjectedRequestTokens(),
|
|
75624
75626
|
estimatedInputTokens: estimatedCompactionRequestTokens,
|
|
75625
75627
|
windowUsagePercent,
|
|
75628
|
+
targetInputTokens: targetCompactionRequestLimit,
|
|
75626
75629
|
safeInputLimitTokens: safeCompactionRequestLimit,
|
|
75627
75630
|
maxContextTokens: compactionRequestLimit
|
|
75628
75631
|
});
|
|
@@ -75809,6 +75812,7 @@ var init_full = __esmMin((() => {
|
|
|
75809
75812
|
retry_count: retryCount,
|
|
75810
75813
|
round: 1,
|
|
75811
75814
|
thinking_effort: COMPACTION_THINKING_EFFORT,
|
|
75815
|
+
stage_count: hierarchicalPassCount + 1,
|
|
75812
75816
|
...usage === null ? {} : {
|
|
75813
75817
|
input_tokens: inputTotal(usage),
|
|
75814
75818
|
output_tokens: usage.output
|
|
@@ -75916,6 +75920,7 @@ var init_micro = __esmMin((() => {
|
|
|
75916
75920
|
minContentTokens: 100,
|
|
75917
75921
|
cacheMissedThresholdMs: 3600 * 1e3,
|
|
75918
75922
|
truncatedMarker: "[Old tool result content cleared]",
|
|
75923
|
+
truncatedArgumentsMarker: "[Old tool call arguments cleared]",
|
|
75919
75924
|
minContextUsageRatio: .5
|
|
75920
75925
|
};
|
|
75921
75926
|
MicroCompaction = class {
|
|
@@ -75959,22 +75964,26 @@ var init_micro = __esmMin((() => {
|
|
|
75959
75964
|
const previousCutoff = this.cutoff;
|
|
75960
75965
|
const effect = this.measureEffect(history, selection.cutoff);
|
|
75961
75966
|
const previousEffect = this.measureEffect(history, previousCutoff);
|
|
75962
|
-
if (effect.truncatedToolResultCount <= previousEffect.truncatedToolResultCount) return;
|
|
75967
|
+
if (effect.truncatedToolResultCount <= previousEffect.truncatedToolResultCount && effect.truncatedToolArgumentCount <= previousEffect.truncatedToolArgumentCount) return;
|
|
75963
75968
|
this.apply(selection.cutoff);
|
|
75964
75969
|
const rawContextTokens = estimateTokensForMessages(history);
|
|
75965
|
-
const tokensBefore = rawContextTokens - previousEffect.truncatedToolResultTokensBefore + previousEffect.truncatedToolResultTokensAfter;
|
|
75966
|
-
const tokensAfter = rawContextTokens - effect.truncatedToolResultTokensBefore + effect.truncatedToolResultTokensAfter;
|
|
75970
|
+
const tokensBefore = rawContextTokens - previousEffect.truncatedToolResultTokensBefore + previousEffect.truncatedToolResultTokensAfter - previousEffect.truncatedToolArgumentTokensBefore + previousEffect.truncatedToolArgumentTokensAfter;
|
|
75971
|
+
const tokensAfter = rawContextTokens - effect.truncatedToolResultTokensBefore + effect.truncatedToolResultTokensAfter - effect.truncatedToolArgumentTokensBefore + effect.truncatedToolArgumentTokensAfter;
|
|
75967
75972
|
this.agent.telemetry.track("micro_compaction_finished", {
|
|
75968
75973
|
trigger: selection.trigger,
|
|
75969
75974
|
keep_recent_messages: config.keepRecentMessages,
|
|
75970
75975
|
min_content_tokens: config.minContentTokens,
|
|
75971
75976
|
cache_missed_threshold_ms: config.cacheMissedThresholdMs,
|
|
75972
75977
|
truncated_marker: config.truncatedMarker,
|
|
75978
|
+
truncated_arguments_marker: config.truncatedArgumentsMarker,
|
|
75973
75979
|
min_context_usage_ratio: config.minContextUsageRatio,
|
|
75974
75980
|
context_usage_ratio: selection.contextUsageRatio,
|
|
75975
75981
|
truncated_tool_result_count: effect.truncatedToolResultCount,
|
|
75976
75982
|
truncated_tool_result_tokens_before: effect.truncatedToolResultTokensBefore,
|
|
75977
75983
|
truncated_tool_result_tokens_after: effect.truncatedToolResultTokensAfter,
|
|
75984
|
+
truncated_tool_argument_count: effect.truncatedToolArgumentCount,
|
|
75985
|
+
truncated_tool_argument_tokens_before: effect.truncatedToolArgumentTokensBefore,
|
|
75986
|
+
truncated_tool_argument_tokens_after: effect.truncatedToolArgumentTokensAfter,
|
|
75978
75987
|
tokens_before: tokensBefore,
|
|
75979
75988
|
tokens_after: tokensAfter,
|
|
75980
75989
|
previous_cutoff: previousCutoff,
|
|
@@ -75986,6 +75995,8 @@ var init_micro = __esmMin((() => {
|
|
|
75986
75995
|
}
|
|
75987
75996
|
compact(messages) {
|
|
75988
75997
|
const config = this.config;
|
|
75998
|
+
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
75999
|
+
const serializedArgumentsMarker = JSON.stringify({ _blun_compacted: config.truncatedArgumentsMarker });
|
|
75989
76000
|
const result = [];
|
|
75990
76001
|
let i = 0;
|
|
75991
76002
|
for (const msg of messages) {
|
|
@@ -75996,6 +76007,26 @@ var init_micro = __esmMin((() => {
|
|
|
75996
76007
|
text: config.truncatedMarker
|
|
75997
76008
|
}]
|
|
75998
76009
|
});
|
|
76010
|
+
else if (i < this.cutoff && msg.role === "assistant" && Array.isArray(msg.toolCalls)) {
|
|
76011
|
+
let changed = false;
|
|
76012
|
+
const toolCalls = msg.toolCalls.map((call) => {
|
|
76013
|
+
if (!completedToolCallIds.has(call.id) || typeof call.arguments !== "string" || this.toolArgumentTokens(call.arguments) < config.minContentTokens) return call;
|
|
76014
|
+
try {
|
|
76015
|
+
JSON.parse(call.arguments);
|
|
76016
|
+
} catch {
|
|
76017
|
+
return call;
|
|
76018
|
+
}
|
|
76019
|
+
changed = true;
|
|
76020
|
+
return {
|
|
76021
|
+
...call,
|
|
76022
|
+
arguments: serializedArgumentsMarker
|
|
76023
|
+
};
|
|
76024
|
+
});
|
|
76025
|
+
result.push(changed ? {
|
|
76026
|
+
...msg,
|
|
76027
|
+
toolCalls
|
|
76028
|
+
} : msg);
|
|
76029
|
+
}
|
|
75999
76030
|
else result.push(msg);
|
|
76000
76031
|
i++;
|
|
76001
76032
|
}
|
|
@@ -76003,28 +76034,70 @@ var init_micro = __esmMin((() => {
|
|
|
76003
76034
|
}
|
|
76004
76035
|
measureEffect(messages, cutoff) {
|
|
76005
76036
|
let markerTokenCount;
|
|
76037
|
+
let argumentsMarkerTokenCount;
|
|
76006
76038
|
let truncatedToolResultCount = 0;
|
|
76007
76039
|
let truncatedToolResultTokensBefore = 0;
|
|
76008
76040
|
let truncatedToolResultTokensAfter = 0;
|
|
76041
|
+
let truncatedToolArgumentCount = 0;
|
|
76042
|
+
let truncatedToolArgumentTokensBefore = 0;
|
|
76043
|
+
let truncatedToolArgumentTokensAfter = 0;
|
|
76044
|
+
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
76045
|
+
const serializedArgumentsMarker = JSON.stringify({ _blun_compacted: this.config.truncatedArgumentsMarker });
|
|
76009
76046
|
for (let i = 0; i < messages.length && i < cutoff; i++) {
|
|
76010
76047
|
const message = messages[i];
|
|
76011
|
-
if (message?.role
|
|
76012
|
-
|
|
76013
|
-
|
|
76014
|
-
|
|
76015
|
-
|
|
76016
|
-
|
|
76017
|
-
|
|
76018
|
-
|
|
76019
|
-
|
|
76020
|
-
|
|
76048
|
+
if (message?.role === "tool" && message.toolCallId !== void 0) {
|
|
76049
|
+
const contentTokens = estimateTokensForContentParts(message.content);
|
|
76050
|
+
if (contentTokens >= this.config.minContentTokens) {
|
|
76051
|
+
markerTokenCount ??= estimateTokensForContentParts([{
|
|
76052
|
+
type: "text",
|
|
76053
|
+
text: this.config.truncatedMarker
|
|
76054
|
+
}]);
|
|
76055
|
+
truncatedToolResultCount += 1;
|
|
76056
|
+
truncatedToolResultTokensBefore += contentTokens;
|
|
76057
|
+
truncatedToolResultTokensAfter += markerTokenCount;
|
|
76058
|
+
}
|
|
76059
|
+
}
|
|
76060
|
+
if (message?.role !== "assistant" || !Array.isArray(message.toolCalls)) continue;
|
|
76061
|
+
for (const call of message.toolCalls) {
|
|
76062
|
+
if (!completedToolCallIds.has(call.id) || typeof call.arguments !== "string") continue;
|
|
76063
|
+
try {
|
|
76064
|
+
JSON.parse(call.arguments);
|
|
76065
|
+
} catch {
|
|
76066
|
+
continue;
|
|
76067
|
+
}
|
|
76068
|
+
const argumentTokens = this.toolArgumentTokens(call.arguments);
|
|
76069
|
+
if (argumentTokens < this.config.minContentTokens) continue;
|
|
76070
|
+
argumentsMarkerTokenCount ??= this.toolArgumentTokens(serializedArgumentsMarker);
|
|
76071
|
+
truncatedToolArgumentCount += 1;
|
|
76072
|
+
truncatedToolArgumentTokensBefore += argumentTokens;
|
|
76073
|
+
truncatedToolArgumentTokensAfter += argumentsMarkerTokenCount;
|
|
76074
|
+
}
|
|
76021
76075
|
}
|
|
76022
76076
|
return {
|
|
76023
76077
|
truncatedToolResultCount,
|
|
76024
76078
|
truncatedToolResultTokensBefore,
|
|
76025
|
-
truncatedToolResultTokensAfter
|
|
76079
|
+
truncatedToolResultTokensAfter,
|
|
76080
|
+
truncatedToolArgumentCount,
|
|
76081
|
+
truncatedToolArgumentTokensBefore,
|
|
76082
|
+
truncatedToolArgumentTokensAfter
|
|
76026
76083
|
};
|
|
76027
76084
|
}
|
|
76085
|
+
toolArgumentTokens(argumentsValue) {
|
|
76086
|
+
return estimateTokensForMessages([{
|
|
76087
|
+
role: "assistant",
|
|
76088
|
+
content: [],
|
|
76089
|
+
toolCalls: [{
|
|
76090
|
+
type: "function",
|
|
76091
|
+
id: "",
|
|
76092
|
+
name: "",
|
|
76093
|
+
arguments: argumentsValue
|
|
76094
|
+
}]
|
|
76095
|
+
}]) - estimateTokensForMessages([{
|
|
76096
|
+
role: "assistant",
|
|
76097
|
+
content: [],
|
|
76098
|
+
toolCalls: []
|
|
76099
|
+
}]);
|
|
76100
|
+
}
|
|
76028
76101
|
};
|
|
76029
76102
|
}));
|
|
76030
76103
|
//#endregion
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ compatibility: designed for BLUN Code
|
|
|
9
9
|
|
|
10
10
|
Use the bundled script instead of manually reading `wire.jsonl` or telemetry files. It reports counts and timing metadata without returning prompts, system instructions, tool arguments, tool results, private paths, or hidden reasoning.
|
|
11
11
|
|
|
12
|
-
In addition to wire and telemetry counts, the summary reads only structured `turn request tools` fields from the session's own BLUN log. It reports eligible, selected, and deferred schema counts, estimated schema tokens avoided, and suppression reasons. Other log lines are ignored and never emitted.
|
|
12
|
+
In addition to wire and telemetry counts, the summary reads only structured `turn request tools` fields from the session's own BLUN log. It reports eligible, selected, and deferred schema counts, estimated schema tokens avoided, and suppression reasons. Micro-compaction telemetry also reports how many completed tool-call arguments were relieved and the estimated argument tokens saved. Argument contents are never returned. Other log lines are ignored and never emitted.
|
|
13
13
|
|
|
14
14
|
Resolve `SKILL_DIR` to the directory containing this file. Do not assume a user-specific installation path.
|
|
15
15
|
|
|
@@ -278,6 +278,8 @@ async function summarizeTelemetry(telemetryDir, sessionId, warnings) {
|
|
|
278
278
|
offloaded_tool_results: 0,
|
|
279
279
|
offloaded_output_chars: 0,
|
|
280
280
|
truncated_tool_results: 0,
|
|
281
|
+
truncated_tool_arguments: 0,
|
|
282
|
+
truncated_tool_argument_tokens_saved: 0,
|
|
281
283
|
};
|
|
282
284
|
if (!fs.existsSync(telemetryDir)) return summary;
|
|
283
285
|
|
|
@@ -290,6 +292,10 @@ async function summarizeTelemetry(telemetryDir, sessionId, warnings) {
|
|
|
290
292
|
if (record.event === 'micro_compaction_finished') {
|
|
291
293
|
summary.micro_compactions += 1;
|
|
292
294
|
summary.truncated_tool_results += numberValue(record.properties?.truncated_tool_result_count);
|
|
295
|
+
summary.truncated_tool_arguments += numberValue(record.properties?.truncated_tool_argument_count);
|
|
296
|
+
summary.truncated_tool_argument_tokens_saved += Math.max(0,
|
|
297
|
+
numberValue(record.properties?.truncated_tool_argument_tokens_before)
|
|
298
|
+
- numberValue(record.properties?.truncated_tool_argument_tokens_after));
|
|
293
299
|
} else if (record.event === 'compaction_failed') {
|
|
294
300
|
summary.full_compaction_failures += 1;
|
|
295
301
|
} else if (record.event === 'tool_result_offloaded') {
|