blun-king-cli 9.1.402 → 9.1.404

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
@@ -381,6 +381,30 @@ Anweisung wie "Zeig mir den letzten Telegram-Verlauf" das passende Werkzeug im
381
381
  selben Modellschritt erhalten, während Begrüßungen und fachfremde Anfragen keine
382
382
  zusätzlichen Schemata laden.
383
383
 
384
+ Begrenztes Ranking bei großen Eingaben
385
+ --------------------------------------
386
+
387
+ Ab BLUN King 9.1.403 bewertet die automatische Werkzeugauswahl pro aktueller
388
+ Anfrage höchstens 1.000 Zeichen. Eingebettete Inhalte aus
389
+ `<attached_documents>`, `<attachment_content>`, `<document_content>` und
390
+ `<file_content>` werden vor dem Ranking vollständig entfernt. Damit können
391
+ große Anhänge weder die Auswahl unnötig verteuern noch anhand ihres Inhalts ein
392
+ fachfremdes Werkzeug vorladen.
393
+
394
+ Ruhige Konfigurationsaktualisierung
395
+ -----------------------------------
396
+
397
+ Ab BLUN King 9.1.404 ersetzt eine Konfigurationsaktualisierung die private
398
+ config.toml nur noch, wenn sich ihre serialisierten Bytes tatsächlich ändern.
399
+ Bei identischem Inhalt bleiben Dateidentität und Änderungszeit erhalten; die
400
+ Prüfung und Härtung der privaten Dateirechte läuft trotzdem weiter. Echte
401
+ Änderungen verwenden unverändert den crash-sicheren atomaren Schreibweg.
402
+
403
+ Der eigentliche Anhang und die vollständige Nutzernachricht bleiben für den Zug
404
+ unverändert verfügbar. Die Begrenzung betrifft ausschließlich die kleine
405
+ lexikalische Vorauswahl von höchstens zwei Werkzeugschemas; ToolSearch und alle
406
+ explizit benötigten Medien- und Anhangswerkzeuge bleiben erhalten.
407
+
384
408
  Abschlussbedingungen mit Laufzeitbeleg
385
409
  --------------------------------------
386
410
 
package/README.md CHANGED
@@ -391,6 +391,28 @@ Anweisung wie „Zeig mir den letzten Telegram-Verlauf“ das passende Werkzeug
391
391
  selben Modellschritt erhalten, während Begrüßungen und fachfremde Anfragen keine
392
392
  zusätzlichen Schemata laden.
393
393
 
394
+ ## Begrenztes Ranking bei großen Eingaben
395
+
396
+ Ab BLUN King 9.1.403 bewertet die automatische Werkzeugauswahl pro aktueller
397
+ Anfrage höchstens 1.000 Zeichen. Eingebettete Inhalte aus
398
+ `<attached_documents>`, `<attachment_content>`, `<document_content>` und
399
+ `<file_content>` werden vor dem Ranking vollständig entfernt. Damit können
400
+ große Anhänge weder die Auswahl unnötig verteuern noch anhand ihres Inhalts ein
401
+ fachfremdes Werkzeug vorladen.
402
+
403
+ ## Ruhige Konfigurationsaktualisierung
404
+
405
+ Ab BLUN King 9.1.404 ersetzt eine Konfigurationsaktualisierung die private
406
+ `config.toml` nur noch, wenn sich ihre serialisierten Bytes tatsächlich ändern.
407
+ Bei identischem Inhalt bleiben Dateidentität und Änderungszeit erhalten; die
408
+ Prüfung und Härtung der privaten Dateirechte läuft trotzdem weiter. Echte
409
+ Änderungen verwenden unverändert den crash-sicheren atomaren Schreibweg.
410
+
411
+ Der eigentliche Anhang und die vollständige Nutzernachricht bleiben für den Zug
412
+ unverändert verfügbar. Die Begrenzung betrifft ausschließlich die kleine
413
+ lexikalische Vorauswahl von höchstens zwei Werkzeugschemas; ToolSearch und alle
414
+ explizit benötigten Medien- und Anhangswerkzeuge bleiben erhalten.
415
+
394
416
  ## Abschlussbedingungen mit Laufzeitbeleg
395
417
 
396
418
  Ab BLUN King 9.1.397 kann ein autonomes Ziel mit ausdrücklich gesetzter
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+
5
+ async function configFileMatches(filePath, nextContent, fsImpl = fs) {
6
+ const content = Buffer.isBuffer(nextContent)
7
+ ? nextContent
8
+ : Buffer.from(String(nextContent), 'utf8');
9
+
10
+ try {
11
+ const stat = await fsImpl.lstat(filePath);
12
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size !== content.byteLength) {
13
+ return false;
14
+ }
15
+
16
+ const current = await fsImpl.readFile(filePath);
17
+ return Buffer.isBuffer(current)
18
+ ? current.equals(content)
19
+ : Buffer.from(current).equals(content);
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ module.exports = {
26
+ configFileMatches,
27
+ };
@@ -6,6 +6,7 @@ const DEFERRED_TOOL_LOADER_NAME = 'ToolSearch';
6
6
  const MAX_PERSISTENT_DEFERRED_TOOLS = 4;
7
7
  const MAX_TOOL_SEARCH_QUERY_CHARS = 1_000;
8
8
  const MAX_AUTO_RANKED_TOOLS = 2;
9
+ const TOOL_RANK_EMBEDDED_CONTENT_RE = /<(attached_documents?|attachment_content|document_content|file_content)\b[^>]*>[\s\S]*?<\/\1>/giu;
9
10
  const TOOL_RANK_STOP_WORDS = new Set([
10
11
  'aber', 'also', 'and', 'aus', 'bitte', 'can', 'das', 'den', 'der', 'des', 'die', 'dies', 'diese',
11
12
  'du', 'ein', 'eine', 'einer', 'eines', 'for', 'fuer', 'für', 'haben', 'ich', 'ist', 'kann', 'kannst',
@@ -177,7 +178,10 @@ function rankingIntentTexts(value) {
177
178
  const channelBodies = [...text.matchAll(
178
179
  /(?:^|\r?\n)<channel\b[^>]*>\r?\n([\s\S]*?)\r?\n<\/channel>(?=\r?\n|$)/giu,
179
180
  )].map((match) => match[1]);
180
- return channelBodies.length > 0 ? channelBodies : [text];
181
+ const intentTexts = channelBodies.length > 0 ? channelBodies : [text];
182
+ return intentTexts.map((intentText) => normalizeDeferredToolQuery(
183
+ intentText.replace(TOOL_RANK_EMBEDDED_CONTENT_RE, ' '),
184
+ ));
181
185
  }
182
186
 
183
187
  function rankingTokens(value) {
package/blun.mjs CHANGED
@@ -16051,6 +16051,7 @@ function transformLoopControlData(data) {
16051
16051
  delete out["maxStepsPerRun"];
16052
16052
  return out;
16053
16053
  }
16054
+ const { configFileMatches } = createRequire(import.meta.url)("./bin/config-write-dedup-policy.cjs");
16054
16055
  async function writeConfigFile(filePath, config) {
16055
16056
  const validated = validateConfig(stripEnvModelConfig(config));
16056
16057
  const configDirectory = dirname$3(filePath);
@@ -16058,7 +16059,12 @@ async function writeConfigFile(filePath, config) {
16058
16059
  recursive: true,
16059
16060
  mode: 448
16060
16061
  }) !== void 0) await hardenPrivatePath(configDirectory, "directory");
16061
- await atomicWritePrivate$1(filePath, `${stringify$1(configToTomlData(validated))}\n`);
16062
+ const serialized = `${stringify$1(configToTomlData(validated))}\n`;
16063
+ if (await configFileMatches(filePath, serialized)) {
16064
+ await hardenPrivatePath(filePath, "file");
16065
+ return;
16066
+ }
16067
+ await atomicWritePrivate$1(filePath, serialized);
16062
16068
  }
16063
16069
  function configToTomlData(config) {
16064
16070
  const out = cloneRecord$2(config.raw);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.402",
3
+ "version": "9.1.404",
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": {