blun-king-cli 9.1.613 → 9.1.615
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 +14 -0
- package/LIESMICH.txt +1 -1
- package/README.md +1 -1
- package/agent-spine-plugin/src/lib/documents.js +1 -1
- package/agent-spine-plugin/src/lib/hook-context.js +1 -0
- package/agent-spine-plugin/src/lib/host-instruction-budget.js +1 -2
- package/agent-spine-plugin/src/lib/preflight.js +16 -5
- package/agent-spine-plugin/src/lib/source-roots.js +1 -1
- package/blun.mjs +1927 -1011
- package/bundled-agent-sources.json +5 -5
- package/codebase-index/codebase_index.py +25 -17
- package/package.json +1 -1
- package/telegram-plugin/dist/bridge.mjs +1 -200
- package/telegram-plugin/dist/mcp-server.mjs +8 -4
- package/worker-host.mjs +1215 -600
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# BLUN King Changelog
|
|
2
2
|
|
|
3
|
+
## 9.1.615
|
|
4
|
+
|
|
5
|
+
Große Werkzeugkataloge laufen jetzt über Kings vorhandene Werkzeugsuche, statt alle optionalen Werkzeugschemata auf einmal an das Modell zu senden. Meldet der Anbieter ein kleineres Kontextfenster, passt King das Werkzeugbudget an. Neu gefundene Werkzeuge bleiben für den nächsten Schritt verfügbar. Bei der automatischen Auswahl liest King keine Parameterschemata noch nicht ausgewählter MCP-Werkzeuge; lokal registrierte Werkzeuge behalten ihre Parameterhinweise.
|
|
6
|
+
|
|
7
|
+
Bei kleineren wirksamen Kontextfenstern lagert King große Werkzeugergebnisse früher aus. Die vollständige Ausgabe bleibt über den vorhandenen Leseweg abrufbar, sofern er sie sicher wiedergeben kann.
|
|
8
|
+
|
|
9
|
+
Normale Telegram-Antworten und das Bearbeiten von Nachrichten brauchen keinen Sprachfreigabe-Beleg mehr. Gibst du einen Beleg mit, muss er genau zum gesendeten Text passen. Eine ausdrücklich konfigurierte Antwortprüfung und die Freigabe für veröffentlichte Übersetzungen bleiben bestehen.
|
|
10
|
+
|
|
11
|
+
Neue Anfragen an die lokale Codesuche protokollieren Metadaten statt des vollständigen Fragetexts. Bei wiederholten Modellaufrufen berücksichtigt King eine vom Anbieter vorgegebene Wartezeit; du kannst das Warten abbrechen.
|
|
12
|
+
|
|
13
|
+
## 9.1.614
|
|
14
|
+
|
|
15
|
+
- Zu große AGENTS.md- und AGENTS.override.md-Dateien stoppen einen Zug nicht mehr allein wegen ihrer Größe. Außerhalb der King-Konsole liest King insgesamt bis zu 32 KiB aus Anweisungsdateien und nennt dir einmal je Sitzung die Anzahl der ausgelassenen Bytes. In der King-Konsole bleiben die Dateien vollständig, solange die Anfragegrenze das zulässt. Verknüpfungen und unsichere Pfade bleiben gesperrt.
|
|
16
|
+
|
|
3
17
|
## 9.1.613
|
|
4
18
|
|
|
5
19
|
- King schätzt vor dem Senden nun die Größe der gesamten Modellanfrage, einschließlich Anweisungen, Verlauf, Werkzeugdefinitionen und Bilddaten. Nähert sie sich der Byte-Grenze des Servers, beginnt eine stufenweise Verdichtung. Lässt sich eine Anfrage nicht sicher aufteilen, bricht King ab, ohne den gespeicherten Verlauf stillschweigend zu verwerfen.
|
package/LIESMICH.txt
CHANGED
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ export async function indexExplicitDocuments(entries) {
|
|
|
86
86
|
if (!metadata.isFile() || metadata.isSymbolicLink()) throw new Error(`source is not a regular non-symlink file: ${entry.id}`);
|
|
87
87
|
buffer = await readFile(path);
|
|
88
88
|
}
|
|
89
|
-
if (buffer.byteLength > (entry.maxBytes ||
|
|
89
|
+
if (buffer.byteLength > (entry.maxBytes || 8 * 1024 * 1024)) throw new Error(`source exceeds its byte limit: ${entry.id}`);
|
|
90
90
|
const classification = classify(entry.id);
|
|
91
91
|
const document = {
|
|
92
92
|
path,
|
|
@@ -44,6 +44,7 @@ return null;
|
|
|
44
44
|
|
|
45
45
|
export function hostContextLimit(preflight) {
|
|
46
46
|
if (preflight?.receipt?.instructionHost === "codex") return 32768 + Buffer.byteLength(JSON.stringify(preflight.briefing || {}));
|
|
47
|
+
if (preflight?.briefing?.instructions?.length) return 32768 + Buffer.byteLength(JSON.stringify(preflight.briefing));
|
|
47
48
|
const mode = preflight?.receipt?.instructionBudget?.mode;
|
|
48
49
|
if (mode === "claude-required-overflow") return MAX_CLAUDE_OVERFLOW_CONTEXT_BYTES;
|
|
49
50
|
return STANDARD_HOST_CONTEXT_BYTES;
|
|
@@ -4,8 +4,7 @@ const KING_TOTAL = 8388608;
|
|
|
4
4
|
export const isKingHost = (env = process.env) => !!(env.BLUN_PLUGIN_ROOT && env.BLUN_HOME);
|
|
5
5
|
|
|
6
6
|
export function instructionBudget(host, usedBytes = 0, env = process.env) {
|
|
7
|
-
const hardLimitBytes =
|
|
8
|
-
: host === "claude" ? 16384 : host === "codex" ? 32768 : STANDARD;
|
|
7
|
+
const hardLimitBytes = KING_TOTAL;
|
|
9
8
|
return { mode: usedBytes > STANDARD ? `${host}-required-overflow` : "standard",
|
|
10
9
|
standardBytes: STANDARD, hardLimitBytes, usedBytes, overflowBytes: Math.max(0, usedBytes - STANDARD) };
|
|
11
10
|
}
|
|
@@ -497,11 +497,12 @@ export async function runPreflight({ input, scope, resolvedSources, prompt, now
|
|
|
497
497
|
let instructionBytes = 0;
|
|
498
498
|
const maximumInstructionBytes = instructionBudget(instructionHost, 0, env).hardLimitBytes;
|
|
499
499
|
const kingInstructions = instructionHost === "codex" && isKingHost(env);
|
|
500
|
+
const contentBudget = kingInstructions ? 900000 : 32768;
|
|
500
501
|
for (const document of documents) {
|
|
501
502
|
const allowedRoot = document.sourceScope === "user" ? resolvedSources.hostHome : resolvedSources.projectRoot;
|
|
502
|
-
const snapshot = await safeReadRequired(document.path, allowedRoot, maximumInstructionBytes, fileHooks,
|
|
503
|
+
const snapshot = await safeReadRequired(document.path, allowedRoot, maximumInstructionBytes, fileHooks, Math.max(0, contentBudget - instructionBytes));
|
|
503
504
|
if (snapshot.sha256 !== document.sha256 || snapshot.bytes !== document.bytes) throw new Error(`required instruction changed after source resolution: ${document.relativePath}`);
|
|
504
|
-
instructionBytes +=
|
|
505
|
+
instructionBytes += snapshot.readBytes;
|
|
505
506
|
if (instructionBytes > maximumInstructionBytes) {
|
|
506
507
|
throw new Error(`required host instructions total ${instructionBytes} bytes; mandatory limit is ${maximumInstructionBytes} bytes`);
|
|
507
508
|
}
|
|
@@ -564,7 +565,7 @@ export async function runPreflight({ input, scope, resolvedSources, prompt, now
|
|
|
564
565
|
const envelope = { receipt, consumedAt: null, invalidatedAt: null, stateSignature: "" };
|
|
565
566
|
envelope.stateSignature = createHmac("sha256", key).update(envelopeBody(envelope)).digest("hex");
|
|
566
567
|
state.receipts.push(envelope); state.revision += 1;
|
|
567
|
-
if (
|
|
568
|
+
if (requiredInstructions.length > 0) {
|
|
568
569
|
const notices = [];
|
|
569
570
|
for (const item of requiredInstructions.filter((instruction) => instruction.bytes > 8192)) {
|
|
570
571
|
const sessionDigest = sha256(`${exactScope.sessionId}\0${item.path}`);
|
|
@@ -572,6 +573,15 @@ export async function runPreflight({ input, scope, resolvedSources, prompt, now
|
|
|
572
573
|
state.history.push({ event: "instruction-notice", sessionDigest, at: createdAt, authority: "diagnostic-only" });
|
|
573
574
|
notices.push(`${item.displayPath}: ${item.bytes} bytes; ${item.readBytes} read; ${item.omittedBytes} omitted.`);
|
|
574
575
|
}
|
|
576
|
+
const totalBytes = requiredInstructions.reduce((sum, item) => sum + item.bytes, 0);
|
|
577
|
+
const omittedBytes = totalBytes - instructionBytes;
|
|
578
|
+
if (omittedBytes > 0) {
|
|
579
|
+
const totalDigest = sha256(`${exactScope.sessionId}\0instruction-total`);
|
|
580
|
+
if (!state.history.some((event) => event.event === "instruction-notice" && event.sessionDigest === totalDigest)) {
|
|
581
|
+
state.history.push({ event: "instruction-notice", sessionDigest: totalDigest, at: createdAt, authority: "diagnostic-only" });
|
|
582
|
+
notices.push(`Instruction total: ${totalBytes} bytes; ${instructionBytes} read; ${omittedBytes} omitted.`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
575
585
|
instructionNotice = notices.join("\n") || null;
|
|
576
586
|
}
|
|
577
587
|
state.lastTurn = { status: "ready", receiptId: receipt.id, at: createdAt, host: exactScope.host,
|
|
@@ -625,12 +635,13 @@ export async function verifyPreflightReceipt({ receipt, input, scope, resolvedSo
|
|
|
625
635
|
let instructionBytes = 0;
|
|
626
636
|
const maximumInstructionBytes = instructionBudget(receipt.instructionHost, 0, env).hardLimitBytes;
|
|
627
637
|
const kingInstructions = receipt.instructionHost === "codex" && isKingHost(env);
|
|
638
|
+
const contentBudget = kingInstructions ? 900000 : 32768;
|
|
628
639
|
for (const instruction of receipt.instructionFiles) {
|
|
629
640
|
const allowedRoot = instruction.scope === "user" ? freshSources.hostHome : freshSources.projectRoot;
|
|
630
|
-
const currentSnapshot = await safeReadRequired(instruction.path, allowedRoot, maximumInstructionBytes, null,
|
|
641
|
+
const currentSnapshot = await safeReadRequired(instruction.path, allowedRoot, maximumInstructionBytes, null, Math.max(0, contentBudget - instructionBytes));
|
|
631
642
|
if (currentSnapshot.sha256 !== instruction.sha256 || currentSnapshot.bytes !== instruction.bytes
|
|
632
643
|
|| currentSnapshot.identity !== instruction.identity) return false;
|
|
633
|
-
instructionBytes +=
|
|
644
|
+
instructionBytes += currentSnapshot.readBytes;
|
|
634
645
|
}
|
|
635
646
|
if (instructionBytes > maximumInstructionBytes
|
|
636
647
|
|| canonical(receipt.instructionBudget) !== canonical(instructionBudget(receipt.instructionHost, instructionBytes, env))) return false;
|
|
@@ -376,7 +376,7 @@ export async function resolveHostSourceCatalog({ host, cwd = process.cwd(), inpu
|
|
|
376
376
|
const codexHome = isKingHost(env) ? env.BLUN_HOME : env.CODEX_HOME || env.BLUN_HOME || join(homedir(), ".codex");
|
|
377
377
|
hostHome = await existingDirectory(resolve(codexHome)) || resolve(codexHome);
|
|
378
378
|
const config = await codexConfig(hostHome);
|
|
379
|
-
|
|
379
|
+
config.maxBytes = KING_SOURCE_BYTES;
|
|
380
380
|
if (env.AGENTSPINE_ROOT) projectRoot = await canonicalPath(env.AGENTSPINE_ROOT);
|
|
381
381
|
else ({ root: projectRoot, resolution: rootResolution } = await findRoot(canonicalCwd, config.rootMarkers));
|
|
382
382
|
sources = await codexSources({ cwd: canonicalCwd, projectRoot, codexHome: hostHome, config });
|