blun-king-cli 9.1.423 → 9.1.424

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.
@@ -14,7 +14,8 @@ const NON_ACTIONABLE_USER_ORIGINS = new Set([
14
14
  'skill_activation',
15
15
  ]);
16
16
  const STOP_WORDS = new Set([
17
- 'aber', 'alle', 'alles', 'auch', 'eine', 'einem', 'einen', 'einer', 'eines',
17
+ 'aber', 'alle', 'alles', 'auch', 'das', 'dem', 'den', 'der', 'des', 'die',
18
+ 'ein', 'eine', 'einem', 'einen', 'einer', 'eines',
18
19
  'fuer', 'haben', 'hier', 'immer', 'jetzt', 'kann', 'machen', 'mehr', 'mich',
19
20
  'nicht', 'noch', 'oder', 'sein', 'sind', 'soll', 'und', 'uns', 'von', 'was',
20
21
  'wenn', 'werden', 'wie', 'with', 'that', 'this', 'from', 'have', 'into',
@@ -22,8 +23,36 @@ const STOP_WORDS = new Set([
22
23
  ]);
23
24
  const REUSABLE_HEADING = /\b(rule|regel|condition|bedingung|countercheck|gegenprobe|trigger|ausloeser|auslöser)\b/iu;
24
25
 
26
+ const SEMANTIC_SIGNAL_RULES = Object.freeze([
27
+ ['problem:reliability', /\b(?:error|failure|failed|broken|crash(?:ed)?|timeout|unavailable|corrupt(?:ed)?|dropped|missing|lost|fehler|scheiter\w*|absturz|ausfall|kaputt|defekt|fehlend|verloren|unerreichbar|abbruch)\b/iu],
28
+ ['problem:delivery', /\b(?:deliver\w*|receiv\w*|message\w*|repl(?:y|ies)|inbox|outbox|send(?:ing|s|t)?|consum\w*|zustell\w*|empfang\w*|nachricht\w*|meldung\w*|senden|bekomm\w*|antwort\w*)\b/iu],
29
+ ['problem:stagnation', /\b(?:loop\w*|repeat\w*|stuck|hang(?:ing)?|freeze|frozen|idle|no progress|stop(?:s|ped)? consuming|schleife\w*|wiederhol\w*|hang\w*|stillstand|leerlauf|kein fortschritt|taub)\b/iu],
30
+ ['problem:performance', /\b(?:slow|latency|bottleneck|throughput|memory pressure|cpu|vram|langsam\w*|latenz|durchsatz|engpass|speicherdruck)\b/iu],
31
+ ['problem:protocol', /\b(?:schema|contract|payload|protocol|format|version mismatch|manifest mismatch|vertrag|protokoll|versionskonflikt)\b/iu],
32
+ ['problem:capability', /\b(?:capabilit\w*|missing tool|not available|unsupported|fahigkeit\w*|werkzeug fehlt|nicht verfugbar)\b/iu],
33
+ ['area:orchestration', /\b(?:agent\w*|worker\w*|queue\w*|checkpoint\w*|heartbeat\w*|delegat\w*|owner\w*|responsib\w*|task\w*|turn\w*|busy|group\w*|channel\w*|arbeiter\w*|warteschlange\w*|prufpunkt\w*|herzschlag\w*|zustandig\w*|auftrag\w*|zug\w*|beschaftigt|gruppe\w*|gruppen\w*|kanal\w*)\b/iu],
34
+ ['area:memory', /\b(?:memory|recall|remember\w*|context|history|resume|checkpoint|mnemo|gedachtnis|erinner\w*|kontext|verlauf|wiederaufnahme)\b/iu],
35
+ ['area:release', /\b(?:release\w*|rollout\w*|update\w*|updater\w*|npm|package\w*|manifest\w*|version\w*|veroffentlich\w*|paket\w*|integrity|integritat)\b/iu],
36
+ ['area:media', /\b(?:image\w*|video\w*|audio\w*|portrait\w*|render\w*|pixel\w*|media|bild\w*|foto\w*|gesicht\w*|stimme\w*)\b/iu],
37
+ ['risk:validation', /\b(?:verif\w*|validat\w*|test\w*|check\w*|gate\w*|rollback\w*|canary|proof|evidence|sha(?:256|512)?|measur\w*|inspect\w*|(?:ge)?pruf\w*|gegenprobe\w*|beleg\w*|evidenz\w*|mess\w*|kontroll\w*)\b/iu],
38
+ ['action:repair', /\b(?:fix\w*|repair\w*|restore\w*|recover\w*|reparier\w*|beheb\w*|wiederherstell\w*)\b/iu],
39
+ ['action:investigate', /\b(?:inspect\w*|diagnos\w*|measure\w*|trace\w*|check\w*|(?:ge)?pruf\w*|mess\w*|untersuch\w*)\b/iu],
40
+ ]);
41
+
25
42
  function normalizeText(value) {
26
- return String(value || '').normalize('NFKD').replace(/\p{M}/gu, '').toLowerCase();
43
+ return String(value || '')
44
+ .normalize('NFKD')
45
+ .replace(/\p{M}/gu, '')
46
+ .replace(/\u00df/gu, 'ss')
47
+ .toLowerCase();
48
+ }
49
+
50
+ function semanticSignalTags(value) {
51
+ const normalized = normalizeText(value);
52
+ if (!normalized) return [];
53
+ return SEMANTIC_SIGNAL_RULES
54
+ .filter(([, pattern]) => pattern.test(normalized))
55
+ .map(([tag]) => tag);
27
56
  }
28
57
 
29
58
  function terms(value) {
@@ -100,15 +129,25 @@ function isReusableSection(section) {
100
129
  return REUSABLE_HEADING.test(`${section.heading}\n${section.body}`);
101
130
  }
102
131
 
103
- function scoreSection(section, queryTerms) {
132
+ function scoreSection(section, queryTerms, queryTags) {
104
133
  const heading = normalizeText(`${section.parent} ${section.heading}`);
105
134
  const body = normalizeText(section.body);
106
135
  let score = isReusableSection(section) ? 1 : 0;
136
+ let lexicalMatches = 0;
107
137
  for (const term of queryTerms) {
108
- if (heading.includes(term)) score += 6;
109
- if (body.includes(term)) score += 4;
138
+ if (heading.includes(term)) {
139
+ score += 6;
140
+ lexicalMatches += 1;
141
+ }
142
+ if (body.includes(term)) {
143
+ score += 4;
144
+ lexicalMatches += 1;
145
+ }
110
146
  }
111
- return score;
147
+ const sectionTags = new Set(semanticSignalTags(`${heading}\n${body}`));
148
+ const semanticMatches = queryTags.filter((tag) => sectionTags.has(tag));
149
+ score += semanticMatches.length * 2;
150
+ return { lexicalMatches, score, semanticMatches };
112
151
  }
113
152
 
114
153
  function compactSection(section, maxChars) {
@@ -144,16 +183,24 @@ function selectRelevantMistakeSources(sources, query, options = {}) {
144
183
  }))
145
184
  ));
146
185
  const queryTerms = terms(query);
186
+ const queryTags = semanticSignalTags(query);
147
187
  const ranked = sections.map((section) => {
148
188
  const reusable = isReusableSection(section);
149
- const score = scoreSection(section, queryTerms);
189
+ const { lexicalMatches, score, semanticMatches } = scoreSection(section, queryTerms, queryTags);
150
190
  return {
151
191
  ...section,
152
- matched: score > (reusable ? 1 : 0),
192
+ lexicalMatches,
153
193
  reusable,
154
194
  score,
195
+ semanticMatches,
155
196
  };
156
197
  });
198
+ const hasLexicalMatch = ranked.some((section) => section.lexicalMatches > 0);
199
+ for (const section of ranked) {
200
+ section.matched = hasLexicalMatch
201
+ ? section.lexicalMatches > 0
202
+ : section.semanticMatches.length > 0;
203
+ }
157
204
  const hasMatch = ranked.some((section) => section.matched);
158
205
  ranked.sort((left, right) => {
159
206
  if (hasMatch && right.score !== left.score) return right.score - left.score;
@@ -188,6 +235,11 @@ function selectRelevantMistakeSources(sources, query, options = {}) {
188
235
  selected.sort((left, right) => left.ordinal - right.ordinal);
189
236
  const text = [header, ...selected.map((section) => section.rendered)].join('\n\n').slice(0, maxChars);
190
237
  return {
238
+ selected: selected.map((section) => ({
239
+ heading: section.heading,
240
+ reference: normalizedSources[section.sourceIndex]?.reference || '',
241
+ semanticMatches: section.semanticMatches || [],
242
+ })),
191
243
  selectedChars: text.length,
192
244
  selectedSections: selected.length,
193
245
  text,
@@ -209,6 +261,7 @@ module.exports = {
209
261
  RECENT_USER_MESSAGES,
210
262
  isLowInformationMistakeTurn,
211
263
  recentUserText,
264
+ semanticSignalTags,
212
265
  selectRelevantMistakeContent,
213
266
  selectRelevantMistakeSources,
214
267
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.423",
3
+ "version": "9.1.424",
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": {