metheus-governance-mcp-cli 0.2.91 → 0.2.93
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/README.md +21 -19
- package/cli.mjs +168 -21
- package/lib/bot-commands.mjs +21 -3
- package/lib/selftest-bot-commands.mjs +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ Install creates local provider settings templates here:
|
|
|
31
31
|
These files are for local provider bot secrets, local transport options, and optional per-bot local AI binding.
|
|
32
32
|
|
|
33
33
|
- Store locally:
|
|
34
|
-
- `TELEGRAM_BOT_TOKEN` or named Telegram bot mappings such as `
|
|
34
|
+
- `TELEGRAM_BOT_TOKEN` or named Telegram bot mappings such as `TELEGRAM_BOT_RYOAI_TOKEN`
|
|
35
35
|
- `SLACK_BOT_TOKEN`
|
|
36
36
|
- `KAKAOTALK_BOT_TOKEN`
|
|
37
37
|
- Server-side Metheus stores project chat destination metadata separately:
|
|
@@ -48,21 +48,21 @@ Example templates:
|
|
|
48
48
|
TELEGRAM_API_BASE_URL=
|
|
49
49
|
TELEGRAM_AUTO_CLEAR_WEBHOOK=true
|
|
50
50
|
TELEGRAM_ALLOWED_UPDATES=message,edited_message
|
|
51
|
-
TELEGRAM_DEFAULT_BOT_KEY=
|
|
51
|
+
TELEGRAM_DEFAULT_BOT_KEY=ryoai
|
|
52
52
|
|
|
53
53
|
# Legacy fallback
|
|
54
54
|
TELEGRAM_BOT_TOKEN=
|
|
55
55
|
|
|
56
56
|
# Preferred named bot mapping
|
|
57
|
-
|
|
57
|
+
TELEGRAM_BOT_RYOAI_SERVER_BOT_ID=
|
|
58
58
|
# Optional fallback only when server bot binding is unavailable
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
# TELEGRAM_BOT_RYOAI_USERNAME=<bot_username>
|
|
60
|
+
TELEGRAM_BOT_RYOAI_TOKEN=
|
|
61
|
+
TELEGRAM_BOT_RYOAI_ROLE_PROFILE=monitor
|
|
62
|
+
TELEGRAM_BOT_RYOAI_AI_CLIENT=gpt
|
|
63
|
+
TELEGRAM_BOT_RYOAI_AI_MODEL=gpt-5.4
|
|
64
|
+
TELEGRAM_BOT_RYOAI_AI_PERMISSION_MODE=read_only
|
|
65
|
+
TELEGRAM_BOT_RYOAI_AI_REASONING_EFFORT=low
|
|
66
66
|
|
|
67
67
|
# ~/.metheus/slack.env
|
|
68
68
|
SLACK_BOT_TOKEN=
|
|
@@ -164,6 +164,8 @@ metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctx
|
|
|
164
164
|
- `~/.metheus/kakaotalk.env`
|
|
165
165
|
- `~/.metheus/bot-runner.json`
|
|
166
166
|
|
|
167
|
+
When `telegram.env` already exists, bootstrap/setup keeps your secrets but auto-normalizes the file to the latest named-entry layout so stale keys such as `TELEGRAM_BOT_<NAME>_BOT_*` are rewritten to `TELEGRAM_BOT_<NAME>_*`.
|
|
168
|
+
|
|
167
169
|
Fill provider bot secrets and provider-local transport options locally. Project chat destination identifiers should be managed on the Metheus server as project chat destinations, not as local env values and not inside legacy Chat Hooks/webhooks.
|
|
168
170
|
|
|
169
171
|
`~/.metheus/bot-runner.json` is the local automation profile for:
|
|
@@ -212,15 +214,15 @@ Direct commands:
|
|
|
212
214
|
|
|
213
215
|
```bash
|
|
214
216
|
metheus-governance-mcp-cli bot list
|
|
215
|
-
metheus-governance-mcp-cli bot show --provider telegram --bot-key
|
|
217
|
+
metheus-governance-mcp-cli bot show --provider telegram --bot-key ryoai
|
|
216
218
|
metheus-governance-mcp-cli bot add --provider telegram
|
|
217
219
|
metheus-governance-mcp-cli bot edit
|
|
218
220
|
metheus-governance-mcp-cli bot edit --provider telegram
|
|
219
221
|
metheus-governance-mcp-cli bot remove --provider telegram
|
|
220
|
-
metheus-governance-mcp-cli bot set-default --provider telegram --bot-key
|
|
221
|
-
metheus-governance-mcp-cli bot migrate --provider telegram --bot-key
|
|
222
|
+
metheus-governance-mcp-cli bot set-default --provider telegram --bot-key ryoai
|
|
223
|
+
metheus-governance-mcp-cli bot migrate --provider telegram --bot-key ryoai
|
|
222
224
|
metheus-governance-mcp-cli bot global --provider telegram
|
|
223
|
-
metheus-governance-mcp-cli bot verify --provider telegram --bot-key
|
|
225
|
+
metheus-governance-mcp-cli bot verify --provider telegram --bot-key ryoai
|
|
224
226
|
```
|
|
225
227
|
|
|
226
228
|
Behavior:
|
|
@@ -269,11 +271,11 @@ Non-interactive examples:
|
|
|
269
271
|
metheus-governance-mcp-cli bot global --provider telegram --non-interactive true --api-base-url http://127.0.0.1:8999/telegram --auto-clear-webhook false --allowed-updates message,edited_message,channel_post
|
|
270
272
|
metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --default true
|
|
271
273
|
metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --ai-client gpt --ai-model "gpt-5.4" --ai-permission-mode read_only --ai-reasoning-effort low
|
|
272
|
-
metheus-governance-mcp-cli bot edit --provider telegram --bot-key
|
|
273
|
-
metheus-governance-mcp-cli bot set-default --provider telegram --bot-key
|
|
274
|
-
metheus-governance-mcp-cli bot migrate --provider telegram --bot-key
|
|
275
|
-
metheus-governance-mcp-cli bot remove --provider telegram --bot-key
|
|
276
|
-
metheus-governance-mcp-cli bot verify --provider telegram --bot-key
|
|
274
|
+
metheus-governance-mcp-cli bot edit --provider telegram --bot-key ryoai --non-interactive true --ai-client claude --ai-model "Sonnet 4.6r" --ai-permission-mode danger_full_access --ai-reasoning-effort high
|
|
275
|
+
metheus-governance-mcp-cli bot set-default --provider telegram --bot-key ryoai --non-interactive true
|
|
276
|
+
metheus-governance-mcp-cli bot migrate --provider telegram --bot-key ryoai --server-bot-id <server_bot_uuid> --bot-name <telegram_username> --role-profile monitor --ai-client gpt --ai-permission-mode read_only --ai-reasoning-effort low --non-interactive true
|
|
277
|
+
metheus-governance-mcp-cli bot remove --provider telegram --bot-key ryoai --non-interactive true
|
|
278
|
+
metheus-governance-mcp-cli bot verify --provider telegram --bot-key ryoai --json true
|
|
277
279
|
```
|
|
278
280
|
|
|
279
281
|
For direct Telegram adds, the CLI can derive the local entry key from the matched server bot name. You no longer need `--bot-key` or `--username` in the normal server-bound path. Treat `--bot-key` as an advanced override only when you intentionally want a different local suffix.
|
package/cli.mjs
CHANGED
|
@@ -749,32 +749,32 @@ function providerEnvTemplate(provider) {
|
|
|
749
749
|
"# TELEGRAM_BOT_TOKEN=<bot token>",
|
|
750
750
|
"#",
|
|
751
751
|
"# Preferred v2 multi-bot mapping:",
|
|
752
|
-
"# TELEGRAM_DEFAULT_BOT_KEY=
|
|
753
|
-
"#
|
|
754
|
-
"#
|
|
755
|
-
"#
|
|
756
|
-
"#
|
|
757
|
-
"#
|
|
758
|
-
"#
|
|
759
|
-
"#
|
|
760
|
-
"#
|
|
752
|
+
"# TELEGRAM_DEFAULT_BOT_KEY=ryoai",
|
|
753
|
+
"# TELEGRAM_BOT_RYOAI_SERVER_BOT_ID=<server bot uuid>",
|
|
754
|
+
"# TELEGRAM_BOT_RYOAI_USERNAME=<optional fallback username when server binding is unavailable>",
|
|
755
|
+
"# TELEGRAM_BOT_RYOAI_TOKEN=<bot token>",
|
|
756
|
+
"# TELEGRAM_BOT_RYOAI_ROLE_PROFILE=monitor",
|
|
757
|
+
"# TELEGRAM_BOT_RYOAI_AI_CLIENT=gpt",
|
|
758
|
+
"# TELEGRAM_BOT_RYOAI_AI_MODEL=gpt-5.4",
|
|
759
|
+
"# TELEGRAM_BOT_RYOAI_AI_PERMISSION_MODE=read_only",
|
|
760
|
+
"# TELEGRAM_BOT_RYOAI_AI_REASONING_EFFORT=low",
|
|
761
761
|
"",
|
|
762
762
|
"TELEGRAM_API_BASE_URL=",
|
|
763
763
|
"TELEGRAM_AUTO_CLEAR_WEBHOOK=true",
|
|
764
764
|
"TELEGRAM_ALLOWED_UPDATES=message,edited_message",
|
|
765
|
-
"TELEGRAM_DEFAULT_BOT_KEY=
|
|
765
|
+
"TELEGRAM_DEFAULT_BOT_KEY=ryoai",
|
|
766
766
|
"",
|
|
767
767
|
"# Legacy fallback (still supported)",
|
|
768
768
|
"TELEGRAM_BOT_TOKEN=",
|
|
769
769
|
"",
|
|
770
770
|
"# Preferred named bot entry",
|
|
771
|
-
"
|
|
772
|
-
"
|
|
773
|
-
"
|
|
774
|
-
"
|
|
775
|
-
"
|
|
776
|
-
"
|
|
777
|
-
"
|
|
771
|
+
"TELEGRAM_BOT_RYOAI_SERVER_BOT_ID=",
|
|
772
|
+
"TELEGRAM_BOT_RYOAI_TOKEN=",
|
|
773
|
+
"TELEGRAM_BOT_RYOAI_ROLE_PROFILE=",
|
|
774
|
+
"TELEGRAM_BOT_RYOAI_AI_CLIENT=",
|
|
775
|
+
"TELEGRAM_BOT_RYOAI_AI_MODEL=",
|
|
776
|
+
"TELEGRAM_BOT_RYOAI_AI_PERMISSION_MODE=",
|
|
777
|
+
"TELEGRAM_BOT_RYOAI_AI_REASONING_EFFORT=",
|
|
778
778
|
"",
|
|
779
779
|
].join("\n");
|
|
780
780
|
}
|
|
@@ -1053,7 +1053,12 @@ function ensureProviderEnvTemplate(provider) {
|
|
|
1053
1053
|
const filePath = providerEnvFilePath(provider);
|
|
1054
1054
|
try {
|
|
1055
1055
|
if (fs.existsSync(filePath)) {
|
|
1056
|
-
return {
|
|
1056
|
+
return {
|
|
1057
|
+
filePath,
|
|
1058
|
+
created: false,
|
|
1059
|
+
existed: true,
|
|
1060
|
+
normalized: normalizeExistingProviderEnvFile(provider, filePath),
|
|
1061
|
+
};
|
|
1057
1062
|
}
|
|
1058
1063
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
1059
1064
|
fs.writeFileSync(filePath, providerEnvTemplate(provider), "utf8");
|
|
@@ -2636,11 +2641,21 @@ function parseSimpleEnvText(rawText) {
|
|
|
2636
2641
|
return out;
|
|
2637
2642
|
}
|
|
2638
2643
|
|
|
2644
|
+
function formatProviderEnvValue(rawValue) {
|
|
2645
|
+
const text = String(rawValue ?? "");
|
|
2646
|
+
if (!text) return "";
|
|
2647
|
+
if (/^[A-Za-z0-9_./:@,\-]+$/.test(text)) {
|
|
2648
|
+
return text;
|
|
2649
|
+
}
|
|
2650
|
+
return JSON.stringify(text);
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2639
2653
|
function normalizeTelegramBotEnvKey(rawValue, fallback = "") {
|
|
2640
2654
|
const normalized = String(rawValue || "")
|
|
2641
2655
|
.trim()
|
|
2642
2656
|
.toLowerCase()
|
|
2643
2657
|
.replace(/[^a-z0-9]+/g, "_")
|
|
2658
|
+
.replace(/_bot$/g, "")
|
|
2644
2659
|
.replace(/^_+|_+$/g, "");
|
|
2645
2660
|
return normalized || fallback;
|
|
2646
2661
|
}
|
|
@@ -2704,6 +2719,124 @@ function collectTelegramEnvBotEntries(parsedEnv) {
|
|
|
2704
2719
|
return Array.from(entries.values());
|
|
2705
2720
|
}
|
|
2706
2721
|
|
|
2722
|
+
function isTelegramEntryEnvKey(rawKey) {
|
|
2723
|
+
return /^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i
|
|
2724
|
+
.test(String(rawKey || "").trim());
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2727
|
+
function telegramEntryCommentNameForEnv(entry) {
|
|
2728
|
+
const current = safeObject(entry);
|
|
2729
|
+
const username = normalizeTelegramBotUsername(current.username || "");
|
|
2730
|
+
if (username) return username;
|
|
2731
|
+
const key = normalizeTelegramBotEnvKey(current.key || "", "telegram_bot");
|
|
2732
|
+
if (!key) return "telegram_bot";
|
|
2733
|
+
return key.endsWith("_bot") ? key : `${key}_bot`;
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
function renderNormalizedTelegramEnv(parsedEnv) {
|
|
2737
|
+
const parsed = safeObject(parsedEnv);
|
|
2738
|
+
const entries = collectTelegramEnvBotEntries(parsed)
|
|
2739
|
+
.filter((entry) => (
|
|
2740
|
+
entry.token
|
|
2741
|
+
|| entry.username
|
|
2742
|
+
|| entry.serverBotID
|
|
2743
|
+
|| entry.roleProfile
|
|
2744
|
+
|| entry.client
|
|
2745
|
+
|| entry.model
|
|
2746
|
+
|| entry.permissionMode
|
|
2747
|
+
|| entry.reasoningEffort
|
|
2748
|
+
))
|
|
2749
|
+
.sort((left, right) => String(left.key || "").localeCompare(String(right.key || "")));
|
|
2750
|
+
const defaultBotKey = normalizeTelegramBotEnvKey(parsed.TELEGRAM_DEFAULT_BOT_KEY || "", "");
|
|
2751
|
+
if (defaultBotKey) {
|
|
2752
|
+
entries.sort((left, right) => {
|
|
2753
|
+
if (left.key === defaultBotKey) return -1;
|
|
2754
|
+
if (right.key === defaultBotKey) return 1;
|
|
2755
|
+
return String(left.key || "").localeCompare(String(right.key || ""));
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2758
|
+
const lines = [
|
|
2759
|
+
"# Metheus local Telegram bot settings",
|
|
2760
|
+
"# Keep this file on your machine only. Do not commit it.",
|
|
2761
|
+
"# Store Telegram bot secrets, AI bindings, and local transport options only.",
|
|
2762
|
+
"",
|
|
2763
|
+
`TELEGRAM_API_BASE_URL=${formatProviderEnvValue(parsed.TELEGRAM_API_BASE_URL || "")}`,
|
|
2764
|
+
`TELEGRAM_AUTO_CLEAR_WEBHOOK=${boolFromRaw(parsed.TELEGRAM_AUTO_CLEAR_WEBHOOK, true) ? "true" : "false"}`,
|
|
2765
|
+
`TELEGRAM_ALLOWED_UPDATES=${formatProviderEnvValue(String(parsed.TELEGRAM_ALLOWED_UPDATES || "").trim() || "message,edited_message")}`,
|
|
2766
|
+
`TELEGRAM_DEFAULT_BOT_KEY=${formatProviderEnvValue(defaultBotKey || "")}`,
|
|
2767
|
+
"",
|
|
2768
|
+
"# Legacy fallback",
|
|
2769
|
+
`TELEGRAM_BOT_TOKEN=${formatProviderEnvValue(parsed.TELEGRAM_BOT_TOKEN || "")}`,
|
|
2770
|
+
"",
|
|
2771
|
+
];
|
|
2772
|
+
if (!entries.length) {
|
|
2773
|
+
lines.push("# No named Telegram bot entries configured yet", "");
|
|
2774
|
+
} else {
|
|
2775
|
+
entries.forEach((entry) => {
|
|
2776
|
+
const upper = String(entry.key || "").trim().toUpperCase();
|
|
2777
|
+
lines.push(
|
|
2778
|
+
`# Telegram bot entry: ${telegramEntryCommentNameForEnv(entry)}`,
|
|
2779
|
+
`TELEGRAM_BOT_${upper}_SERVER_BOT_ID=${formatProviderEnvValue(entry.serverBotID || "")}`,
|
|
2780
|
+
);
|
|
2781
|
+
if (String(entry.username || "").trim()) {
|
|
2782
|
+
lines.push(`TELEGRAM_BOT_${upper}_USERNAME=${formatProviderEnvValue(entry.username || "")}`);
|
|
2783
|
+
}
|
|
2784
|
+
lines.push(
|
|
2785
|
+
`TELEGRAM_BOT_${upper}_TOKEN=${formatProviderEnvValue(entry.token || "")}`,
|
|
2786
|
+
`TELEGRAM_BOT_${upper}_ROLE_PROFILE=${formatProviderEnvValue(entry.roleProfile || "")}`,
|
|
2787
|
+
`TELEGRAM_BOT_${upper}_AI_CLIENT=${formatProviderEnvValue(entry.client || "")}`,
|
|
2788
|
+
`TELEGRAM_BOT_${upper}_AI_MODEL=${formatProviderEnvValue(entry.model || "")}`,
|
|
2789
|
+
`TELEGRAM_BOT_${upper}_AI_PERMISSION_MODE=${formatProviderEnvValue(entry.permissionMode || "")}`,
|
|
2790
|
+
`TELEGRAM_BOT_${upper}_AI_REASONING_EFFORT=${formatProviderEnvValue(entry.reasoningEffort || "")}`,
|
|
2791
|
+
"",
|
|
2792
|
+
);
|
|
2793
|
+
});
|
|
2794
|
+
}
|
|
2795
|
+
const knownKeys = new Set([
|
|
2796
|
+
"TELEGRAM_API_BASE_URL",
|
|
2797
|
+
"TELEGRAM_AUTO_CLEAR_WEBHOOK",
|
|
2798
|
+
"TELEGRAM_ALLOWED_UPDATES",
|
|
2799
|
+
"TELEGRAM_DEFAULT_BOT_KEY",
|
|
2800
|
+
"TELEGRAM_BOT_TOKEN",
|
|
2801
|
+
]);
|
|
2802
|
+
entries.forEach((entry) => {
|
|
2803
|
+
const upper = String(entry.key || "").trim().toUpperCase();
|
|
2804
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_SERVER_BOT_ID`);
|
|
2805
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_USERNAME`);
|
|
2806
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_TOKEN`);
|
|
2807
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_ROLE_PROFILE`);
|
|
2808
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_AI_CLIENT`);
|
|
2809
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_AI_MODEL`);
|
|
2810
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_AI_PERMISSION_MODE`);
|
|
2811
|
+
knownKeys.add(`TELEGRAM_BOT_${upper}_AI_REASONING_EFFORT`);
|
|
2812
|
+
});
|
|
2813
|
+
const extras = Object.keys(parsed)
|
|
2814
|
+
.filter((key) => !knownKeys.has(key) && !isTelegramEntryEnvKey(key))
|
|
2815
|
+
.sort((left, right) => left.localeCompare(right));
|
|
2816
|
+
if (extras.length) {
|
|
2817
|
+
lines.push("# Additional preserved keys");
|
|
2818
|
+
extras.forEach((key) => {
|
|
2819
|
+
lines.push(`${key}=${formatProviderEnvValue(parsed[key])}`);
|
|
2820
|
+
});
|
|
2821
|
+
lines.push("");
|
|
2822
|
+
}
|
|
2823
|
+
return `${lines.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd()}\n`;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
function normalizeExistingProviderEnvFile(provider, filePath) {
|
|
2827
|
+
if (normalizeBotProvider(provider) !== "telegram") return false;
|
|
2828
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
2829
|
+
const rendered = renderNormalizedTelegramEnv(parseSimpleEnvText(raw));
|
|
2830
|
+
if (raw.replace(/\r\n/g, "\n") === rendered.replace(/\r\n/g, "\n")) {
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
fs.writeFileSync(filePath, rendered, {
|
|
2834
|
+
encoding: "utf8",
|
|
2835
|
+
mode: 0o600,
|
|
2836
|
+
});
|
|
2837
|
+
return true;
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2707
2840
|
function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
2708
2841
|
const parsed = safeObject(parsedEnv);
|
|
2709
2842
|
const legacyToken = String(parsed.TELEGRAM_BOT_TOKEN || "").trim();
|
|
@@ -5078,8 +5211,8 @@ TELEGRAM_API_BASE_URL=http://127.0.0.1:8999/api
|
|
|
5078
5211
|
TELEGRAM_AUTO_CLEAR_WEBHOOK=false
|
|
5079
5212
|
TELEGRAM_ALLOWED_UPDATES=message,edited_message,channel_post
|
|
5080
5213
|
TELEGRAM_DEFAULT_BOT_KEY=review
|
|
5081
|
-
|
|
5082
|
-
|
|
5214
|
+
TELEGRAM_BOT_RYOAI_USERNAME=RyoAI_bot
|
|
5215
|
+
TELEGRAM_BOT_RYOAI_TOKEN=ryoai-token
|
|
5083
5216
|
TELEGRAM_BOT_REVIEW_SERVER_BOT_ID=bot-review
|
|
5084
5217
|
TELEGRAM_BOT_REVIEW_USERNAME=ReviewBot
|
|
5085
5218
|
TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
@@ -5108,11 +5241,25 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
5108
5241
|
"telegram_env_v2_bot_name_override_selects_matching_token",
|
|
5109
5242
|
telegramEnvV2ByUsername.ok
|
|
5110
5243
|
&& telegramEnvV2ByUsername.token === "ryoai-token"
|
|
5111
|
-
&& telegramEnvV2ByUsername.botKey === "
|
|
5244
|
+
&& telegramEnvV2ByUsername.botKey === "ryoai"
|
|
5112
5245
|
&& Array.isArray(telegramEnvV2ByUsername.allowedUpdates)
|
|
5113
5246
|
&& telegramEnvV2ByUsername.allowedUpdates.includes("channel_post"),
|
|
5114
5247
|
`bot=${String(telegramEnvV2ByUsername.botKey || "(none)")} updates=${String((telegramEnvV2ByUsername.allowedUpdates || []).join(","))}`,
|
|
5115
5248
|
);
|
|
5249
|
+
const telegramEnvNormalizedText = renderNormalizedTelegramEnv(parseSimpleEnvText(`
|
|
5250
|
+
TELEGRAM_DEFAULT_BOT_KEY=ryoai_bot
|
|
5251
|
+
TELEGRAM_BOT_RYOAI_BOT_SERVER_BOT_ID=bot-ryoai
|
|
5252
|
+
TELEGRAM_BOT_RYOAI_BOT_TOKEN=ryoai-token
|
|
5253
|
+
`));
|
|
5254
|
+
push(
|
|
5255
|
+
"telegram_env_existing_file_auto_normalizes_named_keys",
|
|
5256
|
+
telegramEnvNormalizedText.includes("TELEGRAM_DEFAULT_BOT_KEY=ryoai")
|
|
5257
|
+
&& telegramEnvNormalizedText.includes("TELEGRAM_BOT_RYOAI_SERVER_BOT_ID=bot-ryoai")
|
|
5258
|
+
&& telegramEnvNormalizedText.includes("TELEGRAM_BOT_RYOAI_TOKEN=ryoai-token")
|
|
5259
|
+
&& telegramEnvNormalizedText.includes("# Telegram bot entry: ryoai_bot")
|
|
5260
|
+
&& !telegramEnvNormalizedText.includes("TELEGRAM_BOT_RYOAI_BOT_TOKEN"),
|
|
5261
|
+
telegramEnvNormalizedText,
|
|
5262
|
+
);
|
|
5116
5263
|
const telegramSupport = getProviderSupport("telegram");
|
|
5117
5264
|
push(
|
|
5118
5265
|
"provider_support_telegram_full_runner",
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -67,7 +67,11 @@ function suggestDisplayedAIModel(deps, clientName, rawModelValue = "") {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
function normalizeServerBotIdentityText(rawValue) {
|
|
70
|
-
return String(rawValue || "")
|
|
70
|
+
return String(rawValue || "")
|
|
71
|
+
.trim()
|
|
72
|
+
.replace(/^@+/, "")
|
|
73
|
+
.toLowerCase()
|
|
74
|
+
.replace(/_bot$/g, "");
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
function summarizeServerBotRoles(bots) {
|
|
@@ -437,6 +441,15 @@ function telegramEntryEnvKeys(botKey) {
|
|
|
437
441
|
};
|
|
438
442
|
}
|
|
439
443
|
|
|
444
|
+
function telegramEntryCommentName(entry) {
|
|
445
|
+
const current = safeObject(entry);
|
|
446
|
+
const username = String(current.username || "").trim();
|
|
447
|
+
if (username) return username;
|
|
448
|
+
const key = String(current.key || "").trim();
|
|
449
|
+
if (!key) return "telegram_bot";
|
|
450
|
+
return key.endsWith("_bot") ? key : `${key}_bot`;
|
|
451
|
+
}
|
|
452
|
+
|
|
440
453
|
function persistTelegramUsername(entry) {
|
|
441
454
|
const current = safeObject(entry);
|
|
442
455
|
if (current.__preferServerIdentity) return "";
|
|
@@ -487,6 +500,11 @@ function telegramKnownKeys(parsedEnv, deps) {
|
|
|
487
500
|
return keys;
|
|
488
501
|
}
|
|
489
502
|
|
|
503
|
+
function isTelegramEntryEnvKey(rawKey) {
|
|
504
|
+
return /^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i
|
|
505
|
+
.test(String(rawKey || "").trim());
|
|
506
|
+
}
|
|
507
|
+
|
|
490
508
|
function renderTelegramEnv(parsedEnv, deps) {
|
|
491
509
|
const parsed = safeObject(parsedEnv);
|
|
492
510
|
const collectEntries = requireDependency(deps, "collectTelegramEnvBotEntries");
|
|
@@ -531,7 +549,7 @@ function renderTelegramEnv(parsedEnv, deps) {
|
|
|
531
549
|
entries.forEach((entry) => {
|
|
532
550
|
const keys = telegramEntryEnvKeys(entry.key);
|
|
533
551
|
const entryLines = [
|
|
534
|
-
`# Telegram bot entry: ${entry
|
|
552
|
+
`# Telegram bot entry: ${telegramEntryCommentName(entry)}`,
|
|
535
553
|
`${keys.serverBotID}=${formatEnvValue(entry.serverBotID || "")}`,
|
|
536
554
|
];
|
|
537
555
|
if (String(entry.username || "").trim()) {
|
|
@@ -551,7 +569,7 @@ function renderTelegramEnv(parsedEnv, deps) {
|
|
|
551
569
|
}
|
|
552
570
|
const knownKeys = telegramKnownKeys(parsed, deps);
|
|
553
571
|
const extras = Object.keys(parsed)
|
|
554
|
-
.filter((key) => !knownKeys.has(key))
|
|
572
|
+
.filter((key) => !knownKeys.has(key) && !isTelegramEntryEnvKey(key))
|
|
555
573
|
.sort((left, right) => left.localeCompare(right));
|
|
556
574
|
if (extras.length) {
|
|
557
575
|
lines.push("# Additional preserved keys");
|
|
@@ -391,12 +391,12 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
391
391
|
const groupedState = parseSimpleEnvText(fs.readFileSync(telegramEnvPath, "utf8"));
|
|
392
392
|
push(
|
|
393
393
|
"bot_add_guided_autoresolves_server_bot_group_without_role_prompt",
|
|
394
|
-
String(groupedState.
|
|
395
|
-
&& String(groupedState.
|
|
396
|
-
&& String(groupedState.
|
|
397
|
-
&& String(groupedState.
|
|
398
|
-
&& String(groupedState.
|
|
399
|
-
`username=${String(groupedState.
|
|
394
|
+
String(groupedState.TELEGRAM_BOT_RYOAI_USERNAME || "").trim() === ""
|
|
395
|
+
&& String(groupedState.TELEGRAM_BOT_RYOAI_SERVER_BOT_ID || "") === ""
|
|
396
|
+
&& String(groupedState.TELEGRAM_BOT_RYOAI_ROLE_PROFILE || "") === ""
|
|
397
|
+
&& String(groupedState.TELEGRAM_BOT_RYOAI_AI_CLIENT || "") === ""
|
|
398
|
+
&& String(groupedState.TELEGRAM_BOT_RYOAI_AI_PERMISSION_MODE || "") === "",
|
|
399
|
+
`username=${String(groupedState.TELEGRAM_BOT_RYOAI_USERNAME || "")} server_bot_id=${String(groupedState.TELEGRAM_BOT_RYOAI_SERVER_BOT_ID || "")} role=${String(groupedState.TELEGRAM_BOT_RYOAI_ROLE_PROFILE || "")}`,
|
|
400
400
|
);
|
|
401
401
|
|
|
402
402
|
const groupedEditResult = await runCLI({
|
|
@@ -410,7 +410,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
410
410
|
...env,
|
|
411
411
|
METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
|
|
412
412
|
"1", // provider: telegram
|
|
413
|
-
"2", // bot entry:
|
|
413
|
+
"2", // bot entry: ryoai
|
|
414
414
|
"1", // keep token
|
|
415
415
|
"2", // grouped role settings: edit one role
|
|
416
416
|
"3", // select role to edit: worker
|
|
@@ -455,7 +455,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
455
455
|
args: [
|
|
456
456
|
"bot", "show",
|
|
457
457
|
"--provider", "telegram",
|
|
458
|
-
"--bot-key", "
|
|
458
|
+
"--bot-key", "ryoai",
|
|
459
459
|
"--base-url", `http://127.0.0.1:${groupedMock.port}`,
|
|
460
460
|
"--json", "true",
|
|
461
461
|
],
|