blun-king-cli 9.1.120 → 9.1.122

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
@@ -119,6 +119,10 @@ Ab BLUN King 9.1.119 enthält der bei jedem Modellschritt erneut gesendete Promp
119
119
 
120
120
  Ab BLUN King 9.1.120 lagert die Konsole auch große ältere Assistentenantworten aus dem aktiven Modellkontext in private Sitzungsdateien aus. Der vollständige Gesprächsverlauf bleibt erhalten; im Modellkontext verbleiben eine begrenzte Vorschau und der Dateipfad. Die 20 neuesten Nachrichten sowie Assistentenantworten mit Werkzeugaufrufen bleiben unverändert, damit laufende Arbeit und Aufrufketten vollständig verfügbar sind.
121
121
 
122
+ Ab BLUN King 9.1.121 begrenzt die Modellprojektion auch die Gesamtgröße älterer, mittelgroßer Werkzeugergebnisse, die ausschließlich Text enthalten. Überschreiten Werkzeugergebnisse außerhalb der letzten 20 Nachrichten zusammen 12.000 Zeichen, archiviert King so viele der größten geeigneten Ergebnisse wie nötig und behält nur kompakte, lesbare Dateiverweise im Modellkontext. Der nur ergänzte Rohverlauf und die vollständigen Ergebnisse bleiben unverändert. Gemischte Medienergebnisse und die letzten 20 Nachrichten werden nicht angetastet. In einer gemessenen Sitzung von Fredrik wählte dieser Schnitt 12 ältere Ergebnisse aus und verringerte die projizierte alte Werkzeugausgabe um mindestens 63.444 Zeichen, also um etwa 15.861 geschätzte Token.
123
+
124
+ Ab BLUN King 9.1.122 wird die vollständige integrierte Designrichtlinie nicht mehr bei jeder Modellanfrage mitgesendet. Nicht visuelle Arbeit erhält nur noch einen kompakten Aktivierungsvertrag. Vor Arbeiten an Benutzeroberflächen, Frontends, visueller Gestaltung, Interaktionen, Design oder Barrierefreiheit lädt King die vollständige Richtlinie über das Skill-Werkzeug; vom Nutzer ausgewählte Design-Skills bleiben zusätzlich verfügbar. Auch bestehende Sitzungen profitieren davon, ohne dass ihr nur ergänzter Rohverlauf umgeschrieben wird, denn verkürzt wird ausschließlich die Modellprojektion. Die Auslagerung älterer reiner Textausgaben von Werkzeugen erzielt nun außerdem die bestmögliche Entlastung, wenn allein die ausgenommenen kleinen Ergebnisse bereits über dem Ziel von 12.000 Zeichen liegen, statt in diesem Fall die gesamte Entlastung abzubrechen. In Fredriks aktuell vermessener Sitzung wurden 14 ältere Werkzeugergebnisse ausgewählt; die projizierte alte Werkzeugausgabe sank dadurch von 77.342 auf 12.418 Zeichen. Zusammen mit der bedarfsgeladenen Designrichtlinie sowie den bestehenden Auslagerungen von Nutzer- und Assistentennachrichten sank die gemessene Projektion von 322.780 Rohzeichen auf 109.656 Zeichen, also auf etwa 27.414 geschätzte Token. Die neuesten 20 Nachrichten, gemischte Medien, der Rohverlauf, Exporte und die vollständige bedarfsgeladene Designrichtlinie bleiben unverändert.
125
+
122
126
  Verliert ein delegierter Einzelagent oder ein Mitglied eines Agentenschwarms die Provider-Verbindung, erhält es eine leere Provider-Antwort, bricht sein Stream wegen Leerlaufs ab oder meldet der Server HTTP 408/500/502/503/504, setzt BLUN King denselben Agenten anhand seines dauerhaften Verlaufs fort. Bei Einzelagenten sowie bei Schwarm-Unterbrechungen außerhalb von HTTP 429 wartet die erste Fortsetzung zwei Sekunden und die zweite fünf Sekunden; danach bleibt der ursprüngliche Fehler sichtbar. HTTP 429 behält im Schwarm seine getrennte, längere Überlastungsregel. Authentifizierungs-, Zahlungs- oder Kontingent-, Richtlinien-, Kontext-, Werkzeug- und Codefehler sowie manuelle Abbrüche lösen keine automatische Fortsetzung aus. Jeder Fortsetzungsversuch verwendet die bestehende Agenten-ID, damit bereits abgeschlossene Arbeit nicht wiederholt wird.
123
127
 
124
128
  Rein lesende Sitzungsdiagnose
package/README.md CHANGED
@@ -125,6 +125,10 @@ Ab BLUN King 9.1.119 enthält der bei jedem Modellschritt erneut gesendete Promp
125
125
 
126
126
  Ab BLUN King 9.1.120 lagert die Konsole auch große ältere Assistentenantworten aus dem aktiven Modellkontext in private Sitzungsdateien aus. Der vollständige Gesprächsverlauf bleibt erhalten; im Modellkontext verbleiben eine begrenzte Vorschau und der Dateipfad. Die 20 neuesten Nachrichten sowie Assistentenantworten mit Werkzeugaufrufen bleiben unverändert, damit laufende Arbeit und Aufrufketten vollständig verfügbar sind.
127
127
 
128
+ Ab BLUN King 9.1.121 begrenzt die Modellprojektion auch die Gesamtgröße älterer, mittelgroßer Werkzeugergebnisse, die ausschließlich Text enthalten. Überschreiten Werkzeugergebnisse außerhalb der letzten 20 Nachrichten zusammen 12.000 Zeichen, archiviert King so viele der größten geeigneten Ergebnisse wie nötig und behält nur kompakte, lesbare Dateiverweise im Modellkontext. Der nur ergänzte Rohverlauf und die vollständigen Ergebnisse bleiben unverändert. Gemischte Medienergebnisse und die letzten 20 Nachrichten werden nicht angetastet. In einer gemessenen Sitzung von Fredrik wählte dieser Schnitt 12 ältere Ergebnisse aus und verringerte die projizierte alte Werkzeugausgabe um mindestens 63.444 Zeichen, also um etwa 15.861 geschätzte Token.
129
+
130
+ Ab BLUN King 9.1.122 wird die vollständige integrierte Designrichtlinie nicht mehr bei jeder Modellanfrage mitgesendet. Nicht visuelle Arbeit erhält nur noch einen kompakten Aktivierungsvertrag. Vor Arbeiten an Benutzeroberflächen, Frontends, visueller Gestaltung, Interaktionen, Design oder Barrierefreiheit lädt King die vollständige Richtlinie über das Skill-Werkzeug; vom Nutzer ausgewählte Design-Skills bleiben zusätzlich verfügbar. Auch bestehende Sitzungen profitieren davon, ohne dass ihr nur ergänzter Rohverlauf umgeschrieben wird, denn verkürzt wird ausschließlich die Modellprojektion. Die Auslagerung älterer reiner Textausgaben von Werkzeugen erzielt nun außerdem die bestmögliche Entlastung, wenn allein die ausgenommenen kleinen Ergebnisse bereits über dem Ziel von 12.000 Zeichen liegen, statt in diesem Fall die gesamte Entlastung abzubrechen. In Fredriks aktuell vermessener Sitzung wurden 14 ältere Werkzeugergebnisse ausgewählt; die projizierte alte Werkzeugausgabe sank dadurch von 77.342 auf 12.418 Zeichen. Zusammen mit der bedarfsgeladenen Designrichtlinie sowie den bestehenden Auslagerungen von Nutzer- und Assistentennachrichten sank die gemessene Projektion von 322.780 Rohzeichen auf 109.656 Zeichen, also auf etwa 27.414 geschätzte Token. Die neuesten 20 Nachrichten, gemischte Medien, der Rohverlauf, Exporte und die vollständige bedarfsgeladene Designrichtlinie bleiben unverändert.
131
+
128
132
  Ab BLUN King 9.1.99 werden auch direkt aufeinanderfolgende reine Textergebnisse als Stapel betrachtet. Enthalten sie zusammen mehr als 12.000 Zeichen, obwohl kein einzelnes Ergebnis diese Grenze überschreitet, speichert King so viele der größten geeigneten Ergebnisse wie nötig in privaten Dateien. In der Modellprojektion verbleiben lesbare Verweise. Der unveränderte Sitzungsrohverlauf bleibt vollständig erhalten. Gemischte Medienergebnisse, einzelne Ergebnisse unter 3.000 Zeichen und Stapel bis einschließlich 12.000 Zeichen bleiben unverändert. Beispiel: Bei zwei Suchergebnissen mit 7.000 und 6.000 Zeichen wird das größere Ergebnis privat gespeichert; Anfang, Ende, ausgelassene Zeichenzahl und `output_path` bleiben für den Agenten sichtbar.
129
133
 
130
134
  Ab BLUN King 9.1.100 beendet eine begrenzte Grep-Inhaltssuche ripgrep, sobald der Versatz, die angeforderten Zeilen und eine zusätzliche Vorschauzeile vollständig vorliegen. Die Vorschauzeile belegt, ob eine weitere Seite existiert, ohne vorher bis zu 10 MB einzulesen. Unbegrenzte Suchen, Trefferzählungen und nach Änderungszeit sortierte Dateilisten laufen weiterhin vollständig durch.
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ const BASELINE_ACTIVATION_MAX_CHARS = 700;
4
+ const BASELINE_SKILL_ORIGIN_PREFIX = 'baseline_skill:';
5
+
6
+ function escapeXmlAttribute(value) {
7
+ return String(value ?? '')
8
+ .replaceAll('&', '&')
9
+ .replaceAll('"', '"')
10
+ .replaceAll('<', '&lt;')
11
+ .replaceAll('>', '&gt;');
12
+ }
13
+
14
+ function renderBaselineActivationPrompt(input = {}) {
15
+ const skillName = String(input.skillName || 'blun-design-dna').trim();
16
+ const attributes = [
17
+ `name="${escapeXmlAttribute(skillName)}"`,
18
+ input.skillSource ? `source="${escapeXmlAttribute(input.skillSource)}"` : '',
19
+ input.skillDir ? `dir="${escapeXmlAttribute(input.skillDir)}"` : '',
20
+ ].filter(Boolean).join(' ');
21
+
22
+ return [
23
+ `<blun-baseline-skill ${attributes}>`,
24
+ 'For non-visual work, keep the design baseline dormant and do not load its full body.',
25
+ `Before UI, frontend, visual, interaction, design, or accessibility work, call the Skill tool with "${skillName}" and follow the complete loaded instructions before editing.`,
26
+ 'User-selected design skills are additive; they do not replace the baseline.',
27
+ '</blun-baseline-skill>',
28
+ ].join('\n');
29
+ }
30
+
31
+ function compactBaselineSkillInjections(messages) {
32
+ if (!Array.isArray(messages)) return messages;
33
+ return messages.map((message) => {
34
+ const variant = String(message?.origin?.variant || '');
35
+ if (message?.origin?.kind !== 'injection' || !variant.startsWith(BASELINE_SKILL_ORIGIN_PREFIX)) {
36
+ return message;
37
+ }
38
+ const skillName = variant.slice(BASELINE_SKILL_ORIGIN_PREFIX.length).trim();
39
+ if (!skillName || !Array.isArray(message.content)) return message;
40
+ const textIndex = message.content.findIndex((part) => part?.type === 'text');
41
+ if (textIndex < 0) return message;
42
+ const compactText = `<system-reminder>\n${renderBaselineActivationPrompt({ skillName })}\n</system-reminder>`;
43
+ if (message.content[textIndex].text === compactText) return message;
44
+ const content = [...message.content];
45
+ content[textIndex] = { ...content[textIndex], text: compactText };
46
+ return { ...message, content };
47
+ });
48
+ }
49
+
50
+ module.exports = {
51
+ BASELINE_ACTIVATION_MAX_CHARS,
52
+ compactBaselineSkillInjections,
53
+ renderBaselineActivationPrompt,
54
+ };
@@ -7,6 +7,7 @@ const FIRST_USE_SKILLS = new Set([
7
7
  'translate-native',
8
8
  'native-diacritics',
9
9
  'blun-app-design-system',
10
+ 'blun-design-dna',
10
11
  ]);
11
12
 
12
13
  const DEFAULT_SEARCH_LIMIT = 12;
@@ -6,6 +6,10 @@ const TOOL_RESULT_OFFLOAD_MARKER = '[Tool result offloaded]';
6
6
  const TOOL_RESULT_BATCH_MAX_CHARS = TOOL_RESULT_MAX_CHARS;
7
7
  const TOOL_RESULT_BATCH_MIN_ITEM_CHARS = 3_000;
8
8
  const TOOL_RESULT_BATCH_REPLACEMENT_BUDGET_CHARS = 2_500;
9
+ const TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES = 20;
10
+ const TOOL_RESULT_HISTORICAL_MAX_CHARS = TOOL_RESULT_BATCH_MAX_CHARS;
11
+ const TOOL_RESULT_HISTORICAL_MIN_ITEM_CHARS = 600;
12
+ const TOOL_RESULT_HISTORICAL_REPLACEMENT_BUDGET_CHARS = 600;
9
13
 
10
14
  function shouldOffloadToolResult(textLength) {
11
15
  return Number.isFinite(textLength) && textLength > TOOL_RESULT_MAX_CHARS;
@@ -62,15 +66,48 @@ function selectToolResultBatchOffloads(textLengths) {
62
66
  : [];
63
67
  }
64
68
 
69
+ function selectHistoricalToolResultOffloads(textLengths) {
70
+ if (!Array.isArray(textLengths) || textLengths.length === 0) return [];
71
+
72
+ const normalized = textLengths.map((length) => (
73
+ Number.isFinite(length) && length > 0 ? Math.floor(length) : 0
74
+ ));
75
+ const totalChars = normalized.reduce((total, length) => total + length, 0);
76
+ if (totalChars <= TOOL_RESULT_HISTORICAL_MAX_CHARS) return [];
77
+
78
+ let projectedChars = totalChars;
79
+ const selected = [];
80
+ const candidates = normalized
81
+ .map((length, index) => ({ index, length }))
82
+ .filter(({ length }) => (
83
+ length >= TOOL_RESULT_HISTORICAL_MIN_ITEM_CHARS
84
+ && length > TOOL_RESULT_HISTORICAL_REPLACEMENT_BUDGET_CHARS
85
+ ))
86
+ .sort((left, right) => right.length - left.length || left.index - right.index);
87
+
88
+ for (const candidate of candidates) {
89
+ if (projectedChars <= TOOL_RESULT_HISTORICAL_MAX_CHARS) break;
90
+ projectedChars -= candidate.length - TOOL_RESULT_HISTORICAL_REPLACEMENT_BUDGET_CHARS;
91
+ selected.push(candidate.index);
92
+ }
93
+
94
+ return selected.sort((left, right) => left - right);
95
+ }
96
+
65
97
  module.exports = {
66
98
  TOOL_RESULT_BATCH_MAX_CHARS,
67
99
  TOOL_RESULT_BATCH_MIN_ITEM_CHARS,
68
100
  TOOL_RESULT_BATCH_REPLACEMENT_BUDGET_CHARS,
101
+ TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES,
102
+ TOOL_RESULT_HISTORICAL_MAX_CHARS,
103
+ TOOL_RESULT_HISTORICAL_MIN_ITEM_CHARS,
104
+ TOOL_RESULT_HISTORICAL_REPLACEMENT_BUDGET_CHARS,
69
105
  TOOL_RESULT_MAX_CHARS,
70
106
  TOOL_RESULT_PREVIEW_CHARS,
71
107
  TOOL_RESULT_OFFLOAD_MARKER,
72
108
  createToolResultPreview,
73
109
  isPersistedToolResultReference,
110
+ selectHistoricalToolResultOffloads,
74
111
  selectToolResultBatchOffloads,
75
112
  shouldOffloadToolResult,
76
113
  };
package/blun.mjs CHANGED
@@ -78960,7 +78960,7 @@ var init_context$2 = __esmMin((() => {
78960
78960
  }
78961
78961
  project(messages, options) {
78962
78962
  const anomalies = [];
78963
- const result = project(this.agent.assistantMessageOffload.compact(this.agent.userMessageOffload.compact(this.agent.microCompaction.compact(this.agent.toolResultBatchOffload.compact(dedupeRepeatedInjections(messages))))), {
78963
+ const result = project(this.agent.assistantMessageOffload.compact(this.agent.userMessageOffload.compact(this.agent.microCompaction.compact(this.agent.toolResultBatchOffload.compact(dedupeRepeatedInjections(compactBaselineSkillInjections(messages)))))), {
78964
78964
  ...options,
78965
78965
  onAnomaly: (anomaly) => {
78966
78966
  anomalies.push(anomaly);
@@ -235799,15 +235799,7 @@ function renderUserSlashSkillPrompt(input) {
235799
235799
  ].join("\n");
235800
235800
  }
235801
235801
  function renderBaselineSkillPrompt(input) {
235802
- return [
235803
- "This baseline skill is always active. Apply it silently whenever it is relevant.",
235804
- "Additional skills selected by the user are additive and remain available.",
235805
- "",
235806
- renderSkillLoadedBlock({
235807
- ...input,
235808
- trigger: "baseline"
235809
- })
235810
- ].join("\n");
235802
+ return renderBaselineActivationPrompt(input);
235811
235803
  }
235812
235804
  function renderModelToolSkillPrompt(input) {
235813
235805
  return [
@@ -235835,8 +235827,10 @@ function renderSkillAttributes(input) {
235835
235827
  ["args", input.skillArgs]
235836
235828
  ].filter((item) => item[1] !== void 0).map(([name, value]) => ` ${name}="${escapeXml$1(value)}"`).join("");
235837
235829
  }
235830
+ var compactBaselineSkillInjections, renderBaselineActivationPrompt;
235838
235831
  var init_prompt$2 = __esmMin((() => {
235839
235832
  init_xml_escape();
235833
+ ({ compactBaselineSkillInjections, renderBaselineActivationPrompt } = createRequire(import.meta.url)("./bin/baseline-skill-performance-policy.cjs"));
235840
235834
  }));
235841
235835
  //#endregion
235842
235836
  //#region ../../packages/agent-core/src/agent/skill/index.ts
@@ -235885,11 +235879,8 @@ var init_skill$3 = __esmMin((() => {
235885
235879
  if (skill === void 0) return false;
235886
235880
  const variant = `${BASELINE_SKILL_ORIGIN_PREFIX}${skill.name}`;
235887
235881
  if (this.agent.context.history.some((message) => message.origin?.kind === "injection" && message.origin.variant === variant)) return true;
235888
- const skillContent = this.registry.renderSkillPrompt(skill, "");
235889
235882
  this.agent.context.appendSystemReminder(renderBaselineSkillPrompt({
235890
235883
  skillName: skill.name,
235891
- skillArgs: "",
235892
- skillContent,
235893
235884
  skillSource: skill.source,
235894
235885
  skillDir: skill.dir
235895
235886
  }), {
@@ -260329,10 +260320,53 @@ function renderReadSourceReference(toolName, toolCallId, text, outputPath) {
260329
260320
  lines.push("", "[preview: head and tail]", createToolResultPreview(text));
260330
260321
  return lines.join("\n");
260331
260322
  }
260323
+ async function persistHistoricalToolResultForModel(options, knownText) {
260324
+ const text = knownText ?? persistableToolResultText(options.result.output);
260325
+ if (text === void 0 || options.result.truncated === true) return options.result;
260326
+ const readSourcePath = reusableReadSourcePath(options);
260327
+ let outputPath = readSourcePath;
260328
+ let storageMode = "original_file";
260329
+ if (outputPath === void 0) {
260330
+ if (options.homedir === void 0) return options.result;
260331
+ outputPath = await saveToolResult({
260332
+ homedir: options.homedir,
260333
+ toolName: options.toolName,
260334
+ toolCallId: options.toolCallId
260335
+ }, text);
260336
+ storageMode = "private_archive";
260337
+ }
260338
+ if (outputPath === void 0) return options.result;
260339
+ options.telemetry?.track("tool_result_historical_offloaded", {
260340
+ ...buildToolResultOffloadTelemetry({
260341
+ toolName: options.toolName,
260342
+ text,
260343
+ previewChars: 0
260344
+ }),
260345
+ storage_mode: storageMode
260346
+ });
260347
+ return {
260348
+ ...options.result,
260349
+ output: renderHistoricalToolResultReference(options.toolName, options.toolCallId, text, outputPath, storageMode),
260350
+ ...(options.result.isError === true ? { isError: true } : {})
260351
+ };
260352
+ }
260353
+ function renderHistoricalToolResultReference(toolName, toolCallId, text, outputPath, storageMode) {
260354
+ return [
260355
+ TOOL_RESULT_OFFLOAD_MARKER,
260356
+ "An older tool result was archived to keep the active context fast.",
260357
+ `storage_mode: ${storageMode}`,
260358
+ `tool_name: ${toolName}`,
260359
+ `tool_call_id: ${toolCallId}`,
260360
+ `output_size_chars: ${String(text.length)}`,
260361
+ `output_size_bytes: ${String(Buffer.byteLength(text, "utf8"))}`,
260362
+ `output_path: ${outputPath}`,
260363
+ "next_step: Use Read with output_path if the full result is needed again."
260364
+ ].join("\n");
260365
+ }
260332
260366
  function safeToolResultFileStem(toolName, toolCallId) {
260333
260367
  return `${toolName}-${toolCallId}`.replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 80) || "tool-result";
260334
260368
  }
260335
- var TOOL_RESULT_MAX_CHARS, TOOL_RESULT_PREVIEW_CHARS, TOOL_RESULT_OFFLOAD_MARKER, shouldOffloadToolResult, createToolResultPreview, selectToolResultBatchOffloads, buildToolResultOffloadTelemetry;
260369
+ var TOOL_RESULT_MAX_CHARS, TOOL_RESULT_PREVIEW_CHARS, TOOL_RESULT_OFFLOAD_MARKER, TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES, shouldOffloadToolResult, createToolResultPreview, selectToolResultBatchOffloads, selectHistoricalToolResultOffloads, buildToolResultOffloadTelemetry;
260336
260370
  var init_tool_result_budget = __esmMin((() => {
260337
260371
  init_dist$6();
260338
260372
  const toolResultOffloadPolicy = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs");
@@ -260340,9 +260374,11 @@ var init_tool_result_budget = __esmMin((() => {
260340
260374
  TOOL_RESULT_MAX_CHARS = toolResultOffloadPolicy.TOOL_RESULT_MAX_CHARS;
260341
260375
  TOOL_RESULT_PREVIEW_CHARS = toolResultOffloadPolicy.TOOL_RESULT_PREVIEW_CHARS;
260342
260376
  TOOL_RESULT_OFFLOAD_MARKER = toolResultOffloadPolicy.TOOL_RESULT_OFFLOAD_MARKER;
260377
+ TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES = toolResultOffloadPolicy.TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES;
260343
260378
  shouldOffloadToolResult = toolResultOffloadPolicy.shouldOffloadToolResult;
260344
260379
  createToolResultPreview = toolResultOffloadPolicy.createToolResultPreview;
260345
260380
  selectToolResultBatchOffloads = toolResultOffloadPolicy.selectToolResultBatchOffloads;
260381
+ selectHistoricalToolResultOffloads = toolResultOffloadPolicy.selectHistoricalToolResultOffloads;
260346
260382
  }));
260347
260383
  //#endregion
260348
260384
  //#region ../../packages/agent-core/src/agent/turn/tool-result-batch-offload.ts
@@ -260360,7 +260396,20 @@ var ToolResultBatchOffload = class {
260360
260396
  if (message?.role !== "tool") break;
260361
260397
  tail.unshift(message);
260362
260398
  }
260363
- const candidates = tail.map((message) => {
260399
+ const tailIds = new Set(tail.map((message) => message.toolCallId).filter((id) => id !== void 0));
260400
+ const recentStart = Math.max(0, history.length - TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES);
260401
+ const historical = history.slice(0, recentStart).filter((message) => message?.role === "tool" && !tailIds.has(message.toolCallId));
260402
+ const candidateBatches = [{
260403
+ messages: tail,
260404
+ historical: false,
260405
+ select: selectToolResultBatchOffloads
260406
+ }, {
260407
+ messages: historical,
260408
+ historical: true,
260409
+ select: selectHistoricalToolResultOffloads
260410
+ }].map((batch) => ({
260411
+ ...batch,
260412
+ candidates: batch.messages.map((message) => {
260364
260413
  if (message.toolCallId === void 0 || this.replacements.has(message.toolCallId) || isPersistedToolResultReference(message.content)) return;
260365
260414
  const text = persistableToolResultText(message.content);
260366
260415
  if (text === void 0) return;
@@ -260371,15 +260420,19 @@ var ToolResultBatchOffload = class {
260371
260420
  toolName: toolCall?.name ?? "Tool",
260372
260421
  toolArgs: this.toolArgsFor(toolCall)
260373
260422
  };
260374
- }).filter((candidate) => candidate !== void 0);
260375
- const selected = selectToolResultBatchOffloads(candidates.map((candidate) => candidate.text.length));
260376
- if (selected.length === 0) return 0;
260423
+ }).filter((candidate) => candidate !== void 0)
260424
+ }));
260425
+ const selectedCandidates = candidateBatches.flatMap((batch) => batch.select(batch.candidates.map((candidate) => candidate.text.length)).map((index) => {
260426
+ const candidate = batch.candidates[index];
260427
+ return candidate === void 0 ? void 0 : { ...candidate, historical: batch.historical };
260428
+ }).filter((candidate) => candidate !== void 0));
260429
+ if (selectedCandidates.length === 0) return 0;
260377
260430
  const replacements = [];
260378
260431
  let charsBefore = 0;
260379
260432
  let charsAfter = 0;
260380
- for (const index of selected) {
260381
- const candidate = candidates[index];
260382
- if (candidate === void 0) continue;
260433
+ let historicalResultCount = 0;
260434
+ let tailResultCount = 0;
260435
+ for (const candidate of selectedCandidates) {
260383
260436
  const original = {
260384
260437
  output: candidate.message.content,
260385
260438
  isError: candidate.message.isError
@@ -260393,7 +260446,7 @@ var ToolResultBatchOffload = class {
260393
260446
  telemetry: this.agent.telemetry
260394
260447
  };
260395
260448
  const readSourcePath = reusableReadSourcePath(resultOptions);
260396
- const persisted = readSourcePath === void 0 ? await persistToolResultForModel(resultOptions, candidate.text) : referenceReadSourceForModel(resultOptions, candidate.text, readSourcePath);
260449
+ const persisted = candidate.historical ? await persistHistoricalToolResultForModel(resultOptions, candidate.text) : readSourcePath === void 0 ? await persistToolResultForModel(resultOptions, candidate.text) : referenceReadSourceForModel(resultOptions, candidate.text, readSourcePath);
260397
260450
  if (persisted === original || typeof persisted.output !== "string" || persisted.output.length >= candidate.text.length) continue;
260398
260451
  const content = [{
260399
260452
  type: "text",
@@ -260405,11 +260458,15 @@ var ToolResultBatchOffload = class {
260405
260458
  });
260406
260459
  charsBefore += candidate.text.length;
260407
260460
  charsAfter += persisted.output.length;
260461
+ if (candidate.historical) historicalResultCount += 1;
260462
+ else tailResultCount += 1;
260408
260463
  }
260409
260464
  if (replacements.length === 0) return 0;
260410
260465
  this.apply(replacements);
260411
260466
  this.agent.telemetry.track("tool_result_batch_offloaded", {
260412
260467
  result_count: replacements.length,
260468
+ historical_result_count: historicalResultCount,
260469
+ tail_result_count: tailResultCount,
260413
260470
  chars_before: charsBefore,
260414
260471
  chars_after: charsAfter,
260415
260472
  chars_saved: charsBefore - charsAfter
@@ -296955,14 +297012,6 @@ var init_session$1 = __esmMin((() => {
296955
297012
  });
296956
297013
  await this.skills.loadRoots(roots);
296957
297014
  registerBuiltinSkills(this.skills);
296958
- const baseline = this.skills.getSkill(BASELINE_SKILL_NAME);
296959
- if (baseline !== void 0) this.skills.register({
296960
- ...baseline,
296961
- metadata: {
296962
- ...baseline.metadata,
296963
- disableModelInvocation: true
296964
- }
296965
- }, { replace: true });
296966
297015
  }
296967
297016
  async loadMcpServers() {
296968
297017
  const servers = this.currentMcpConfig?.servers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.120",
3
+ "version": "9.1.122",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {