metheus-governance-mcp-cli 0.2.111 → 0.2.113
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 +9 -1
- package/cli.mjs +184 -8
- package/lib/bot-commands.mjs +4 -3
- package/lib/selftest-bot-commands.mjs +1 -1
- package/lib/selftest-runner-scenarios.mjs +38 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -305,7 +305,7 @@ For direct Telegram adds, the CLI derives the local file name from the matched s
|
|
|
305
305
|
|
|
306
306
|
For direct Telegram edits, prefer `--bot-name` or `--bot-id` because server bot identity is the source of truth. Use `--bot-key` only when you intentionally need the legacy local selector. If one server bot name expands to multiple roles such as `approval / worker / review / monitor`, prefer the guided `bot edit` flow so you can keep the current grouped settings, edit one role only, or walk every role in sequence instead of forcing one entry-level AI override.
|
|
307
307
|
|
|
308
|
-
For runner commands,
|
|
308
|
+
For runner commands, routes are the executable unit. Use `--route-name` as the primary selector. `--bot-name` and `--bot-id` are convenience route aliases only when they identify one enabled route uniquely. Use `runner list` first if you are not sure which route belongs to which server bot, and use `runner show` to inspect the resolved route, server identity, workspace mapping, and execution profile together.
|
|
309
309
|
|
|
310
310
|
Current support status:
|
|
311
311
|
|
|
@@ -388,6 +388,7 @@ Commands:
|
|
|
388
388
|
|
|
389
389
|
```bash
|
|
390
390
|
metheus-governance-mcp-cli runner list
|
|
391
|
+
metheus-governance-mcp-cli runner show --route-name telegram-monitor
|
|
391
392
|
metheus-governance-mcp-cli runner once --route-name telegram-monitor
|
|
392
393
|
metheus-governance-mcp-cli runner start --route-name telegram-monitor
|
|
393
394
|
```
|
|
@@ -399,9 +400,16 @@ metheus-governance-mcp-cli runner once --route-name telegram-monitor --dry-run-d
|
|
|
399
400
|
metheus-governance-mcp-cli runner start --route-name telegram-monitor
|
|
400
401
|
```
|
|
401
402
|
|
|
403
|
+
What `runner list` means:
|
|
404
|
+
- `server_bot_name` may come from `route.server_bot_name` or be resolved from the Telegram bot env file by `server_bot_id`
|
|
405
|
+
- `server_bot_name_source=route_config` means the route file already stores the name directly
|
|
406
|
+
- `server_bot_name_source=telegram_env_lookup` means the CLI resolved the name from the local Telegram bot file
|
|
407
|
+
- `route_alias_by_server_bot_name` is a convenience selector, not a separate execution target
|
|
408
|
+
|
|
402
409
|
Debug/selection overrides:
|
|
403
410
|
|
|
404
411
|
```bash
|
|
412
|
+
metheus-governance-mcp-cli runner show --bot-name <server_bot_name>
|
|
405
413
|
metheus-governance-mcp-cli runner once --project-id <project_uuid> --provider telegram --role monitor
|
|
406
414
|
metheus-governance-mcp-cli runner start --project-id <project_uuid> --provider telegram --role monitor --poll-interval-ms 5000
|
|
407
415
|
metheus-governance-mcp-cli runner once --project-id <project_uuid> --provider telegram --role monitor --role-profile review
|
package/cli.mjs
CHANGED
|
@@ -255,8 +255,9 @@ function printUsage() {
|
|
|
255
255
|
` ${cmd} selftest [--json <true|false>]`,
|
|
256
256
|
` ${cmd} local-bot-bridge [--client <gpt|claude|gemini|sample>] [--cwd <path>] [--model <name>] [--permission-mode <read_only|workspace_write|danger_full_access>] [--reasoning-effort <low|medium|high>]`,
|
|
257
257
|
` ${cmd} runner list [--json <true|false>]`,
|
|
258
|
-
` ${cmd} runner
|
|
259
|
-
` ${cmd} runner
|
|
258
|
+
` ${cmd} runner show [--route-name <name> | --bot-name <server_name> | --bot-id <uuid>] [--json <true|false>]`,
|
|
259
|
+
` ${cmd} runner once [--route-name <name> | --bot-name <server_name when one enabled route matches> | --bot-id <uuid when one enabled route matches>] [--project-id <uuid>] [--provider <telegram|slack|kakaotalk>] [--role <monitor|review|worker|approval>] [--role-profile <name>] [--mentions-only <true|false>] [--reply-to-bot-messages <true|false>] [--direct-messages <true|false>] [--ignore-edited-messages <true|false>] [--dry-run-delivery <true|false>] [--context-comments <n>] [--archive-replies <true|false>]`,
|
|
260
|
+
` ${cmd} runner start [--route-name <name> | --bot-name <server_name when one enabled route matches> | --bot-id <uuid when one enabled route matches>] [--project-id <uuid>] [--provider <telegram|slack|kakaotalk>] [--role <monitor|review|worker|approval>] [--role-profile <name>] [--mentions-only <true|false>] [--reply-to-bot-messages <true|false>] [--direct-messages <true|false>] [--ignore-edited-messages <true|false>] [--dry-run-delivery <true|false>] [--poll-interval-ms <n>] [--context-comments <n>] [--archive-replies <true|false>]`,
|
|
260
261
|
` ${cmd} ctxpack pull [--project-id <uuid>] [--base-url <url>] [--workspace-dir <path|auto>] [--paths <csv>] [--timeout-seconds <n>]`,
|
|
261
262
|
` ${cmd} auth status`,
|
|
262
263
|
` ${cmd} auth login [--base-url <url>] [--flow <auto|device|callback|manual>] [--keycloak-url <url>] [--realm <name>] [--client-id <id>] [--open-browser <true|false>] [--callback-port <n>] [--timeout-seconds <n>] [--manual <true|false>]`,
|
|
@@ -1269,10 +1270,21 @@ function normalizeBotRunnerConfigContents(parsed, filePath) {
|
|
|
1269
1270
|
if (!binding.name || (!binding.botID && !binding.botName)) continue;
|
|
1270
1271
|
if (!binding.roleProfile && !binding.client && !binding.model && !binding.permissionMode && !binding.reasoningEffort) continue;
|
|
1271
1272
|
botBindings[binding.name] = binding;
|
|
1272
|
-
const
|
|
1273
|
+
const rawBindingObject = safeObject(rawBinding);
|
|
1274
|
+
const rawClient = String(rawBindingObject.client || "").trim().toLowerCase();
|
|
1273
1275
|
if (rawClient === "codex") {
|
|
1274
1276
|
migrated = true;
|
|
1275
1277
|
}
|
|
1278
|
+
if (
|
|
1279
|
+
(!Object.prototype.hasOwnProperty.call(rawBindingObject, "server_bot_id")
|
|
1280
|
+
&& !Object.prototype.hasOwnProperty.call(rawBindingObject, "serverBotID")
|
|
1281
|
+
&& (Object.prototype.hasOwnProperty.call(rawBindingObject, "bot_id") || Object.prototype.hasOwnProperty.call(rawBindingObject, "botId")))
|
|
1282
|
+
|| (!Object.prototype.hasOwnProperty.call(rawBindingObject, "server_bot_name")
|
|
1283
|
+
&& !Object.prototype.hasOwnProperty.call(rawBindingObject, "serverBotName")
|
|
1284
|
+
&& (Object.prototype.hasOwnProperty.call(rawBindingObject, "bot_name") || Object.prototype.hasOwnProperty.call(rawBindingObject, "botName")))
|
|
1285
|
+
) {
|
|
1286
|
+
migrated = true;
|
|
1287
|
+
}
|
|
1276
1288
|
}
|
|
1277
1289
|
|
|
1278
1290
|
const projectMappings = {};
|
|
@@ -1289,6 +1301,16 @@ function normalizeBotRunnerConfigContents(parsed, filePath) {
|
|
|
1289
1301
|
const routeSource = safeObject(rawRoute);
|
|
1290
1302
|
const route = normalizeRunnerRoute(routeSource);
|
|
1291
1303
|
routes.push(route);
|
|
1304
|
+
if (
|
|
1305
|
+
(!Object.prototype.hasOwnProperty.call(routeSource, "server_bot_id")
|
|
1306
|
+
&& !Object.prototype.hasOwnProperty.call(routeSource, "serverBotID")
|
|
1307
|
+
&& (Object.prototype.hasOwnProperty.call(routeSource, "bot_id") || Object.prototype.hasOwnProperty.call(routeSource, "botID")))
|
|
1308
|
+
|| (!Object.prototype.hasOwnProperty.call(routeSource, "server_bot_name")
|
|
1309
|
+
&& !Object.prototype.hasOwnProperty.call(routeSource, "serverBotName")
|
|
1310
|
+
&& (Object.prototype.hasOwnProperty.call(routeSource, "bot_name") || Object.prototype.hasOwnProperty.call(routeSource, "botName")))
|
|
1311
|
+
) {
|
|
1312
|
+
migrated = true;
|
|
1313
|
+
}
|
|
1292
1314
|
if (!Object.prototype.hasOwnProperty.call(routeSource, "trigger_policy") && !Object.prototype.hasOwnProperty.call(routeSource, "triggerPolicy")) {
|
|
1293
1315
|
migrated = true;
|
|
1294
1316
|
}
|
|
@@ -1797,8 +1819,27 @@ function matchesRunnerRouteText(candidate, expected) {
|
|
|
1797
1819
|
return String(candidate || "").trim().toLowerCase() === expectedText.toLowerCase();
|
|
1798
1820
|
}
|
|
1799
1821
|
|
|
1800
|
-
function
|
|
1822
|
+
function resolveConfiguredRunnerRouteServerBotName(route, telegramEntries = []) {
|
|
1801
1823
|
const candidate = normalizeRunnerRoute(route);
|
|
1824
|
+
if (candidate.botName) {
|
|
1825
|
+
return candidate.botName;
|
|
1826
|
+
}
|
|
1827
|
+
if (candidate.provider !== "telegram") {
|
|
1828
|
+
return "";
|
|
1829
|
+
}
|
|
1830
|
+
const matchedTelegramEntry = ensureArray(telegramEntries).find((entry) => {
|
|
1831
|
+
const current = safeObject(entry);
|
|
1832
|
+
return (
|
|
1833
|
+
(candidate.botID && current.serverBotID && current.serverBotID === candidate.botID)
|
|
1834
|
+
|| (candidate.botName && current.serverBotName && current.serverBotName === candidate.botName)
|
|
1835
|
+
);
|
|
1836
|
+
});
|
|
1837
|
+
return String(matchedTelegramEntry?.serverBotName || "").trim();
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
function configuredRunnerRouteMatchesInlineSelection(route, inlineRoute, flags, options = {}) {
|
|
1841
|
+
const candidate = normalizeRunnerRoute(route);
|
|
1842
|
+
const candidateBotName = resolveConfiguredRunnerRouteServerBotName(candidate, options.telegramEntries);
|
|
1802
1843
|
if (hasRunnerFlag(flags, "route-name") && !matchesRunnerRouteText(candidate.name, flags["route-name"])) {
|
|
1803
1844
|
return false;
|
|
1804
1845
|
}
|
|
@@ -1817,7 +1858,7 @@ function configuredRunnerRouteMatchesInlineSelection(route, inlineRoute, flags)
|
|
|
1817
1858
|
if (inlineRoute.botID && candidate.botID !== inlineRoute.botID) {
|
|
1818
1859
|
return false;
|
|
1819
1860
|
}
|
|
1820
|
-
if (inlineRoute.botName && !matchesRunnerRouteText(
|
|
1861
|
+
if (inlineRoute.botName && !matchesRunnerRouteText(candidateBotName, inlineRoute.botName)) {
|
|
1821
1862
|
return false;
|
|
1822
1863
|
}
|
|
1823
1864
|
if (inlineRoute.destinationID && candidate.destinationID !== inlineRoute.destinationID) {
|
|
@@ -2014,9 +2055,10 @@ function resolveRunnerRoutes(flags, mode) {
|
|
|
2014
2055
|
.map((rawRoute) => normalizeRunnerRoute(rawRoute))
|
|
2015
2056
|
.filter((route) => route.enabled)
|
|
2016
2057
|
.filter((route) => !routeNameFilter || String(route.name || "").trim().toLowerCase() === routeNameFilter);
|
|
2058
|
+
const telegramEntries = selectionRequested ? ensureArray(readTelegramEnvState().entries) : [];
|
|
2017
2059
|
|
|
2018
2060
|
if (selectionRequested) {
|
|
2019
|
-
const matchedRoutes = configuredRoutes.filter((route) => configuredRunnerRouteMatchesInlineSelection(route, inlineRoute, flags));
|
|
2061
|
+
const matchedRoutes = configuredRoutes.filter((route) => configuredRunnerRouteMatchesInlineSelection(route, inlineRoute, flags, { telegramEntries }));
|
|
2020
2062
|
if (matchedRoutes.length === 1) {
|
|
2021
2063
|
return [applyRunnerRouteFlagOverrides(matchedRoutes[0], flags)];
|
|
2022
2064
|
}
|
|
@@ -2591,10 +2633,14 @@ function buildRunnerRouteListRows() {
|
|
|
2591
2633
|
);
|
|
2592
2634
|
})
|
|
2593
2635
|
: null;
|
|
2636
|
+
const botNameSource = route.botName
|
|
2637
|
+
? "route_config"
|
|
2638
|
+
: matchedTelegramEntry?.serverBotName
|
|
2639
|
+
? "telegram_env_lookup"
|
|
2640
|
+
: "unresolved";
|
|
2594
2641
|
const resolvedBotName = firstNonEmptyString([
|
|
2595
2642
|
route.botName,
|
|
2596
2643
|
matchedTelegramEntry?.serverBotName,
|
|
2597
|
-
matchedTelegramEntry?.key,
|
|
2598
2644
|
"-",
|
|
2599
2645
|
]);
|
|
2600
2646
|
return {
|
|
@@ -2604,6 +2650,7 @@ function buildRunnerRouteListRows() {
|
|
|
2604
2650
|
provider: route.provider || "-",
|
|
2605
2651
|
projectID: route.projectID || "-",
|
|
2606
2652
|
botName: resolvedBotName,
|
|
2653
|
+
botNameSource,
|
|
2607
2654
|
botID: route.botID || "-",
|
|
2608
2655
|
role: route.role || "-",
|
|
2609
2656
|
roleProfile: route.roleProfile || "-",
|
|
@@ -2621,6 +2668,7 @@ async function runRunnerList(flags) {
|
|
|
2621
2668
|
return;
|
|
2622
2669
|
}
|
|
2623
2670
|
process.stdout.write("Runner routes\n");
|
|
2671
|
+
process.stdout.write(" note: routes are the executable unit. --bot-name and --bot-id are convenience selectors that resolve one enabled route when the match is unique.\n");
|
|
2624
2672
|
if (!rows.length) {
|
|
2625
2673
|
process.stdout.write(" none configured\n");
|
|
2626
2674
|
return;
|
|
@@ -2633,18 +2681,141 @@ async function runRunnerList(flags) {
|
|
|
2633
2681
|
` provider: ${row.provider}`,
|
|
2634
2682
|
` project_id: ${row.projectID}`,
|
|
2635
2683
|
` server_bot_name: ${row.botName}`,
|
|
2684
|
+
` server_bot_name_source: ${row.botNameSource}`,
|
|
2636
2685
|
` server_bot_id: ${row.botID}`,
|
|
2637
2686
|
` role: ${row.role}`,
|
|
2638
2687
|
` role_profile: ${row.roleProfile}`,
|
|
2639
2688
|
` destination_label: ${row.destinationLabel}`,
|
|
2640
2689
|
` poll_interval_ms: ${row.pollIntervalMs}`,
|
|
2641
2690
|
` run_once: ${CLI_NAME} runner once --route-name ${row.name}`,
|
|
2642
|
-
row.botName
|
|
2691
|
+
row.botName && row.botNameSource !== "unresolved"
|
|
2692
|
+
? ` route_alias_by_server_bot_name: ${CLI_NAME} runner once --bot-name "${row.botName}"`
|
|
2693
|
+
: "",
|
|
2643
2694
|
].join("\n") + "\n",
|
|
2644
2695
|
);
|
|
2645
2696
|
});
|
|
2646
2697
|
}
|
|
2647
2698
|
|
|
2699
|
+
function resolveRunnerShowSelection(flags) {
|
|
2700
|
+
const routes = resolveRunnerRoutes(flags, "once");
|
|
2701
|
+
if (!routes.length) {
|
|
2702
|
+
throw new Error("no runner route matched the provided filters");
|
|
2703
|
+
}
|
|
2704
|
+
if (routes.length > 1) {
|
|
2705
|
+
const names = routes.map((route) => normalizeRunnerRoute(route).name || runnerRouteKey(route)).join(", ");
|
|
2706
|
+
throw new Error(`Multiple enabled runner routes matched. Narrow with --route-name, --bot-name, or --bot-id. Matches: ${names}`);
|
|
2707
|
+
}
|
|
2708
|
+
return normalizeRunnerRoute(routes[0]);
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
function findRunnerTelegramEntryForRoute(route, telegramEntries) {
|
|
2712
|
+
const normalizedRoute = normalizeRunnerRoute(route);
|
|
2713
|
+
if (normalizedRoute.provider !== "telegram") return null;
|
|
2714
|
+
return ensureArray(telegramEntries).find((entry) => {
|
|
2715
|
+
const current = safeObject(entry);
|
|
2716
|
+
return (
|
|
2717
|
+
(normalizedRoute.botID && current.serverBotID && current.serverBotID === normalizedRoute.botID)
|
|
2718
|
+
|| (normalizedRoute.botName && current.serverBotName && current.serverBotName === normalizedRoute.botName)
|
|
2719
|
+
);
|
|
2720
|
+
}) || null;
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
function buildRunnerShowPayload(route, flags = {}) {
|
|
2724
|
+
const normalizedRoute = normalizeRunnerRoute(route);
|
|
2725
|
+
const runnerConfig = loadBotRunnerConfig({ persistIfNeeded: true });
|
|
2726
|
+
const diagnostics = collectRunnerRouteDiagnostics(normalizedRoute, runnerConfig);
|
|
2727
|
+
const telegramState = readTelegramEnvState();
|
|
2728
|
+
const telegramEntries = ensureArray(telegramState.entries);
|
|
2729
|
+
const matchedTelegramEntry = findRunnerTelegramEntryForRoute(normalizedRoute, telegramEntries);
|
|
2730
|
+
const botNameSource = normalizedRoute.botName
|
|
2731
|
+
? "route_config"
|
|
2732
|
+
: matchedTelegramEntry?.serverBotName
|
|
2733
|
+
? "telegram_env_lookup"
|
|
2734
|
+
: "unresolved";
|
|
2735
|
+
const resolvedServerBotName = firstNonEmptyString([
|
|
2736
|
+
normalizedRoute.botName,
|
|
2737
|
+
matchedTelegramEntry?.serverBotName,
|
|
2738
|
+
"-",
|
|
2739
|
+
]);
|
|
2740
|
+
const envConfig = normalizedRoute.provider
|
|
2741
|
+
? loadProviderEnvConfig(normalizedRoute.provider, {
|
|
2742
|
+
botID: normalizedRoute.botID,
|
|
2743
|
+
botName: resolvedServerBotName !== "-" ? resolvedServerBotName : "",
|
|
2744
|
+
route: normalizedRoute,
|
|
2745
|
+
})
|
|
2746
|
+
: null;
|
|
2747
|
+
return {
|
|
2748
|
+
ok: diagnostics.errors.length === 0,
|
|
2749
|
+
route_name: normalizedRoute.name || runnerRouteKey(normalizedRoute),
|
|
2750
|
+
route_key: runnerRouteKey(normalizedRoute),
|
|
2751
|
+
route_config_file: runnerConfig.filePath,
|
|
2752
|
+
route_config: serializeRunnerRoute(normalizedRoute),
|
|
2753
|
+
resolved_server_identity: {
|
|
2754
|
+
server_bot_name: resolvedServerBotName,
|
|
2755
|
+
server_bot_name_source: botNameSource,
|
|
2756
|
+
server_bot_id: normalizedRoute.botID || "-",
|
|
2757
|
+
telegram_entry_file: String(envConfig?.entryFilePath || "").trim() || "-",
|
|
2758
|
+
},
|
|
2759
|
+
workspace_mapping: {
|
|
2760
|
+
workspace_dir: diagnostics.workspaceDir || "-",
|
|
2761
|
+
workspace_source: diagnostics.workspaceSource || "-",
|
|
2762
|
+
},
|
|
2763
|
+
execution_profile: {
|
|
2764
|
+
route_role: normalizedRoute.role || "-",
|
|
2765
|
+
role_profile_name: diagnostics.roleProfileName || "-",
|
|
2766
|
+
client: String(diagnostics.roleProfile?.client || "").trim() || "-",
|
|
2767
|
+
model: String(diagnostics.roleProfile?.model || "").trim() || "-",
|
|
2768
|
+
permission_mode: String(diagnostics.roleProfile?.permissionMode || "").trim() || "-",
|
|
2769
|
+
reasoning_effort: String(diagnostics.roleProfile?.reasoningEffort || "").trim() || "-",
|
|
2770
|
+
},
|
|
2771
|
+
route_selection_note: "Routes are the executable unit. --bot-name and --bot-id are convenience selectors that resolve one enabled route when the match is unique.",
|
|
2772
|
+
warnings: diagnostics.warnings,
|
|
2773
|
+
errors: diagnostics.errors,
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
async function runRunnerShow(flags) {
|
|
2778
|
+
const route = resolveRunnerShowSelection(flags);
|
|
2779
|
+
const payload = buildRunnerShowPayload(route, flags);
|
|
2780
|
+
if (boolFromRaw(flags.json, false)) {
|
|
2781
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
2782
|
+
return;
|
|
2783
|
+
}
|
|
2784
|
+
process.stdout.write("Runner route details\n");
|
|
2785
|
+
process.stdout.write(" note: routes are the executable unit. --bot-name and --bot-id are convenience selectors that resolve one enabled route when the match is unique.\n");
|
|
2786
|
+
process.stdout.write(
|
|
2787
|
+
[
|
|
2788
|
+
` route_name: ${payload.route_name}`,
|
|
2789
|
+
` route_key: ${payload.route_key}`,
|
|
2790
|
+
` route_config_file: ${payload.route_config_file}`,
|
|
2791
|
+
" route_config:",
|
|
2792
|
+
` provider: ${payload.route_config.provider || "-"}`,
|
|
2793
|
+
` project_id: ${payload.route_config.project_id || "-"}`,
|
|
2794
|
+
` role: ${payload.route_config.role || "-"}`,
|
|
2795
|
+
` role_profile: ${payload.route_config.role_profile || "-"}`,
|
|
2796
|
+
` destination_label: ${payload.route_config.destination_label || "-"}`,
|
|
2797
|
+
` poll_interval_ms: ${payload.route_config.poll_interval_ms || 0}`,
|
|
2798
|
+
" resolved_server_identity:",
|
|
2799
|
+
` server_bot_name: ${payload.resolved_server_identity.server_bot_name}`,
|
|
2800
|
+
` server_bot_name_source: ${payload.resolved_server_identity.server_bot_name_source}`,
|
|
2801
|
+
` server_bot_id: ${payload.resolved_server_identity.server_bot_id}`,
|
|
2802
|
+
` telegram_entry_file: ${payload.resolved_server_identity.telegram_entry_file}`,
|
|
2803
|
+
" workspace_mapping:",
|
|
2804
|
+
` workspace_dir: ${payload.workspace_mapping.workspace_dir}`,
|
|
2805
|
+
` workspace_source: ${payload.workspace_mapping.workspace_source}`,
|
|
2806
|
+
" execution_profile:",
|
|
2807
|
+
` route_role: ${payload.execution_profile.route_role}`,
|
|
2808
|
+
` role_profile_name: ${payload.execution_profile.role_profile_name}`,
|
|
2809
|
+
` client: ${payload.execution_profile.client}`,
|
|
2810
|
+
` model: ${payload.execution_profile.model}`,
|
|
2811
|
+
` permission_mode: ${payload.execution_profile.permission_mode}`,
|
|
2812
|
+
` reasoning_effort: ${payload.execution_profile.reasoning_effort}`,
|
|
2813
|
+
payload.warnings.length ? ` warnings: ${payload.warnings.join("; ")}` : " warnings: -",
|
|
2814
|
+
payload.errors.length ? ` errors: ${payload.errors.join("; ")}` : " errors: -",
|
|
2815
|
+
].join("\n") + "\n",
|
|
2816
|
+
);
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2648
2819
|
async function runRunnerStart(flags) {
|
|
2649
2820
|
const jsonMode = boolFromRaw(flags.json, false);
|
|
2650
2821
|
const routes = resolveRunnerRoutes(flags, "start");
|
|
@@ -2709,6 +2880,10 @@ async function runRunner(argv) {
|
|
|
2709
2880
|
await runRunnerList(flags);
|
|
2710
2881
|
return;
|
|
2711
2882
|
}
|
|
2883
|
+
if (subcommand === "show") {
|
|
2884
|
+
await runRunnerShow(flags);
|
|
2885
|
+
return;
|
|
2886
|
+
}
|
|
2712
2887
|
if (subcommand === "once") {
|
|
2713
2888
|
await runRunnerOnce(flags);
|
|
2714
2889
|
return;
|
|
@@ -3938,6 +4113,7 @@ function buildBotCommandDeps() {
|
|
|
3938
4113
|
normalizeBotProvider,
|
|
3939
4114
|
normalizeTelegramBotEnvKey,
|
|
3940
4115
|
normalizeTelegramBotUsername,
|
|
4116
|
+
normalizeRunnerRoute,
|
|
3941
4117
|
normalizeRunnerRoleProfileName,
|
|
3942
4118
|
normalizeLocalAIClientName,
|
|
3943
4119
|
normalizeLocalAIPermissionMode,
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -1254,6 +1254,7 @@ function summarizeTelegramRouteLinks(parsedEnv, entry, serverBinding, deps) {
|
|
|
1254
1254
|
const selectedEntry = safeObject(entry);
|
|
1255
1255
|
const binding = safeObject(serverBinding);
|
|
1256
1256
|
const config = safeObject(requireDependency(deps, "loadBotRunnerConfig")({ persistIfNeeded: true }));
|
|
1257
|
+
const normalizeRunnerRoute = requireDependency(deps, "normalizeRunnerRoute");
|
|
1257
1258
|
const routes = ensureArray(config.routes);
|
|
1258
1259
|
const entryKey = String(selectedEntry.key || "").trim();
|
|
1259
1260
|
const defaultBotKey = String(safeObject(parsedEnv).TELEGRAM_DEFAULT_BOT_KEY || "").trim();
|
|
@@ -1267,12 +1268,12 @@ function summarizeTelegramRouteLinks(parsedEnv, entry, serverBinding, deps) {
|
|
|
1267
1268
|
);
|
|
1268
1269
|
const linkedRoutes = [];
|
|
1269
1270
|
routes.forEach((rawRoute, index) => {
|
|
1270
|
-
const route =
|
|
1271
|
+
const route = normalizeRunnerRoute(rawRoute);
|
|
1271
1272
|
if (route.enabled === false) return;
|
|
1272
1273
|
if (String(route.provider || "").trim().toLowerCase() !== "telegram") return;
|
|
1273
1274
|
const routeName = String(route.name || route.route_name || `telegram-route-${index + 1}`).trim();
|
|
1274
|
-
const routeBotID = String(route.bot_id || route.botID || "").trim();
|
|
1275
|
-
const routeBotName = normalizeServerBotIdentityText(route.bot_name || route.botName || "");
|
|
1275
|
+
const routeBotID = String(route.server_bot_id || route.serverBotID || route.bot_id || route.botID || "").trim();
|
|
1276
|
+
const routeBotName = normalizeServerBotIdentityText(route.server_bot_name || route.serverBotName || route.bot_name || route.botName || "");
|
|
1276
1277
|
const routeRole = String(route.role_profile || route.roleProfile || route.role || "").trim();
|
|
1277
1278
|
let matchedBy = "";
|
|
1278
1279
|
if (serverBotID && routeBotID === serverBotID) {
|
|
@@ -565,7 +565,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
565
565
|
enabled: true,
|
|
566
566
|
project_id: "03c586a2-006d-4051-83b4-f353a5813176",
|
|
567
567
|
provider: "telegram",
|
|
568
|
-
|
|
568
|
+
server_bot_id: mock.bots[0].id,
|
|
569
569
|
role_profile: "monitor",
|
|
570
570
|
},
|
|
571
571
|
{
|
|
@@ -415,7 +415,26 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
415
415
|
originalResolveUserProfile = process.env.USERPROFILE;
|
|
416
416
|
const resolveHome = path.join(runnerRouteResolveTempRoot, "home");
|
|
417
417
|
const resolveMetheusDir = path.join(resolveHome, ".metheus");
|
|
418
|
+
const resolveTelegramDir = path.join(resolveMetheusDir, "telegram-bots");
|
|
418
419
|
fs.mkdirSync(resolveMetheusDir, { recursive: true });
|
|
420
|
+
fs.mkdirSync(resolveTelegramDir, { recursive: true });
|
|
421
|
+
fs.writeFileSync(
|
|
422
|
+
path.join(resolveTelegramDir, "global.env"),
|
|
423
|
+
"TELEGRAM_DEFAULT_BOT_KEY=serverprotocolmonitorbot\n",
|
|
424
|
+
"utf8",
|
|
425
|
+
);
|
|
426
|
+
fs.writeFileSync(
|
|
427
|
+
path.join(resolveTelegramDir, "ServerProtocolMonitorBot.env"),
|
|
428
|
+
[
|
|
429
|
+
"TELEGRAM_BOT_SERVER_BOT_ID=22222222-2222-2222-2222-222222222222",
|
|
430
|
+
"TELEGRAM_BOT_SERVER_NAME=ServerProtocolMonitorBot",
|
|
431
|
+
"TELEGRAM_BOT_SERVER_ROLES=monitor",
|
|
432
|
+
"TELEGRAM_BOT_SERVER_ROLE_IDS=monitor:22222222-2222-2222-2222-222222222222",
|
|
433
|
+
"TELEGRAM_BOT_TOKEN=test-token",
|
|
434
|
+
"",
|
|
435
|
+
].join("\n"),
|
|
436
|
+
"utf8",
|
|
437
|
+
);
|
|
419
438
|
fs.writeFileSync(
|
|
420
439
|
path.join(resolveMetheusDir, "bot-runner.json"),
|
|
421
440
|
`${JSON.stringify({
|
|
@@ -435,9 +454,21 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
435
454
|
provider: "telegram",
|
|
436
455
|
role: "monitor",
|
|
437
456
|
role_profile: "monitor",
|
|
438
|
-
|
|
457
|
+
bot_id: "22222222-2222-2222-2222-222222222222",
|
|
439
458
|
destination_label: "AI incubating CHAT ROOM",
|
|
440
459
|
archive_work_item_id: "304ce77a-7032-421c-aeda-bc54daf088dd",
|
|
460
|
+
trigger_policy: {
|
|
461
|
+
mentions_only: true,
|
|
462
|
+
direct_messages: true,
|
|
463
|
+
reply_to_bot_messages: true,
|
|
464
|
+
ignore_edited_messages: true,
|
|
465
|
+
},
|
|
466
|
+
archive_policy: {
|
|
467
|
+
mirror_replies: true,
|
|
468
|
+
dedupe_inbound: true,
|
|
469
|
+
dedupe_outbound: true,
|
|
470
|
+
skip_bot_messages: true,
|
|
471
|
+
},
|
|
441
472
|
},
|
|
442
473
|
],
|
|
443
474
|
}, null, 2)}\n`,
|
|
@@ -457,14 +488,18 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
457
488
|
"once",
|
|
458
489
|
);
|
|
459
490
|
const resolvedRunnerRoute = normalizeRunnerRoute(resolvedRunnerRoutes[0]);
|
|
491
|
+
const persistedRunnerConfig = JSON.parse(fs.readFileSync(path.join(resolveMetheusDir, "bot-runner.json"), "utf8"));
|
|
492
|
+
const persistedRoute = Array.isArray(persistedRunnerConfig.routes) ? persistedRunnerConfig.routes[0] || {} : {};
|
|
460
493
|
push(
|
|
461
494
|
"bot_runner_inline_filters_reuse_configured_route",
|
|
462
495
|
resolvedRunnerRoutes.length === 1
|
|
463
496
|
&& resolvedRunnerRoute.name === "telegram-monitor"
|
|
464
497
|
&& resolvedRunnerRoute.destinationLabel === "AI incubating CHAT ROOM"
|
|
465
498
|
&& resolvedRunnerRoute.dryRunDelivery === true
|
|
466
|
-
&& runnerRouteKey(resolvedRunnerRoute) === "telegram-monitor::11111111-1111-1111-1111-111111111111::telegram::monitor::
|
|
467
|
-
|
|
499
|
+
&& runnerRouteKey(resolvedRunnerRoute) === "telegram-monitor::11111111-1111-1111-1111-111111111111::telegram::monitor::22222222-2222-2222-2222-222222222222::AI incubating CHAT ROOM"
|
|
500
|
+
&& String(persistedRoute.server_bot_id || "") === "22222222-2222-2222-2222-222222222222"
|
|
501
|
+
&& !Object.prototype.hasOwnProperty.call(persistedRoute, "bot_id"),
|
|
502
|
+
`name=${resolvedRunnerRoute.name || "(none)"} destination=${resolvedRunnerRoute.destinationLabel || "(none)"} key=${runnerRouteKey(resolvedRunnerRoute)} persisted=${JSON.stringify(persistedRoute)}`,
|
|
468
503
|
);
|
|
469
504
|
} catch (err) {
|
|
470
505
|
push("bot_runner_inline_filters_reuse_configured_route", false, String(err?.message || err));
|