metheus-governance-mcp-cli 0.2.178 → 0.2.180
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/cli.mjs +1 -0
- package/lib/runner-runtime.mjs +72 -1
- package/lib/selftest-telegram-e2e.mjs +139 -9
- package/package.json +1 -1
package/cli.mjs
CHANGED
package/lib/runner-runtime.mjs
CHANGED
|
@@ -42,6 +42,10 @@ function firstNonEmptyString(values) {
|
|
|
42
42
|
return "";
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function normalizeMentionSelector(rawValue) {
|
|
46
|
+
return String(rawValue || "").trim().replace(/^@+/, "").toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
|
|
45
49
|
function normalizeRunnerSharedInboxKey({ provider, bot, route }) {
|
|
46
50
|
const normalizedProvider = String(provider || route?.provider || "").trim().toLowerCase() || "telegram";
|
|
47
51
|
const botSelector = firstNonEmptyString([
|
|
@@ -60,6 +64,66 @@ function normalizeRunnerSharedInboxKey({ provider, bot, route }) {
|
|
|
60
64
|
return `${normalizedProvider}::${botSelector}`;
|
|
61
65
|
}
|
|
62
66
|
|
|
67
|
+
function buildRouteBotUsernameCandidates(bot, route) {
|
|
68
|
+
return Array.from(new Set(
|
|
69
|
+
[
|
|
70
|
+
bot?.username,
|
|
71
|
+
bot?.name,
|
|
72
|
+
route?.botName,
|
|
73
|
+
route?.serverBotName,
|
|
74
|
+
]
|
|
75
|
+
.map((value) => normalizeMentionSelector(value))
|
|
76
|
+
.filter(Boolean),
|
|
77
|
+
));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function shouldImportManagedBotMessageForRoute({
|
|
81
|
+
update,
|
|
82
|
+
bot,
|
|
83
|
+
route,
|
|
84
|
+
managedConversationBots,
|
|
85
|
+
}) {
|
|
86
|
+
const normalizedUpdate = safeObject(update);
|
|
87
|
+
if (normalizedUpdate.fromIsBot !== true) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
const managedSelectors = new Set(
|
|
91
|
+
ensureArray(managedConversationBots)
|
|
92
|
+
.flatMap((entry) => [
|
|
93
|
+
safeObject(entry).username,
|
|
94
|
+
safeObject(entry).display_name,
|
|
95
|
+
safeObject(safeObject(entry).bot).username,
|
|
96
|
+
safeObject(safeObject(entry).bot).name,
|
|
97
|
+
safeObject(safeObject(entry).route).botName,
|
|
98
|
+
safeObject(safeObject(entry).route).serverBotName,
|
|
99
|
+
])
|
|
100
|
+
.map((value) => normalizeMentionSelector(value))
|
|
101
|
+
.filter(Boolean),
|
|
102
|
+
);
|
|
103
|
+
const senderSelector = normalizeMentionSelector(normalizedUpdate.fromUsername);
|
|
104
|
+
if (!senderSelector || !managedSelectors.has(senderSelector)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const currentBotSelectors = new Set(buildRouteBotUsernameCandidates(bot, route));
|
|
108
|
+
if (!currentBotSelectors.size) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (currentBotSelectors.has(senderSelector)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
const explicitMentions = ensureArray(normalizedUpdate.mentionUsernames)
|
|
115
|
+
.map((value) => normalizeMentionSelector(value))
|
|
116
|
+
.filter(Boolean);
|
|
117
|
+
if (explicitMentions.some((value) => currentBotSelectors.has(value))) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
const replyTargetSelector = normalizeMentionSelector(normalizedUpdate.replyToFromUsername);
|
|
121
|
+
if (normalizedUpdate.replyToFromIsBot === true && replyTargetSelector && currentBotSelectors.has(replyTargetSelector)) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
63
127
|
function normalizeSharedInboxUpdate(rawUpdate) {
|
|
64
128
|
const update = safeObject(rawUpdate);
|
|
65
129
|
const updateID = intFromRawAllowZero(update.updateID ?? update.update_id, 0);
|
|
@@ -270,6 +334,7 @@ export async function archiveLocalTelegramMessagesForRoute({
|
|
|
270
334
|
bot,
|
|
271
335
|
destination,
|
|
272
336
|
archiveThread,
|
|
337
|
+
managedConversationBots = [],
|
|
273
338
|
deps,
|
|
274
339
|
}) {
|
|
275
340
|
const loadProviderEnvConfig = requireDependency(deps, "loadProviderEnvConfig");
|
|
@@ -407,7 +472,13 @@ export async function archiveLocalTelegramMessagesForRoute({
|
|
|
407
472
|
handledUpdateID = Math.max(handledUpdateID, updateID);
|
|
408
473
|
continue;
|
|
409
474
|
}
|
|
410
|
-
|
|
475
|
+
const allowManagedBotImport = shouldImportManagedBotMessageForRoute({
|
|
476
|
+
update,
|
|
477
|
+
bot,
|
|
478
|
+
route,
|
|
479
|
+
managedConversationBots,
|
|
480
|
+
});
|
|
481
|
+
if (boolFromRaw(archivePolicy.skipBotMessages, true) && update.fromIsBot && !allowManagedBotImport) {
|
|
411
482
|
handledUpdateID = Math.max(handledUpdateID, updateID);
|
|
412
483
|
continue;
|
|
413
484
|
}
|
|
@@ -602,15 +602,145 @@ export async function runSelftestTelegramE2E(push, deps) {
|
|
|
602
602
|
deps: buildRunnerRuntimeDeps(),
|
|
603
603
|
});
|
|
604
604
|
const sharedInboxBodies = telegramE2EServer.state.comments.map((item) => String(item.body || ""));
|
|
605
|
-
push(
|
|
606
|
-
"telegram_shared_inbox_fans_out_updates_across_routes_for_same_bot",
|
|
607
|
-
sharedInboxBodies.some((item) => item.includes("message_id: 71"))
|
|
608
|
-
&& sharedInboxBodies.some((item) => item.includes("message_id: 72")),
|
|
609
|
-
`comments=${sharedInboxBodies.length} bodies=${sharedInboxBodies.join(" || ")}`,
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
605
|
+
push(
|
|
606
|
+
"telegram_shared_inbox_fans_out_updates_across_routes_for_same_bot",
|
|
607
|
+
sharedInboxBodies.some((item) => item.includes("message_id: 71"))
|
|
608
|
+
&& sharedInboxBodies.some((item) => item.includes("message_id: 72")),
|
|
609
|
+
`comments=${sharedInboxBodies.length} bodies=${sharedInboxBodies.join(" || ")}`,
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
telegramE2EServer.state.comments = [];
|
|
613
|
+
telegramE2EServer.state.updates = [
|
|
614
|
+
{
|
|
615
|
+
update_id: 401,
|
|
616
|
+
message: {
|
|
617
|
+
message_id: 81,
|
|
618
|
+
date: Math.floor(Date.now() / 1000),
|
|
619
|
+
chat: {
|
|
620
|
+
id: Number(e2eDestination.chat_id),
|
|
621
|
+
type: "supergroup",
|
|
622
|
+
title: e2eDestination.label,
|
|
623
|
+
},
|
|
624
|
+
from: {
|
|
625
|
+
id: 6001,
|
|
626
|
+
is_bot: true,
|
|
627
|
+
first_name: "Lead Bot",
|
|
628
|
+
username: "lead_monitor_bot",
|
|
629
|
+
},
|
|
630
|
+
text: `@${String("PeerMonitorBot").replace(/^@+/, "")} please summarize the project`,
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
];
|
|
634
|
+
await archiveLocalTelegramMessagesForRoute({
|
|
635
|
+
routeKey: runnerRouteKey(normalizeRunnerRoute({
|
|
636
|
+
...e2eRoute,
|
|
637
|
+
name: "selftest-runner-e2e-managed-bot-mention-import",
|
|
638
|
+
server_bot_name: "PeerMonitorBot",
|
|
639
|
+
})),
|
|
640
|
+
route: {
|
|
641
|
+
...e2eRoute,
|
|
642
|
+
name: "selftest-runner-e2e-managed-bot-mention-import",
|
|
643
|
+
server_bot_name: "PeerMonitorBot",
|
|
644
|
+
},
|
|
645
|
+
routeState: {},
|
|
646
|
+
runtime: {
|
|
647
|
+
baseURL: telegramE2EServer.baseURL,
|
|
648
|
+
timeoutSeconds: 10,
|
|
649
|
+
token: e2eToken,
|
|
650
|
+
actor: {
|
|
651
|
+
user_id: e2eActorUserID,
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
bot: {
|
|
655
|
+
id: "66666666-6666-4666-8666-666666666666",
|
|
656
|
+
name: "PeerMonitorBot",
|
|
657
|
+
role: "monitor",
|
|
658
|
+
},
|
|
659
|
+
destination: {
|
|
660
|
+
chatID: e2eDestination.chat_id,
|
|
661
|
+
},
|
|
662
|
+
archiveThread: {
|
|
663
|
+
threadID: e2eThreadID,
|
|
664
|
+
},
|
|
665
|
+
managedConversationBots: [
|
|
666
|
+
{ username: "lead_monitor_bot" },
|
|
667
|
+
{ username: "PeerMonitorBot" },
|
|
668
|
+
],
|
|
669
|
+
deps: buildRunnerRuntimeDeps(),
|
|
670
|
+
});
|
|
671
|
+
push(
|
|
672
|
+
"telegram_managed_bot_public_delegate_is_imported_even_when_skip_bot_messages_is_true",
|
|
673
|
+
telegramE2EServer.state.comments.some((item) => String(item.body || "").includes("message_id: 81")),
|
|
674
|
+
`comments=${telegramE2EServer.state.comments.length}`,
|
|
675
|
+
);
|
|
676
|
+
|
|
677
|
+
telegramE2EServer.state.comments = [];
|
|
678
|
+
telegramE2EServer.state.updates = [
|
|
679
|
+
{
|
|
680
|
+
update_id: 402,
|
|
681
|
+
message: {
|
|
682
|
+
message_id: 82,
|
|
683
|
+
date: Math.floor(Date.now() / 1000),
|
|
684
|
+
chat: {
|
|
685
|
+
id: Number(e2eDestination.chat_id),
|
|
686
|
+
type: "supergroup",
|
|
687
|
+
title: e2eDestination.label,
|
|
688
|
+
},
|
|
689
|
+
from: {
|
|
690
|
+
id: 6002,
|
|
691
|
+
is_bot: true,
|
|
692
|
+
first_name: "External Bot",
|
|
693
|
+
username: "external_random_bot",
|
|
694
|
+
},
|
|
695
|
+
text: `@${String("PeerMonitorBot").replace(/^@+/, "")} hello from outside`,
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
];
|
|
699
|
+
await archiveLocalTelegramMessagesForRoute({
|
|
700
|
+
routeKey: runnerRouteKey(normalizeRunnerRoute({
|
|
701
|
+
...e2eRoute,
|
|
702
|
+
name: "selftest-runner-e2e-unmanaged-bot-skip",
|
|
703
|
+
server_bot_name: "PeerMonitorBot",
|
|
704
|
+
})),
|
|
705
|
+
route: {
|
|
706
|
+
...e2eRoute,
|
|
707
|
+
name: "selftest-runner-e2e-unmanaged-bot-skip",
|
|
708
|
+
server_bot_name: "PeerMonitorBot",
|
|
709
|
+
},
|
|
710
|
+
routeState: {},
|
|
711
|
+
runtime: {
|
|
712
|
+
baseURL: telegramE2EServer.baseURL,
|
|
713
|
+
timeoutSeconds: 10,
|
|
714
|
+
token: e2eToken,
|
|
715
|
+
actor: {
|
|
716
|
+
user_id: e2eActorUserID,
|
|
717
|
+
},
|
|
718
|
+
},
|
|
719
|
+
bot: {
|
|
720
|
+
id: "77777777-7777-4777-8777-777777777777",
|
|
721
|
+
name: "PeerMonitorBot",
|
|
722
|
+
role: "monitor",
|
|
723
|
+
},
|
|
724
|
+
destination: {
|
|
725
|
+
chatID: e2eDestination.chat_id,
|
|
726
|
+
},
|
|
727
|
+
archiveThread: {
|
|
728
|
+
threadID: e2eThreadID,
|
|
729
|
+
},
|
|
730
|
+
managedConversationBots: [
|
|
731
|
+
{ username: "lead_monitor_bot" },
|
|
732
|
+
{ username: "PeerMonitorBot" },
|
|
733
|
+
],
|
|
734
|
+
deps: buildRunnerRuntimeDeps(),
|
|
735
|
+
});
|
|
736
|
+
push(
|
|
737
|
+
"telegram_unmanaged_bot_message_remains_skipped_when_skip_bot_messages_is_true",
|
|
738
|
+
telegramE2EServer.state.comments.length === 0,
|
|
739
|
+
`comments=${telegramE2EServer.state.comments.length}`,
|
|
740
|
+
);
|
|
741
|
+
} catch (err) {
|
|
742
|
+
push("telegram_runner_e2e_local_mock", false, String(err?.message || err));
|
|
743
|
+
} finally {
|
|
614
744
|
try {
|
|
615
745
|
await telegramE2EServer?.close?.();
|
|
616
746
|
} catch {}
|