blun-king-cli 9.1.226 → 9.1.228

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.
@@ -12,7 +12,9 @@ const TOOL_SEARCH_RELATED_TERM_GROUPS = Object.freeze([
12
12
  'current', 'inbox', 'latest', 'message', 'messages', 'nachricht', 'nachrichten', 'queue', 'queued',
13
13
  'recent', 'update', 'updates',
14
14
  ]),
15
- Object.freeze(['history', 'log', 'logs', 'protokoll', 'transcript', 'verlauf']),
15
+ Object.freeze([
16
+ 'chat', 'conversation', 'history', 'log', 'logs', 'processed', 'protokoll', 'transcript', 'verlauf',
17
+ ]),
16
18
  Object.freeze([
17
19
  'fact', 'facts', 'fakt', 'fakten', 'memory', 'memories', 'merk', 'merken', 'note', 'notes',
18
20
  'persist', 'persistent', 'profile', 'remember', 'save', 'speichern', 'store',
@@ -20,7 +22,7 @@ const TOOL_SEARCH_RELATED_TERM_GROUPS = Object.freeze([
20
22
  ]);
21
23
  const TOOL_SEARCH_SINGLE_TERM_RELATED_FALLBACKS = new Set([
22
24
  'fact', 'facts', 'fakt', 'fakten', 'memory', 'memories', 'merk', 'merken', 'note', 'notes',
23
- 'persist', 'persistent', 'profile', 'remember', 'save', 'speichern', 'store',
25
+ 'persist', 'persistent', 'profile', 'remember', 'save', 'speichern', 'store', 'transcript',
24
26
  ]);
25
27
  const CORE_TOOL_NAMES = Object.freeze([
26
28
  'Bash',
@@ -129,18 +131,26 @@ function relatedSearchTerms(token) {
129
131
  return group || [token];
130
132
  }
131
133
 
132
- function searchRelatedDeferredTools(tools, query) {
134
+ function searchRelatedDeferredTools(tools, query, options = {}) {
133
135
  const normalized = String(query || '').trim().toLowerCase();
134
136
  if (!normalized || normalized.startsWith('select:')) return [];
135
137
  const tokens = normalized.split(/\s+/).filter(Boolean);
136
- const requiredNameTokens = tokens.filter((token) => token.startsWith('+')).map((token) => token.slice(1)).filter(Boolean);
137
- const searchTokens = tokens
138
- .filter((token) => !token.startsWith('+'))
138
+ const requestedNameTokens = tokens
139
+ .filter((token) => token.startsWith('+'))
140
+ .map((token) => token.slice(1))
141
+ .filter(Boolean);
142
+ const relaxRequiredNameTokens = options.relaxRequiredNameTokens === true
143
+ && requestedNameTokens.length > 0;
144
+ const requiredNameTokens = relaxRequiredNameTokens ? [] : requestedNameTokens;
145
+ const searchTokens = [
146
+ ...tokens.filter((token) => !token.startsWith('+')),
147
+ ...(relaxRequiredNameTokens ? requestedNameTokens : []),
148
+ ]
139
149
  .filter((token) => !TOOL_SEARCH_INTENT_WORDS.has(token));
140
150
  if (searchTokens.length < 2 && !TOOL_SEARCH_SINGLE_TERM_RELATED_FALLBACKS.has(searchTokens[0])) return [];
141
151
  const minimumMatchedTokens = searchTokens.length === 1 ? 1 : Math.max(2, Math.ceil(searchTokens.length * 0.75));
142
152
 
143
- return tools.map((tool) => {
153
+ const ranked = tools.map((tool) => {
144
154
  const name = String(tool?.name || '').toLowerCase();
145
155
  const description = String(tool?.description || '').toLowerCase();
146
156
  if (!requiredNameTokens.every((token) => name.includes(token))) return null;
@@ -171,7 +181,14 @@ function searchRelatedDeferredTools(tools, query) {
171
181
  right.matchedTokens - left.matchedTokens
172
182
  || right.score - left.score
173
183
  || String(left.tool.name).localeCompare(String(right.tool.name))
174
- )).slice(0, 5).map((entry) => entry.tool);
184
+ ));
185
+ if (relaxRequiredNameTokens && ranked.length > 0) {
186
+ const best = ranked[0];
187
+ return ranked.filter((entry) => (
188
+ entry.matchedTokens === best.matchedTokens && entry.score === best.score
189
+ )).slice(0, 5).map((entry) => entry.tool);
190
+ }
191
+ return ranked.slice(0, 5).map((entry) => entry.tool);
175
192
  }
176
193
 
177
194
  function rememberLoadedTool(loadedToolNames, name) {
@@ -182,6 +199,14 @@ function rememberLoadedTool(loadedToolNames, name) {
182
199
  }
183
200
  }
184
201
 
202
+ function rememberDeferredToolAfterNotFound(loadedToolNames, toolName, result) {
203
+ if (!(loadedToolNames instanceof Set) || result?.isError !== true) return false;
204
+ const name = String(toolName || '').trim();
205
+ if (!name || String(result?.output || '').trim() !== `Tool "${name}" not found`) return false;
206
+ rememberLoadedTool(loadedToolNames, name);
207
+ return true;
208
+ }
209
+
185
210
  function createDeferredToolLoader(selectedTools, deferredTools, loadedToolNames = new Set()) {
186
211
  if (!Array.isArray(selectedTools)) throw new TypeError('selectedTools must be an array');
187
212
  if (!(loadedToolNames instanceof Set)) throw new TypeError('loadedToolNames must be a Set');
@@ -223,6 +248,12 @@ function createDeferredToolLoader(selectedTools, deferredTools, loadedToolNames
223
248
  matches = searchRelatedDeferredTools([...available.values()], query);
224
249
  relatedFallback = matches.length > 0;
225
250
  }
251
+ if (matches.length === 0) {
252
+ matches = searchRelatedDeferredTools([...available.values()], query, {
253
+ relaxRequiredNameTokens: true,
254
+ });
255
+ relatedFallback = matches.length > 0;
256
+ }
226
257
  if (matches.length === 0) {
227
258
  const alreadyLoaded = query.toLowerCase().startsWith('select:')
228
259
  ? searchDeferredTools(
@@ -277,5 +308,6 @@ module.exports = {
277
308
  deferredToolCatalog,
278
309
  deferredToolNames,
279
310
  mediaGenerationToolNamesForText,
311
+ rememberDeferredToolAfterNotFound,
280
312
  toolSchemaBudgetTokens,
281
313
  };
package/blun.mjs CHANGED
@@ -261310,7 +261310,7 @@ function toolResultText(result) {
261310
261310
  function abandonedToolResultOutput(ended) {
261311
261311
  return `Tool call did not complete: ${ended.reason === "cancelled" ? "the turn was cancelled" : ended.reason === "failed" ? `the turn failed${ended.error !== void 0 ? ` (${ended.error.message})` : ""}` : "the turn ended"} before its result was recorded. Do not assume the tool completed successfully.`;
261312
261312
  }
261313
- var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens, projectRecurringCronHistory, TelegramDeliveryLedger, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
261313
+ var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaGenerationToolNamesForText, rememberDeferredToolAfterNotFound, toolSchemaBudgetTokens, projectRecurringCronHistory, TelegramDeliveryLedger, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
261314
261314
  var init_turn = __esmMin((() => {
261315
261315
  init_dist$4();
261316
261316
  init_src$4();
@@ -261327,7 +261327,7 @@ var init_turn = __esmMin((() => {
261327
261327
  init_tool_result_budget();
261328
261328
  init_user_message_offload();
261329
261329
  init_assistant_message_offload();
261330
- ({ CORE_TOOL_NAMES: BLUN_CORE_TOOL_NAMES, createDeferredToolLoader, mediaGenerationToolNamesForText, toolSchemaBudgetTokens } = createRequire(import.meta.url)("./bin/turn-tool-performance-policy.cjs"));
261330
+ ({ CORE_TOOL_NAMES: BLUN_CORE_TOOL_NAMES, createDeferredToolLoader, mediaGenerationToolNamesForText, rememberDeferredToolAfterNotFound, toolSchemaBudgetTokens } = createRequire(import.meta.url)("./bin/turn-tool-performance-policy.cjs"));
261331
261331
  ({ projectRecurringCronHistory } = createRequire(import.meta.url)("./bin/recurring-cron-history-policy.cjs"));
261332
261332
  ({ TelegramDeliveryLedger } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
261333
261333
  BLUN_LEAN_TOOL_NAMES = new Set(BLUN_CORE_TOOL_NAMES);
@@ -262218,6 +262218,7 @@ var init_turn = __esmMin((() => {
262218
262218
  if (event.type === "tool.result") {
262219
262219
  const started = this.toolCallStartedAt.get(event.toolCallId);
262220
262220
  if (started === void 0) return;
262221
+ rememberDeferredToolAfterNotFound(this.loadedToolNames, started.name, event.result);
262221
262222
  this.toolCallStartedAt.delete(event.toolCallId);
262222
262223
  const dupType = this.toolCallDupType.get(event.toolCallId) ?? "normal";
262223
262224
  this.toolCallDupType.delete(event.toolCallId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.226",
3
+ "version": "9.1.228",
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": {