blun-king-cli 9.1.49 → 9.1.51
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 +30 -6
- package/README.md +30 -6
- package/blun.mjs +538 -81
- package/package.json +1 -1
- package/telegram-plugin/dist/mcp-server.mjs +40 -3
package/package.json
CHANGED
|
@@ -73603,8 +73603,9 @@ async function runTool(api, token, name, args) {
|
|
|
73603
73603
|
* Idempotency guard: models occasionally call reply multiple times with the
|
|
73604
73604
|
* same text. A message that
|
|
73605
73605
|
* innerhalb des Fensters bereits wortgleich an denselben Chat ging, wird nicht
|
|
73606
|
-
* erneut gesendet — das Tool meldet dem Modell "bereits zugestellt", damit es
|
|
73607
|
-
* nicht weiter retryt.
|
|
73606
|
+
* erneut gesendet — das Tool meldet dem Modell "bereits zugestellt", damit es
|
|
73607
|
+
* nicht weiter retryt. Bereits automatisch gelieferte Dateien werden aus
|
|
73608
|
+
* einem direkt folgenden manuellen Reply entfernt.
|
|
73608
73609
|
*/
|
|
73609
73610
|
const DUPLICATE_WINDOW_MS = 3e5;
|
|
73610
73611
|
const OUTBOX_TAIL_BYTES = 32768;
|
|
@@ -73629,13 +73630,49 @@ function isRecentDuplicate(chatId, text) {
|
|
|
73629
73630
|
} catch {}
|
|
73630
73631
|
return false;
|
|
73631
73632
|
}
|
|
73633
|
+
function recentlyDeliveredFiles(chatId, files) {
|
|
73634
|
+
if (files.length === 0) return /* @__PURE__ */ new Set();
|
|
73635
|
+
const wanted = new Map(files.map((file) => [resolve(file).toLowerCase(), file]));
|
|
73636
|
+
const delivered = /* @__PURE__ */ new Set();
|
|
73637
|
+
try {
|
|
73638
|
+
const file = outboxLog();
|
|
73639
|
+
const size = statSync(file).size;
|
|
73640
|
+
const raw = readFileSync(file, "utf8");
|
|
73641
|
+
const tail = size > OUTBOX_TAIL_BYTES ? raw.slice(raw.length - OUTBOX_TAIL_BYTES) : raw;
|
|
73642
|
+
const cutoff = Date.now() - DUPLICATE_WINDOW_MS;
|
|
73643
|
+
for (const line of tail.split("\n")) {
|
|
73644
|
+
if (line.trim().length === 0) continue;
|
|
73645
|
+
try {
|
|
73646
|
+
const entry = JSON.parse(line);
|
|
73647
|
+
if (String(entry.chat_id) !== String(chatId)) continue;
|
|
73648
|
+
if (entry.ts === void 0 || Date.parse(entry.ts) < cutoff || !Array.isArray(entry.files)) continue;
|
|
73649
|
+
for (const priorFile of entry.files) {
|
|
73650
|
+
if (typeof priorFile !== "string") continue;
|
|
73651
|
+
const original = wanted.get(resolve(priorFile).toLowerCase());
|
|
73652
|
+
if (original !== void 0) delivered.add(original);
|
|
73653
|
+
}
|
|
73654
|
+
} catch {}
|
|
73655
|
+
}
|
|
73656
|
+
} catch {}
|
|
73657
|
+
return delivered;
|
|
73658
|
+
}
|
|
73632
73659
|
async function runReply(api, args) {
|
|
73633
73660
|
const chatId = args["chat_id"];
|
|
73634
73661
|
const text = args["text"];
|
|
73635
73662
|
const replyTo = args["reply_to"] !== null && args["reply_to"] !== void 0 ? Number(args["reply_to"]) : void 0;
|
|
73636
|
-
|
|
73663
|
+
let files = args["files"] ?? [];
|
|
73637
73664
|
const parseMode = args["format"] === "markdownv2" ? "MarkdownV2" : void 0;
|
|
73638
73665
|
assertAllowedChat(chatId);
|
|
73666
|
+
const duplicateFiles = recentlyDeliveredFiles(chatId, files);
|
|
73667
|
+
if (duplicateFiles.size > 0) {
|
|
73668
|
+
files = files.filter((file) => !duplicateFiles.has(file));
|
|
73669
|
+
appendJsonl(outboxLog(), {
|
|
73670
|
+
direction: "out",
|
|
73671
|
+
kind: "reply-file-duplicate-suppressed",
|
|
73672
|
+
chat_id: chatId,
|
|
73673
|
+
files: [...duplicateFiles]
|
|
73674
|
+
});
|
|
73675
|
+
}
|
|
73639
73676
|
if (files.length === 0 && isGroupChat(chatId) && isGroupNoiseReply(text)) {
|
|
73640
73677
|
appendJsonl(outboxLog(), {
|
|
73641
73678
|
direction: "out",
|