blun-king-cli 9.1.455 → 9.1.457

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.
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const crypto = require('node:crypto');
4
+ const { extractChecksumClaims } = require('./outbound-claim-provenance.cjs');
4
5
 
5
6
  const PHASES = new Set(['orient', 'plan', 'act', 'verify', 'learn', 'wait']);
6
7
  const EVIDENCE_BASES = new Set([
@@ -237,6 +238,9 @@ function normalizeRuntimeExternalReportSource(input) {
237
238
  throw new TypeError('trusted external report source is invalid');
238
239
  }
239
240
  const reporter = bounded(input.reporter ?? input.reporterId, 'external report reporter', 128);
241
+ const claimTokens = extractChecksumClaims(
242
+ Array.isArray(input.claimTokens) ? input.claimTokens.join(' ') : '',
243
+ );
240
244
  return Object.freeze({
241
245
  source: normalizedExternalReportSource(input.source),
242
246
  chatId: bounded(input.chatId, 'external report chatId', 64),
@@ -244,6 +248,7 @@ function normalizeRuntimeExternalReportSource(input) {
244
248
  reporter,
245
249
  reporterId: bounded(input.reporterId ?? reporter, 'external report reporterId', 128),
246
250
  occurredAt: normalizedTimestamp(input.occurredAt, 'external report occurredAt', true),
251
+ ...(claimTokens.length > 0 ? { claimTokens } : {}),
247
252
  });
248
253
  }
249
254
 
@@ -292,17 +297,8 @@ function normalizeExternalReportOrigin(input) {
292
297
  });
293
298
  }
294
299
 
295
- function resolveExternalReportOrigin(selectorInput, runtimeExternalReports) {
296
- const selector = normalizeExternalReportSelector(selectorInput);
297
- const reports = Array.isArray(runtimeExternalReports)
298
- ? runtimeExternalReports.map(normalizeRuntimeExternalReportSource)
299
- : [];
300
- const report = reports.find((candidate) => candidate.source === selector.source
301
- && candidate.chatId === selector.chatId
302
- && candidate.messageId === selector.messageId);
303
- if (report === undefined) {
304
- throw new TypeError('externalReportSource does not match a trusted external report in the current turn');
305
- }
300
+ function externalReportOriginFromRuntimeSource(input) {
301
+ const report = normalizeRuntimeExternalReportSource(input);
306
302
  const reporterRef = crypto.createHash('sha256')
307
303
  .update(`external-report-reporter:${report.source}\0${report.reporterId}`)
308
304
  .digest('hex')
@@ -320,6 +316,20 @@ function resolveExternalReportOrigin(selectorInput, runtimeExternalReports) {
320
316
  });
321
317
  }
322
318
 
319
+ function resolveExternalReportOrigin(selectorInput, runtimeExternalReports) {
320
+ const selector = normalizeExternalReportSelector(selectorInput);
321
+ const reports = Array.isArray(runtimeExternalReports)
322
+ ? runtimeExternalReports.map(normalizeRuntimeExternalReportSource)
323
+ : [];
324
+ const report = reports.find((candidate) => candidate.source === selector.source
325
+ && candidate.chatId === selector.chatId
326
+ && candidate.messageId === selector.messageId);
327
+ if (report === undefined) {
328
+ throw new TypeError('externalReportSource does not match a trusted external report in the current turn');
329
+ }
330
+ return externalReportOriginFromRuntimeSource(report);
331
+ }
332
+
323
333
  function normalizedEvidenceProducerRef(value, field = 'evidence producer ref') {
324
334
  const ref = String(value ?? '').trim();
325
335
  if (!EVIDENCE_PRODUCER_REF_RE.test(ref)) throw new TypeError(`${field} is invalid`);
@@ -1068,6 +1078,7 @@ module.exports = {
1068
1078
  completionCriterionRef,
1069
1079
  evidenceProducerRef,
1070
1080
  emptyActionEvidenceReceipt,
1081
+ externalReportOriginFromRuntimeSource,
1071
1082
  externalReportSourceFromChannelMeta,
1072
1083
  externalReportSourcesFromOrigin,
1073
1084
  normalizeActionCheckpoint,
@@ -0,0 +1,150 @@
1
+ 'use strict';
2
+
3
+ const MAX_CLAIMS = 32;
4
+ const MAX_CONFLICT_ORIGINS = 8;
5
+ const CHECKSUM_CLAIM_RE = /(?<![A-Za-z0-9])[A-Fa-f0-9]{16,128}(?![A-Za-z0-9])/gu;
6
+ const TELEGRAM_MESSAGE_TOOL_RE = /^mcp__[^\s]*telegram[^\s]*__(?:reply|edit_message)$/iu;
7
+ const REF_RE = /^[a-f0-9]{16}$/u;
8
+ const ISO_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}(?::?\d{2})?)$/u;
9
+
10
+ function extractChecksumClaims(value) {
11
+ const claims = [];
12
+ const seen = new Set();
13
+ const text = typeof value === 'string' ? value : String(value ?? '');
14
+ for (const match of text.matchAll(CHECKSUM_CLAIM_RE)) {
15
+ const claim = match[0].toLowerCase();
16
+ if (seen.has(claim)) continue;
17
+ seen.add(claim);
18
+ claims.push(claim);
19
+ if (claims.length >= MAX_CLAIMS) break;
20
+ }
21
+ return Object.freeze(claims);
22
+ }
23
+
24
+ function boundedText(value, max) {
25
+ const text = String(value ?? '')
26
+ .replace(/[\u0000-\u001f\u007f]+/gu, ' ')
27
+ .replace(/\s+/gu, ' ')
28
+ .trim();
29
+ return text.length > 0 ? text.slice(0, max) : undefined;
30
+ }
31
+
32
+ function optionalRef(value) {
33
+ const ref = String(value ?? '').trim().toLowerCase();
34
+ return REF_RE.test(ref) ? ref : undefined;
35
+ }
36
+
37
+ function optionalTimestamp(value) {
38
+ const timestamp = String(value ?? '').trim();
39
+ return ISO_TIMESTAMP_RE.test(timestamp) ? timestamp : undefined;
40
+ }
41
+
42
+ function normalizedExternalReports(value) {
43
+ if (!Array.isArray(value)) return [];
44
+ const reports = [];
45
+ for (const report of value.slice(0, MAX_CLAIMS)) {
46
+ if (!report || typeof report !== 'object' || Array.isArray(report)) continue;
47
+ const reporter = boundedText(report.reporter, 128);
48
+ const eventRef = optionalRef(report.eventRef);
49
+ const occurredAt = optionalTimestamp(report.occurredAt);
50
+ const claimTokens = extractChecksumClaims(
51
+ Array.isArray(report.claimTokens) ? report.claimTokens.join(' ') : '',
52
+ );
53
+ if (reporter === undefined || eventRef === undefined || occurredAt === undefined || claimTokens.length === 0) continue;
54
+ const reporterRef = optionalRef(report.reporterRef);
55
+ reports.push(Object.freeze({ reporter, reporterRef, eventRef, occurredAt, claimTokens }));
56
+ }
57
+ return reports;
58
+ }
59
+
60
+ function externalClaimOrigin(report) {
61
+ return Object.freeze({
62
+ reporter: report.reporter,
63
+ ...(report.reporterRef !== undefined ? { reporterRef: report.reporterRef } : {}),
64
+ eventRef: report.eventRef,
65
+ occurredAt: report.occurredAt,
66
+ });
67
+ }
68
+
69
+ function assessOutboundClaimProvenance({ text, localClaims = [], externalReports = [] } = {}) {
70
+ const claims = extractChecksumClaims(text);
71
+ const local = new Set(extractChecksumClaims(Array.isArray(localClaims) ? localClaims.join(' ') : ''));
72
+ const reports = normalizedExternalReports(externalReports);
73
+ const localMatches = [];
74
+ const externalMatches = [];
75
+ const conflicted = [];
76
+ const unattributed = [];
77
+
78
+ for (const value of claims) {
79
+ if (local.has(value)) {
80
+ localMatches.push(value);
81
+ continue;
82
+ }
83
+ const matchingByEvent = new Map();
84
+ for (const report of reports) {
85
+ if (report.claimTokens.includes(value) && !matchingByEvent.has(report.eventRef)) {
86
+ matchingByEvent.set(report.eventRef, report);
87
+ }
88
+ }
89
+ const matchingReports = [...matchingByEvent.values()];
90
+ if (matchingReports.length === 0) {
91
+ unattributed.push(value);
92
+ continue;
93
+ }
94
+ if (matchingReports.length > 1) {
95
+ conflicted.push(Object.freeze({
96
+ value,
97
+ totalOrigins: matchingReports.length,
98
+ reports: Object.freeze(
99
+ matchingReports.slice(0, MAX_CONFLICT_ORIGINS).map(externalClaimOrigin),
100
+ ),
101
+ }));
102
+ continue;
103
+ }
104
+ const [report] = matchingReports;
105
+ const external = {
106
+ value,
107
+ ...externalClaimOrigin(report),
108
+ };
109
+ externalMatches.push(Object.freeze(external));
110
+ }
111
+
112
+ return Object.freeze({
113
+ local: Object.freeze(localMatches),
114
+ external: Object.freeze(externalMatches),
115
+ conflicted: Object.freeze(conflicted),
116
+ unattributed: Object.freeze(unattributed),
117
+ });
118
+ }
119
+
120
+ function normalizedToolArgs(input) {
121
+ if (input && typeof input === 'object' && !Array.isArray(input)) return input;
122
+ if (typeof input !== 'string') return undefined;
123
+ try {
124
+ const parsed = JSON.parse(input);
125
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : undefined;
126
+ } catch {
127
+ return undefined;
128
+ }
129
+ }
130
+
131
+ function provenanceAdvisoryForToolCall({ toolName, toolArgs, localClaims, externalReports } = {}) {
132
+ if (!TELEGRAM_MESSAGE_TOOL_RE.test(String(toolName ?? ''))) return null;
133
+ const args = normalizedToolArgs(toolArgs);
134
+ if (args === undefined || typeof args.text !== 'string') return null;
135
+ const assessment = assessOutboundClaimProvenance({
136
+ text: args.text,
137
+ localClaims,
138
+ externalReports,
139
+ });
140
+ if (assessment.external.length === 0
141
+ && assessment.conflicted.length === 0
142
+ && assessment.unattributed.length === 0) return null;
143
+ return Object.freeze({ ...assessment, blocked: false });
144
+ }
145
+
146
+ module.exports = {
147
+ assessOutboundClaimProvenance,
148
+ extractChecksumClaims,
149
+ provenanceAdvisoryForToolCall,
150
+ };
package/blun.mjs CHANGED
@@ -21463,7 +21463,8 @@ var { rollbackPersonalityChoice, setPersonalityEnabledAtomic } = createRequire(i
21463
21463
  var { projectSoulText } = createRequire(import.meta.url)("./bin/soul-organization-policy.cjs");
21464
21464
  var { soulFileInstruction } = createRequire(import.meta.url)("./bin/soul-preservation-policy.cjs");
21465
21465
  var { readProfilePersona, resolveSoulFile } = createRequire(import.meta.url)("./bin/profile-identity-resolution.cjs");
21466
- var { advanceActionEvidenceReceipt, assertActionCheckpointEvidenceBasis, assertActionCheckpointRevision, emptyActionEvidenceReceipt, evidenceProducerRef, externalReportSourcesFromOrigin, normalizeActionCheckpoint, projectActionCheckpoint } = createRequire(import.meta.url)("./bin/cognitive-action-checkpoint.cjs");
21466
+ var { advanceActionEvidenceReceipt, assertActionCheckpointEvidenceBasis, assertActionCheckpointRevision, emptyActionEvidenceReceipt, evidenceProducerRef, externalReportOriginFromRuntimeSource, externalReportSourcesFromOrigin, normalizeActionCheckpoint, projectActionCheckpoint } = createRequire(import.meta.url)("./bin/cognitive-action-checkpoint.cjs");
21467
+ var { extractChecksumClaims, provenanceAdvisoryForToolCall } = createRequire(import.meta.url)("./bin/outbound-claim-provenance.cjs");
21467
21468
  var { evaluateGoalCompletionEvidence } = createRequire(import.meta.url)("./bin/goal-completion-evidence-policy.cjs");
21468
21469
  async function prepareSystemPromptContext(kaos, brandHome, options) {
21469
21470
  const additionalDirs = normalizeAdditionalDirs(options?.additionalDirs ?? []);
@@ -261828,6 +261829,7 @@ var init_turn = __esmMin((() => {
261828
261829
  cognitiveToolBatchesByTurn = /* @__PURE__ */ new Map();
261829
261830
  cognitiveActionEvidenceByTurn = /* @__PURE__ */ new Map();
261830
261831
  cognitiveExternalReportsByTurn = /* @__PURE__ */ new Map();
261832
+ cognitiveLocalClaimsByTurn = /* @__PURE__ */ new Map();
261831
261833
  constructor(agent) {
261832
261834
  this.agent = agent;
261833
261835
  }
@@ -261924,6 +261926,59 @@ var init_turn = __esmMin((() => {
261924
261926
  externalReportSourcesForCurrentTurn() {
261925
261927
  return this.cognitiveExternalReportsByTurn.get(this.currentId) ?? Object.freeze([]);
261926
261928
  }
261929
+ recordLocalClaimTokens(turnId, text) {
261930
+ const incoming = extractChecksumClaims(text);
261931
+ if (incoming.length === 0) return;
261932
+ const current = this.cognitiveLocalClaimsByTurn.get(turnId) ?? [];
261933
+ const merged = [...current];
261934
+ const seen = new Set(current);
261935
+ for (const claim of incoming) {
261936
+ if (seen.has(claim)) continue;
261937
+ seen.add(claim);
261938
+ merged.push(claim);
261939
+ }
261940
+ this.cognitiveLocalClaimsByTurn.set(turnId, Object.freeze(merged.slice(-64)));
261941
+ }
261942
+ externalClaimReportsForCurrentTurn() {
261943
+ return this.externalReportSourcesForCurrentTurn().map((source) => ({
261944
+ ...externalReportOriginFromRuntimeSource(source),
261945
+ claimTokens: source.claimTokens ?? []
261946
+ }));
261947
+ }
261948
+ emitOutboundClaimProvenanceAdvisory(turnId, event) {
261949
+ try {
261950
+ const provenanceAdvisory = provenanceAdvisoryForToolCall({
261951
+ toolName: event.name,
261952
+ toolArgs: event.args,
261953
+ localClaims: this.cognitiveLocalClaimsByTurn.get(turnId) ?? [],
261954
+ externalReports: this.externalClaimReportsForCurrentTurn()
261955
+ });
261956
+ if (provenanceAdvisory === null) return;
261957
+ const external = provenanceAdvisory.external.map((entry) => `${entry.value} (${entry.reporter}; ${entry.eventRef}; ${entry.occurredAt})`).join(", ") || "-";
261958
+ const conflicted = provenanceAdvisory.conflicted.map((entry) => `${entry.value} (${entry.reports.map((report) => `${report.reporter}; ${report.eventRef}; ${report.occurredAt}`).join(" | ")})`).join(", ") || "-";
261959
+ const unattributed = provenanceAdvisory.unattributed.join(", ") || "-";
261960
+ this.agent.emitEvent({
261961
+ type: "warning",
261962
+ code: "OUTBOUND_CLAIM_PROVENANCE",
261963
+ message: uiText("sessionEvent.provenance.advisory", {
261964
+ external,
261965
+ conflicted,
261966
+ unattributed
261967
+ }),
261968
+ blocked: false,
261969
+ details: {
261970
+ blocked: false,
261971
+ external: provenanceAdvisory.external,
261972
+ conflicted: provenanceAdvisory.conflicted,
261973
+ unattributed: provenanceAdvisory.unattributed
261974
+ }
261975
+ });
261976
+ } catch (error) {
261977
+ this.agent.telemetry.track("outbound_claim_provenance_error", {
261978
+ error_type: error?.code ?? error?.name ?? "Error"
261979
+ });
261980
+ }
261981
+ }
261927
261982
  projectCognitiveState(turnId, input) {
261928
261983
  try {
261929
261984
  const focusScopes = cognitiveFocusScopesForTurn(input);
@@ -262437,6 +262492,7 @@ var init_turn = __esmMin((() => {
262437
262492
  this.interruptedTelemetryTurnIds.delete(turnId);
262438
262493
  this.cognitiveActionEvidenceByTurn.delete(turnId);
262439
262494
  this.cognitiveExternalReportsByTurn.delete(turnId);
262495
+ this.cognitiveLocalClaimsByTurn.delete(turnId);
262440
262496
  this.stepFailureByTurn.delete(turnId);
262441
262497
  await this.agent.records.flush();
262442
262498
  return {
@@ -262827,6 +262883,7 @@ var init_turn = __esmMin((() => {
262827
262883
  if (event.type === "tool.call") {
262828
262884
  const dupType = this.trackDuplicateToolCall(turnId, event.step, event.name, event.args);
262829
262885
  this.toolCallDupType.set(event.toolCallId, dupType === "cross_step" ? "cross_step" : "normal");
262886
+ this.emitOutboundClaimProvenanceAdvisory(turnId, event);
262830
262887
  this.toolCallStartedAt.set(event.toolCallId, {
262831
262888
  name: event.name,
262832
262889
  args: event.args,
@@ -262842,6 +262899,7 @@ var init_turn = __esmMin((() => {
262842
262899
  if (event.type === "tool.result") {
262843
262900
  const started = this.toolCallStartedAt.get(event.toolCallId);
262844
262901
  if (started === void 0) return;
262902
+ this.recordLocalClaimTokens(turnId, toolResultText(event.result));
262845
262903
  rememberDeferredToolAfterNotFound(this.loadedToolNames, started.name, event.result);
262846
262904
  this.toolCallStartedAt.delete(event.toolCallId);
262847
262905
  const dupType = this.toolCallDupType.get(event.toolCallId) ?? "normal";
@@ -419288,7 +419346,8 @@ function injectChannelEnvelope(host, envelope, preamble) {
419288
419346
  messageId: envelope.meta.message_id,
419289
419347
  reporter: envelope.meta.user,
419290
419348
  reporterId: envelope.meta.user_id,
419291
- occurredAt: envelope.meta.ts
419349
+ occurredAt: envelope.meta.ts,
419350
+ claimTokens: extractChecksumClaims(envelope.text)
419292
419351
  };
419293
419352
  if (contextOnly) {
419294
419353
  bufferContext(preamble, envelope.meta.chat_id, envelope.tag, reportSource);
@@ -506413,6 +506472,7 @@ registerUiCatalogFragment({
506413
506472
  "sessionEvent.goalQueue.blockedTitle": "Goal blocked.",
506414
506473
  "sessionEvent.goalQueue.blockedDetail": "The next queued goal will start only after this goal is complete.",
506415
506474
  "sessionEvent.warning": "Warning: {message}",
506475
+ "sessionEvent.provenance.advisory": "Source check before sending; the message was not blocked. Forwarded report: {external}. Ambiguous source events: {conflicted}. Not found in this turn's tool output or a source event: {unattributed}. Forwarding is allowed, but do not present these values as your own measurement.",
506416
506476
  "sessionEvent.mcp.tool.one": "{count} tool",
506417
506477
  "sessionEvent.mcp.tool.other": "{count} tools",
506418
506478
  "sessionEvent.mcp.connected": "MCP server \"{name}\" connected · {tools} ({transport})",
@@ -506443,6 +506503,7 @@ registerUiCatalogFragment({
506443
506503
  "sessionEvent.goalQueue.blockedTitle": "Ziel blockiert.",
506444
506504
  "sessionEvent.goalQueue.blockedDetail": "Das nächste vorgemerkte Ziel startet erst, wenn dieses Ziel abgeschlossen ist.",
506445
506505
  "sessionEvent.warning": "Warnung: {message}",
506506
+ "sessionEvent.provenance.advisory": "Herkunftsprüfung vor dem Senden; die Nachricht wurde nicht blockiert. Weitergeleiteter Bericht: {external}. Mehrdeutige Quellereignisse: {conflicted}. Weder in einer Werkzeugausgabe dieses Durchlaufs noch in einem Quellereignis gefunden: {unattributed}. Die Weitergabe ist erlaubt, diese Werte dürfen jedoch nicht als eigene Messung dargestellt werden.",
506446
506507
  "sessionEvent.mcp.tool.one": "{count} Tool",
506447
506508
  "sessionEvent.mcp.tool.other": "{count} Tools",
506448
506509
  "sessionEvent.mcp.connected": "MCP-Server „{name}“ verbunden · {tools} ({transport})",
@@ -506473,6 +506534,7 @@ registerUiCatalogFragment({
506473
506534
  "sessionEvent.goalQueue.blockedTitle": "Objetivo bloqueado.",
506474
506535
  "sessionEvent.goalQueue.blockedDetail": "El siguiente objetivo en cola no se iniciará hasta que este objetivo se complete.",
506475
506536
  "sessionEvent.warning": "Advertencia: {message}",
506537
+ "sessionEvent.provenance.advisory": "Comprobación de procedencia antes de enviar; el mensaje no se bloqueó. Informe reenviado: {external}. Eventos de origen ambiguos: {conflicted}. No se encontraron en la salida de las herramientas de este turno ni en un evento de origen: {unattributed}. Se permite reenviar estos valores, pero no presentarlos como mediciones propias.",
506476
506538
  "sessionEvent.mcp.tool.one": "{count} herramienta",
506477
506539
  "sessionEvent.mcp.tool.other": "{count} herramientas",
506478
506540
  "sessionEvent.mcp.connected": "Servidor MCP «{name}» conectado · {tools} ({transport})",
@@ -506503,6 +506565,7 @@ registerUiCatalogFragment({
506503
506565
  "sessionEvent.goalQueue.blockedTitle": "Objectif bloqué.",
506504
506566
  "sessionEvent.goalQueue.blockedDetail": "L’objectif suivant ne démarrera qu’une fois cet objectif terminé.",
506505
506567
  "sessionEvent.warning": "Avertissement : {message}",
506568
+ "sessionEvent.provenance.advisory": "Vérification de la provenance avant l’envoi ; le message n’a pas été bloqué. Rapport transmis : {external}. Événements source ambigus : {conflicted}. Valeurs introuvables dans la sortie des outils de ce tour et dans les événements source : {unattributed}. Leur transmission est autorisée, mais ne les présentez pas comme vos propres mesures.",
506506
506569
  "sessionEvent.mcp.tool.one": "{count} outil",
506507
506570
  "sessionEvent.mcp.tool.other": "{count} outils",
506508
506571
  "sessionEvent.mcp.connected": "Serveur MCP « {name} » connecté · {tools} ({transport})",
@@ -506533,6 +506596,7 @@ registerUiCatalogFragment({
506533
506596
  "sessionEvent.goalQueue.blockedTitle": "Målet är blockerat.",
506534
506597
  "sessionEvent.goalQueue.blockedDetail": "Nästa köade mål startar först när det här målet är slutfört.",
506535
506598
  "sessionEvent.warning": "Varning: {message}",
506599
+ "sessionEvent.provenance.advisory": "Ursprungskontroll före sändning; meddelandet blockerades inte. Vidarebefordrad rapport: {external}. Tvetydiga källhändelser: {conflicted}. Hittades varken i verktygsutdata från den här körningen eller i en källhändelse: {unattributed}. Värdena får vidarebefordras, men framställ dem inte som egna mätningar.",
506536
506600
  "sessionEvent.mcp.tool.one": "{count} verktyg",
506537
506601
  "sessionEvent.mcp.tool.other": "{count} verktyg",
506538
506602
  "sessionEvent.mcp.connected": "MCP-servern ”{name}” är ansluten · {tools} ({transport})",
@@ -506563,6 +506627,7 @@ registerUiCatalogFragment({
506563
506627
  "sessionEvent.goalQueue.blockedTitle": "Cíl je blokován.",
506564
506628
  "sessionEvent.goalQueue.blockedDetail": "Další cíl ve frontě se spustí pouze po dokončení tohoto cíle.",
506565
506629
  "sessionEvent.warning": "Upozornění: {message}",
506630
+ "sessionEvent.provenance.advisory": "Kontrola původu před odesláním; zpráva nebyla zablokována. Předaný report: {external}. Nejednoznačné zdrojové události: {conflicted}. Nenalezeno ve výstupu nástrojů tohoto kola ani ve zdrojové události: {unattributed}. Tyto hodnoty lze předat dál, ale neuvádějte je jako vlastní měření.",
506566
506631
  "sessionEvent.mcp.tool.one": "Nástroje: {count}",
506567
506632
  "sessionEvent.mcp.tool.other": "Nástroje: {count}",
506568
506633
  "sessionEvent.mcp.connected": "Server MCP \"{name}\" připojen · {tools} ({transport})",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.455",
3
+ "version": "9.1.457",
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": {