blun-king-cli 9.1.180 → 9.1.182

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.
@@ -27,13 +27,19 @@ function launcherModeFromArgv(argv) {
27
27
  function createLauncherEnvironment(sourceEnv, mode, publicPackageVersion) {
28
28
  return {
29
29
  ...sourceEnv,
30
- BLUN_NO_AUTO_UPDATE: '1',
31
30
  BLUN_PUBLIC_PACKAGE_VERSION: publicPackageVersion,
32
31
  BLUN_TELEGRAM_ATTACH: mode === LAUNCHER_MODES.KING ? 'on' : 'off',
33
32
  BLUN_TELEGRAM_HEADLESS: 'off',
34
33
  };
35
34
  }
36
35
 
36
+ function createProtectedCoreEnvironment(sourceEnv) {
37
+ return {
38
+ ...sourceEnv,
39
+ BLUN_NO_AUTO_UPDATE: '1',
40
+ };
41
+ }
42
+
37
43
  function isNpmPackageUpdateRequest(args) {
38
44
  if (!Array.isArray(args) || args.length !== 1) return false;
39
45
  const command = String(args[0] || '').toLowerCase();
@@ -47,6 +53,7 @@ function launcherHelpText() {
47
53
  module.exports = {
48
54
  LAUNCHER_MODES,
49
55
  createLauncherEnvironment,
56
+ createProtectedCoreEnvironment,
50
57
  isNpmPackageUpdateRequest,
51
58
  launcherHelpText,
52
59
  launcherModeFromArgv,
@@ -11,6 +11,7 @@ const { spawn } = require('node:child_process');
11
11
  const {
12
12
  LAUNCHER_MODES,
13
13
  createLauncherEnvironment,
14
+ createProtectedCoreEnvironment,
14
15
  isNpmPackageUpdateRequest,
15
16
  launcherHelpText,
16
17
  launcherModeFromArgv,
@@ -18,6 +19,7 @@ const {
18
19
  const { installManagedTelegramPlugin } = require('./plugin-bootstrap');
19
20
  const {
20
21
  availableStandardToolNames,
22
+ seedConfiguredMnemoMcp,
21
23
  seedStandardSkills,
22
24
  seedStandardTools,
23
25
  } = require('./standard-tools-bootstrap');
@@ -178,7 +180,7 @@ function spawnProtectedCore(args, env, cwd, options = {}) {
178
180
  {
179
181
  cwd,
180
182
  detached: shouldDetachProtectedCore(),
181
- env,
183
+ env: createProtectedCoreEnvironment(env),
182
184
  stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
183
185
  windowsHide: true,
184
186
  },
@@ -683,6 +685,7 @@ async function runLauncher(options = {}) {
683
685
  blunDir,
684
686
  names: standardMcpNames,
685
687
  });
688
+ seedConfiguredMnemoMcp({ blunDir, env: process.env });
686
689
 
687
690
  // --- 4. Eigenes BLUN-Grunddesign als einzigen Standard-Skill installieren
688
691
  seedStandardSkills({ packageRoot: PKG, blunDir: privatePaths.sharedHome });
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const LONG_DUPLICATE_MIN_CHARS = 512;
4
+
5
+ function userMessageText(message) {
6
+ if (
7
+ message?.role !== 'user'
8
+ || message.origin?.kind !== 'user'
9
+ || !Array.isArray(message.content)
10
+ ) return '';
11
+
12
+ const textParts = message.content
13
+ .filter((part) => part?.type === 'text' && typeof part.text === 'string')
14
+ .map((part) => part.text);
15
+ return textParts.length > 0 ? textParts.join('\n') : '';
16
+ }
17
+
18
+ function channelAttribute(attributes, name) {
19
+ const match = String(attributes).match(new RegExp(`(?:^|\\s)${name}="([^"]+)"`, 'u'));
20
+ return match?.[1] ?? '';
21
+ }
22
+
23
+ function telegramDeliveryIdentity(text) {
24
+ const channel = String(text).match(/<channel\b([^>]*)>/u);
25
+ if (channel === null) return '';
26
+
27
+ const source = channelAttribute(channel[1], 'source');
28
+ const chatId = channelAttribute(channel[1], 'chat_id');
29
+ const messageId = channelAttribute(channel[1], 'message_id');
30
+ if (source !== 'telegram' || !chatId || !messageId) return '';
31
+ return `${chatId}:${messageId}`;
32
+ }
33
+
34
+ function repeatedUserMessageKey(message) {
35
+ const text = userMessageText(message);
36
+ if (!text) return '';
37
+
38
+ const telegramIdentity = telegramDeliveryIdentity(text);
39
+ if (telegramIdentity) return `telegram:${telegramIdentity}`;
40
+ return text.length >= LONG_DUPLICATE_MIN_CHARS ? `text:${text}` : '';
41
+ }
42
+
43
+ function dedupeRepeatedUserMessages(messages) {
44
+ if (!Array.isArray(messages) || messages.length < 2) return messages;
45
+
46
+ const lastIndexByKey = new Map();
47
+ const keys = messages.map((message, index) => {
48
+ const key = repeatedUserMessageKey(message);
49
+ if (key) lastIndexByKey.set(key, index);
50
+ return key;
51
+ });
52
+
53
+ let changed = false;
54
+ const projected = messages.filter((message, index) => {
55
+ const key = keys[index];
56
+ const keep = !key || lastIndexByKey.get(key) === index;
57
+ if (!keep) changed = true;
58
+ return keep;
59
+ });
60
+ return changed ? projected : messages;
61
+ }
62
+
63
+ module.exports = {
64
+ LONG_DUPLICATE_MIN_CHARS,
65
+ dedupeRepeatedUserMessages,
66
+ telegramDeliveryIdentity,
67
+ userMessageText,
68
+ };
@@ -255,6 +255,44 @@ function seedStandardTools({
255
255
  return { added, updated, configPath };
256
256
  }
257
257
 
258
+ function seedConfiguredMnemoMcp({
259
+ blunDir,
260
+ env = process.env,
261
+ execPath = process.execPath,
262
+ }) {
263
+ const configPath = path.join(blunDir, 'mcp.json');
264
+ const entry = typeof env.BLUN_MNEMO_MCP === 'string' ? env.BLUN_MNEMO_MCP.trim() : '';
265
+ const agent = typeof env.BLUN_MNEMO_AGENT === 'string' ? env.BLUN_MNEMO_AGENT.trim() : '';
266
+ if (entry.length === 0 || agent.length === 0) {
267
+ return { added: false, reason: 'not_configured', configPath };
268
+ }
269
+ if (!fs.existsSync(entry)) return { added: false, reason: 'entry_missing', configPath };
270
+
271
+ ensurePrivateDirectory(blunDir);
272
+ if (fs.existsSync(configPath)) securePrivateFile(configPath);
273
+ const document = readMcpDocument(configPath);
274
+ const servers = { ...document.mcpServers };
275
+ const equivalent = Object.values(servers).some((config) => (
276
+ isObject(config)
277
+ && Array.isArray(config.args)
278
+ && config.args.some((argument) => argument === entry)
279
+ ));
280
+ if (Object.hasOwn(servers, 'mnemo') || equivalent) {
281
+ return { added: false, reason: 'already_configured', configPath };
282
+ }
283
+
284
+ const configuredNode = typeof env.BLUN_MNEMO_NODE === 'string'
285
+ ? env.BLUN_MNEMO_NODE.trim()
286
+ : '';
287
+ servers.mnemo = {
288
+ command: configuredNode || execPath,
289
+ args: [entry],
290
+ env: { MNEMO_AGENT: agent },
291
+ };
292
+ writeMcpDocument(configPath, { ...document, mcpServers: servers });
293
+ return { added: true, reason: 'added', configPath };
294
+ }
295
+
258
296
  function seedStandardSkills({ packageRoot, blunDir }) {
259
297
  const sourceRoot = path.join(packageRoot, 'standard-skills');
260
298
  const sourceRootStat = fs.lstatSync(sourceRoot);
@@ -344,6 +382,7 @@ function seedStandardDesignSkill(options) {
344
382
  module.exports = {
345
383
  availableStandardToolNames,
346
384
  readCatalogue,
385
+ seedConfiguredMnemoMcp,
347
386
  seedStandardDesignSkill,
348
387
  seedStandardSkills,
349
388
  seedStandardTools,
package/blun.mjs CHANGED
@@ -75985,11 +75985,12 @@ var init_full = __esmMin((() => {
75985
75985
  }));
75986
75986
  //#endregion
75987
75987
  //#region ../../packages/agent-core/src/agent/compaction/micro.ts
75988
- var selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS, isPersistedToolResultReference, projectHistoricalUnaddressedTelegramMessages, compactHistoricalSkillActivations, dedupeRecurringCronWakeups, dedupeRepeatedInjections, DEFAULT_CONFIG, MicroCompaction;
75988
+ var selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS, isPersistedToolResultReference, projectHistoricalUnaddressedTelegramMessages, dedupeRepeatedUserMessages, compactHistoricalSkillActivations, dedupeRecurringCronWakeups, dedupeRepeatedInjections, DEFAULT_CONFIG, MicroCompaction;
75989
75989
  var init_micro = __esmMin((() => {
75990
75990
  ({ selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS } = createRequire(import.meta.url)("./bin/micro-compaction-policy.cjs"));
75991
75991
  ({ isPersistedToolResultReference } = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs"));
75992
75992
  ({ projectHistoricalUnaddressedTelegramMessages } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs"));
75993
+ ({ dedupeRepeatedUserMessages } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
75993
75994
  ({ compactHistoricalSkillActivations } = createRequire(import.meta.url)("./bin/skill-activation-performance-policy.cjs"));
75994
75995
  ({ dedupeRecurringCronWakeups, dedupeRepeatedInjections } = createRequire(import.meta.url)("./bin/repeated-injection-projection.cjs"));
75995
75996
  init_tokens();
@@ -78967,7 +78968,8 @@ var init_context$2 = __esmMin((() => {
78967
78968
  const anomalies = [];
78968
78969
  const userOffloaded = this.agent.userMessageOffload.compact(messages);
78969
78970
  const historicalUserReferencesProjected = compactHistoricalPersistedUserMessageReferences(userOffloaded);
78970
- const historicalTelegramProjected = projectHistoricalUnaddressedTelegramMessages(historicalUserReferencesProjected);
78971
+ const duplicateUserMessagesProjected = dedupeRepeatedUserMessages(historicalUserReferencesProjected);
78972
+ const historicalTelegramProjected = projectHistoricalUnaddressedTelegramMessages(duplicateUserMessagesProjected);
78971
78973
  const result = project(this.agent.assistantMessageOffload.compact(this.agent.microCompaction.compact(compactHistoricalSuccessfulToolResults(this.agent.toolResultBatchOffload.compact(dedupeRecurringCronWakeups(dedupeRepeatedInjections(compactHistoricalSkillActivations(compactBaselineSkillInjections(historicalTelegramProjected)))))))), {
78972
78974
  ...options,
78973
78975
  onAnomaly: (anomaly) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.180",
3
+ "version": "9.1.182",
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": {