blun-king-cli 9.1.77 → 9.1.78
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 -0
- package/README.md +6 -0
- package/bin/compaction-history-archive.cjs +112 -0
- package/blun.mjs +20 -2
- package/package.json +1 -1
package/LIESMICH.txt
CHANGED
|
@@ -213,6 +213,21 @@ sodass auch kurze Schritte wie Rendern und Speichern in der Produktionskette
|
|
|
213
213
|
sichtbar sind. Aktualisierte Vorschaubilder werden erneuert; Medienpfade und
|
|
214
214
|
Webadressen sind als Terminalverweise anklickbar.
|
|
215
215
|
|
|
216
|
+
Wiederauffindbarer Verdichtungsverlauf
|
|
217
|
+
--------------------------------------
|
|
218
|
+
|
|
219
|
+
Bevor eine erfolgreiche Vollverdichtung ältere Nachrichten ersetzt, schreibt
|
|
220
|
+
King den verdrängten Verlauf in ein privates Markdown-Archiv unter
|
|
221
|
+
~/.blun/conversation-history/. Die Verdichtungszusammenfassung enthält den
|
|
222
|
+
genauen history_path, sodass der Agent mit Read Einzelheiten wiederfinden kann,
|
|
223
|
+
die nicht in der Zusammenfassung stehen.
|
|
224
|
+
|
|
225
|
+
Eingebettete Bild-, Audio- und Videodaten werden im Archiv nicht doppelt
|
|
226
|
+
gespeichert. Der ursprüngliche Sitzungs-Wire bleibt maßgeblich. Kann das Archiv
|
|
227
|
+
nicht geschrieben werden, protokolliert King compaction_history_archive_failed
|
|
228
|
+
und lässt den normalen Verdichtungsweg verfügbar; ein Archivfehler löscht
|
|
229
|
+
niemals den gespeicherten Sitzungsverlauf.
|
|
230
|
+
|
|
216
231
|
Aktualisieren
|
|
217
232
|
-------------
|
|
218
233
|
|
package/README.md
CHANGED
|
@@ -240,6 +240,12 @@ sodass auch kurze Schritte wie Rendern und Speichern in der Produktionskette
|
|
|
240
240
|
sichtbar sind. Aktualisierte Vorschaubilder werden erneuert; Medienpfade und
|
|
241
241
|
Webadressen sind als Terminalverweise anklickbar.
|
|
242
242
|
|
|
243
|
+
## Wiederauffindbarer Verdichtungsverlauf
|
|
244
|
+
|
|
245
|
+
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.
|
|
246
|
+
|
|
247
|
+
Eingebettete Bild-, Audio- und Videodaten werden im Archiv nicht doppelt gespeichert. Der ursprüngliche Sitzungs-Wire bleibt maßgeblich. Kann das Archiv nicht geschrieben werden, protokolliert King `compaction_history_archive_failed` und lässt den normalen Verdichtungsweg verfügbar; ein Archivfehler löscht niemals den gespeicherten Sitzungsverlauf.
|
|
248
|
+
|
|
243
249
|
## Aktualisieren
|
|
244
250
|
|
|
245
251
|
`blun update`, `king update` und die jeweilige Variante `upgrade` verwenden
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { randomUUID } = require('node:crypto');
|
|
4
|
+
const { mkdir, writeFile } = require('node:fs/promises');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
|
|
7
|
+
const COMPACTION_HISTORY_DIR = 'conversation-history';
|
|
8
|
+
const INLINE_MEDIA_NOTICE = '[inline media payload omitted; original remains in session wire]';
|
|
9
|
+
|
|
10
|
+
async function archiveCompactionHistory(options = {}) {
|
|
11
|
+
const homedir = requiredString(options.homedir, 'homedir');
|
|
12
|
+
const messages = Array.isArray(options.messages) ? options.messages : [];
|
|
13
|
+
const now = finiteNumber(options.now, Date.now());
|
|
14
|
+
const id = safeFilePart(options.id || randomUUID());
|
|
15
|
+
const dir = path.join(homedir, COMPACTION_HISTORY_DIR);
|
|
16
|
+
const timestamp = new Date(now).toISOString().replace(/[:.]/g, '-');
|
|
17
|
+
const outputPath = path.join(dir, `compaction-${timestamp}-${id}.md`);
|
|
18
|
+
|
|
19
|
+
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
20
|
+
await writeFile(outputPath, serializeCompactionHistory(messages, { now }), {
|
|
21
|
+
encoding: 'utf8',
|
|
22
|
+
flag: 'wx',
|
|
23
|
+
mode: 0o600,
|
|
24
|
+
});
|
|
25
|
+
return outputPath;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function serializeCompactionHistory(messages, options = {}) {
|
|
29
|
+
const now = finiteNumber(options.now, Date.now());
|
|
30
|
+
const lines = [
|
|
31
|
+
'# BLUN conversation history archive',
|
|
32
|
+
'',
|
|
33
|
+
`Archived at: ${new Date(now).toISOString()}`,
|
|
34
|
+
`Messages: ${messages.length}`,
|
|
35
|
+
'',
|
|
36
|
+
'This file contains the messages displaced by a full context compaction.',
|
|
37
|
+
'Inline media payloads are omitted here; the original session wire remains authoritative.',
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
for (let index = 0; index < messages.length; index += 1) {
|
|
41
|
+
const message = sanitizeMessage(messages[index]);
|
|
42
|
+
lines.push(
|
|
43
|
+
'',
|
|
44
|
+
`## Message ${index + 1}: ${typeof message?.role === 'string' ? message.role : 'unknown'}`,
|
|
45
|
+
'',
|
|
46
|
+
'```json',
|
|
47
|
+
JSON.stringify(message, null, 2),
|
|
48
|
+
'```',
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
lines.push('');
|
|
52
|
+
return lines.join('\n');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function buildCompactionArchiveNotice(historyPath) {
|
|
56
|
+
return [
|
|
57
|
+
'<system-reminder>',
|
|
58
|
+
'The complete messages displaced by this compaction were archived locally.',
|
|
59
|
+
`history_path: ${historyPath}`,
|
|
60
|
+
'next_step: Use Read with history_path to recover exact details that the summary omitted.',
|
|
61
|
+
'</system-reminder>',
|
|
62
|
+
].join('\n');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function sanitizeMessage(message) {
|
|
66
|
+
if (message === null || typeof message !== 'object') return message;
|
|
67
|
+
if (!Array.isArray(message.content)) return message;
|
|
68
|
+
return {
|
|
69
|
+
...message,
|
|
70
|
+
content: message.content.map(sanitizeContentPart),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function sanitizeContentPart(part) {
|
|
75
|
+
if (part === null || typeof part !== 'object') return part;
|
|
76
|
+
if (part.type === 'image_url' && isInlineMediaUrl(part.imageUrl?.url)) {
|
|
77
|
+
return { type: 'text', text: INLINE_MEDIA_NOTICE };
|
|
78
|
+
}
|
|
79
|
+
if (part.type === 'audio_url' && isInlineMediaUrl(part.audioUrl?.url)) {
|
|
80
|
+
return { type: 'text', text: INLINE_MEDIA_NOTICE };
|
|
81
|
+
}
|
|
82
|
+
if (part.type === 'video_url' && isInlineMediaUrl(part.videoUrl?.url)) {
|
|
83
|
+
return { type: 'text', text: INLINE_MEDIA_NOTICE };
|
|
84
|
+
}
|
|
85
|
+
return part;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function isInlineMediaUrl(value) {
|
|
89
|
+
return typeof value === 'string' && /^data:(?:image|audio|video)\//i.test(value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function requiredString(value, name) {
|
|
93
|
+
if (typeof value === 'string' && value.length > 0) return value;
|
|
94
|
+
throw new TypeError(`${name} must be a non-empty string`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function safeFilePart(value) {
|
|
98
|
+
const cleaned = String(value).replace(/[^a-zA-Z0-9._-]+/g, '_').replace(/^_+|_+$/g, '').slice(0, 96);
|
|
99
|
+
return cleaned || randomUUID();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function finiteNumber(value, fallback) {
|
|
103
|
+
const number = Number(value);
|
|
104
|
+
return Number.isFinite(number) ? number : fallback;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = {
|
|
108
|
+
COMPACTION_HISTORY_DIR,
|
|
109
|
+
archiveCompactionHistory,
|
|
110
|
+
buildCompactionArchiveNotice,
|
|
111
|
+
serializeCompactionHistory,
|
|
112
|
+
};
|
package/blun.mjs
CHANGED
|
@@ -75237,8 +75237,9 @@ 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 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, 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
|
+
({ archiveCompactionHistory, buildCompactionArchiveNotice } = createRequire(import.meta.url)("./bin/compaction-history-archive.cjs"));
|
|
75242
75243
|
init_errors$8();
|
|
75243
75244
|
init_src$4();
|
|
75244
75245
|
init_errors$4();
|
|
@@ -75773,7 +75774,24 @@ var init_full = __esmMin((() => {
|
|
|
75773
75774
|
return;
|
|
75774
75775
|
}
|
|
75775
75776
|
const rawSummary = this.postProcessSummary(summary ?? "");
|
|
75776
|
-
|
|
75777
|
+
let contextSummary = buildCompactionSummaryText(rawSummary);
|
|
75778
|
+
let historyPath;
|
|
75779
|
+
try {
|
|
75780
|
+
historyPath = await archiveCompactionHistory({
|
|
75781
|
+
homedir: this.agent.blunHomeDir,
|
|
75782
|
+
messages: originalHistory
|
|
75783
|
+
});
|
|
75784
|
+
contextSummary = `${contextSummary}\n\n${buildCompactionArchiveNotice(historyPath)}`;
|
|
75785
|
+
this.agent.telemetry.track("compaction_history_archived", {
|
|
75786
|
+
history_path: historyPath,
|
|
75787
|
+
message_count: originalHistory.length
|
|
75788
|
+
});
|
|
75789
|
+
} catch (error) {
|
|
75790
|
+
this.agent.telemetry.track("compaction_history_archive_failed", {
|
|
75791
|
+
message_count: originalHistory.length,
|
|
75792
|
+
error_type: error instanceof Error ? error.name : "Unknown"
|
|
75793
|
+
});
|
|
75794
|
+
}
|
|
75777
75795
|
const result = this.agent.context.applyCompaction({
|
|
75778
75796
|
summary: rawSummary,
|
|
75779
75797
|
contextSummary,
|