metheus-governance-mcp-cli 0.2.84 → 0.2.86
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 +3 -2
- package/cli.mjs +3 -0
- package/lib/bot-commands.mjs +6 -6
- package/lib/local-ai-adapters.mjs +166 -24
- package/lib/selftest-bot-commands.mjs +23 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -241,7 +241,7 @@ Behavior:
|
|
|
241
241
|
- `Sonnet 4.6r` -> `sonnet`
|
|
242
242
|
- `Haiku 4.5` -> `haiku`
|
|
243
243
|
- `Opus 4.6` -> `opus`
|
|
244
|
-
- `
|
|
244
|
+
- `gemini-3.1-pro` -> `auto-gemini-3`
|
|
245
245
|
- if one server bot name maps to multiple server roles, `bot edit` keeps the Telegram env entry bound to the server identity and lets you review the local `role_profiles` for each detected role instead of forcing one role/profile UUID choice up front.
|
|
246
246
|
- In the normal Telegram edit path, the CLI keeps or re-resolves the server bot binding automatically. It no longer asks you to pick `approval / worker / review / monitor` or a server bot UUID first.
|
|
247
247
|
- `bot set-default` without flags starts a guided numbered flow: provider -> bot entry -> confirm default change.
|
|
@@ -410,7 +410,8 @@ Recommended role mapping:
|
|
|
410
410
|
Role profile note:
|
|
411
411
|
- Claude maps `reasoning_effort` to `--effort`.
|
|
412
412
|
- Codex maps `reasoning_effort` to `-c model_reasoning_effort="..."`.
|
|
413
|
-
- Gemini
|
|
413
|
+
- Gemini applies `reasoning_effort` by injecting a temporary `~/.gemini/settings.json` override for the invocation.
|
|
414
|
+
- For Gemini 3 models, `low -> thinkingLevel LOW`, `medium -> THINKING_LEVEL_UNSPECIFIED` (Gemini default), and `high -> thinkingLevel HIGH`.
|
|
414
415
|
|
|
415
416
|
Trigger policy fields:
|
|
416
417
|
- `mentions_only`: in groups, react only when the bot is mentioned or when a message replies to the bot
|
package/cli.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import https from "node:https";
|
|
|
11
11
|
import {
|
|
12
12
|
DEFAULT_LOCAL_AI_CLIENT,
|
|
13
13
|
resolveLocalAIExecutionModel,
|
|
14
|
+
resolveGeminiReasoningConfig,
|
|
14
15
|
SUPPORTED_LOCAL_AI_CLIENTS,
|
|
15
16
|
normalizeLocalAIClientName,
|
|
16
17
|
normalizeLocalAIPermissionMode,
|
|
@@ -3358,6 +3359,7 @@ function buildBotCommandDeps() {
|
|
|
3358
3359
|
normalizeLocalAIClientName,
|
|
3359
3360
|
normalizeLocalAIPermissionMode,
|
|
3360
3361
|
normalizeLocalAIReasoningEffort,
|
|
3362
|
+
resolveGeminiReasoningConfig,
|
|
3361
3363
|
supportedLocalAIClients: SUPPORTED_LOCAL_AI_CLIENTS,
|
|
3362
3364
|
summarizeProviderSupport,
|
|
3363
3365
|
loadProviderEnvConfig,
|
|
@@ -5209,6 +5211,7 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
5209
5211
|
cliPath: fileURLToPath(import.meta.url),
|
|
5210
5212
|
parseSimpleEnvText,
|
|
5211
5213
|
resolveLocalAIExecutionModel,
|
|
5214
|
+
resolveGeminiReasoningConfig,
|
|
5212
5215
|
});
|
|
5213
5216
|
|
|
5214
5217
|
const payload = buildSelftestPayload(checks);
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -1473,12 +1473,12 @@ function suggestedAIModelsForClient(clientName) {
|
|
|
1473
1473
|
{ value: "Haiku 4.5", label: "Haiku 4.5", description: "display label; runs as haiku" },
|
|
1474
1474
|
{ value: "Opus 4.6", label: "Opus 4.6", description: "display label; runs as opus" },
|
|
1475
1475
|
];
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1476
|
+
}
|
|
1477
|
+
if (normalizedClient === "gemini") {
|
|
1478
|
+
return [
|
|
1479
|
+
{ value: "gemini-3.1-pro", label: "gemini-3.1-pro", description: "display label; runs as auto-gemini-3" },
|
|
1480
|
+
];
|
|
1481
|
+
}
|
|
1482
1482
|
if (normalizedClient === "sample") {
|
|
1483
1483
|
return [
|
|
1484
1484
|
{ value: "sample", label: "sample", description: "sample adapter model placeholder" },
|
|
@@ -8,6 +8,15 @@ export const DEFAULT_LOCAL_AI_CLIENT = "codex";
|
|
|
8
8
|
|
|
9
9
|
const SUPPORTED_PERMISSION_MODES = ["read_only", "workspace_write", "danger_full_access"];
|
|
10
10
|
const SUPPORTED_REASONING_EFFORTS = ["low", "medium", "high"];
|
|
11
|
+
const GEMINI_HOME_SYNC_FILES = [
|
|
12
|
+
"google_accounts.json",
|
|
13
|
+
"oauth_creds.json",
|
|
14
|
+
"installation_id",
|
|
15
|
+
"state.json",
|
|
16
|
+
"trustedFolders.json",
|
|
17
|
+
"projects.json",
|
|
18
|
+
"settings.json",
|
|
19
|
+
];
|
|
11
20
|
const LOCAL_AI_MODEL_MAPPINGS = {
|
|
12
21
|
codex: [
|
|
13
22
|
{
|
|
@@ -45,9 +54,16 @@ const LOCAL_AI_MODEL_MAPPINGS = {
|
|
|
45
54
|
],
|
|
46
55
|
gemini: [
|
|
47
56
|
{
|
|
48
|
-
display: "
|
|
49
|
-
execution: "gemini-
|
|
50
|
-
aliases: [
|
|
57
|
+
display: "gemini-3.1-pro",
|
|
58
|
+
execution: "auto-gemini-3",
|
|
59
|
+
aliases: [
|
|
60
|
+
"gemini-3.1-pro",
|
|
61
|
+
"gemini 3.1 pro",
|
|
62
|
+
"Gemini 3.1 Pro",
|
|
63
|
+
"gemini-3.1-pro-preview",
|
|
64
|
+
"auto-gemini-3",
|
|
65
|
+
"pro",
|
|
66
|
+
],
|
|
51
67
|
},
|
|
52
68
|
],
|
|
53
69
|
sample: [],
|
|
@@ -73,6 +89,10 @@ function ensureArray(value) {
|
|
|
73
89
|
return Array.isArray(value) ? value : [];
|
|
74
90
|
}
|
|
75
91
|
|
|
92
|
+
function safeObject(value) {
|
|
93
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
94
|
+
}
|
|
95
|
+
|
|
76
96
|
function intFromRawAllowZero(rawValue, fallback = 0) {
|
|
77
97
|
const parsed = Number.parseInt(String(rawValue ?? "").trim(), 10);
|
|
78
98
|
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
@@ -323,6 +343,122 @@ function buildGeminiArgs({ promptText, model, permissionMode }) {
|
|
|
323
343
|
return args;
|
|
324
344
|
}
|
|
325
345
|
|
|
346
|
+
function isGemini3ExecutionModel(model) {
|
|
347
|
+
const normalizedModel = normalizeModelAliasText(model);
|
|
348
|
+
return normalizedModel === "auto-gemini-3" || normalizedModel.startsWith("gemini-3");
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function readJsonFileIfExists(filePath) {
|
|
352
|
+
if (!filePath || !fs.existsSync(filePath)) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
try {
|
|
356
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
357
|
+
} catch {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function copyFileIfExists(sourcePath, targetPath) {
|
|
363
|
+
if (!sourcePath || !targetPath || !fs.existsSync(sourcePath)) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
367
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function buildGeminiThinkingConfig(model, reasoningEffort) {
|
|
371
|
+
const normalizedReasoningEffort = normalizeLocalAIReasoningEffort(reasoningEffort, "");
|
|
372
|
+
if (!normalizedReasoningEffort) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
if (isGemini3ExecutionModel(model)) {
|
|
376
|
+
if (normalizedReasoningEffort === "low") {
|
|
377
|
+
return { thinkingLevel: "LOW" };
|
|
378
|
+
}
|
|
379
|
+
if (normalizedReasoningEffort === "high") {
|
|
380
|
+
return { thinkingLevel: "HIGH" };
|
|
381
|
+
}
|
|
382
|
+
return { thinkingLevel: "THINKING_LEVEL_UNSPECIFIED" };
|
|
383
|
+
}
|
|
384
|
+
const thinkingBudgetMap = {
|
|
385
|
+
low: 0,
|
|
386
|
+
medium: 4096,
|
|
387
|
+
high: 8192,
|
|
388
|
+
};
|
|
389
|
+
return {
|
|
390
|
+
thinkingBudget: thinkingBudgetMap[normalizedReasoningEffort] ?? thinkingBudgetMap.medium,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export function resolveGeminiReasoningConfig(rawModelValue = "", reasoningEffort = "medium") {
|
|
395
|
+
const executionModel = resolveLocalAIExecutionModel("gemini", rawModelValue);
|
|
396
|
+
const thinkingConfig = buildGeminiThinkingConfig(executionModel, reasoningEffort);
|
|
397
|
+
if (!thinkingConfig) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
model: executionModel,
|
|
402
|
+
thinkingConfig,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function buildGeminiSettingsOverride(existingSettings, model, reasoningEffort) {
|
|
407
|
+
const resolved = resolveGeminiReasoningConfig(model, reasoningEffort);
|
|
408
|
+
if (!resolved) {
|
|
409
|
+
return safeObject(existingSettings);
|
|
410
|
+
}
|
|
411
|
+
const baseSettings = safeObject(existingSettings);
|
|
412
|
+
const baseModelConfigs = safeObject(baseSettings.modelConfigs);
|
|
413
|
+
const nextOverrides = ensureArray(baseModelConfigs.overrides).slice();
|
|
414
|
+
nextOverrides.push({
|
|
415
|
+
match: { model: resolved.model },
|
|
416
|
+
modelConfig: {
|
|
417
|
+
generateContentConfig: {
|
|
418
|
+
thinkingConfig: resolved.thinkingConfig,
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
return {
|
|
423
|
+
...baseSettings,
|
|
424
|
+
modelConfigs: {
|
|
425
|
+
...baseModelConfigs,
|
|
426
|
+
overrides: nextOverrides,
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function prepareGeminiRuntimeEnv({ model, reasoningEffort, env }) {
|
|
432
|
+
const sourceHome = String(env?.GEMINI_CLI_HOME || os.homedir() || "").trim();
|
|
433
|
+
const sourceGeminiDir = sourceHome ? path.join(sourceHome, ".gemini") : "";
|
|
434
|
+
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "metheus-gemini-home-"));
|
|
435
|
+
const tempGeminiDir = path.join(tempHome, ".gemini");
|
|
436
|
+
fs.mkdirSync(tempGeminiDir, { recursive: true });
|
|
437
|
+
for (const fileName of GEMINI_HOME_SYNC_FILES) {
|
|
438
|
+
copyFileIfExists(
|
|
439
|
+
sourceGeminiDir ? path.join(sourceGeminiDir, fileName) : "",
|
|
440
|
+
path.join(tempGeminiDir, fileName),
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
const mergedSettings = buildGeminiSettingsOverride(
|
|
444
|
+
readJsonFileIfExists(path.join(tempGeminiDir, "settings.json")),
|
|
445
|
+
model,
|
|
446
|
+
reasoningEffort,
|
|
447
|
+
);
|
|
448
|
+
fs.writeFileSync(path.join(tempGeminiDir, "settings.json"), `${JSON.stringify(mergedSettings, null, 2)}\n`, "utf8");
|
|
449
|
+
return {
|
|
450
|
+
env: {
|
|
451
|
+
...env,
|
|
452
|
+
GEMINI_CLI_HOME: tempHome,
|
|
453
|
+
},
|
|
454
|
+
cleanup() {
|
|
455
|
+
if (fs.existsSync(tempHome)) {
|
|
456
|
+
fs.rmSync(tempHome, { recursive: true, force: true });
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
326
462
|
function runCodexAdapter({ promptText, workspaceDir, model, permissionMode, reasoningEffort, env }) {
|
|
327
463
|
const outputPath = path.join(os.tmpdir(), `metheus-runner-codex-${Date.now()}-${Math.random().toString(36).slice(2)}.txt`);
|
|
328
464
|
const codexCommand = resolveLocalCliCommand("codex");
|
|
@@ -385,29 +521,34 @@ function runClaudeAdapter({ promptText, workspaceDir, model, permissionMode, rea
|
|
|
385
521
|
return normalizeCliOutput(result.stdout);
|
|
386
522
|
}
|
|
387
523
|
|
|
388
|
-
function runGeminiAdapter({ promptText, workspaceDir, model, permissionMode, env }) {
|
|
524
|
+
function runGeminiAdapter({ promptText, workspaceDir, model, permissionMode, reasoningEffort, env }) {
|
|
389
525
|
const geminiCommand = resolveLocalCliCommand("gemini");
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
526
|
+
const runtime = prepareGeminiRuntimeEnv({ model, reasoningEffort, env });
|
|
527
|
+
try {
|
|
528
|
+
const result = spawnCli(
|
|
529
|
+
geminiCommand,
|
|
530
|
+
buildGeminiArgs({
|
|
531
|
+
promptText,
|
|
532
|
+
model,
|
|
533
|
+
permissionMode,
|
|
534
|
+
}),
|
|
535
|
+
{
|
|
536
|
+
cwd: workspaceDir,
|
|
537
|
+
encoding: "utf8",
|
|
538
|
+
env: runtime.env,
|
|
539
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
540
|
+
},
|
|
541
|
+
);
|
|
542
|
+
if (result.error) {
|
|
543
|
+
throw new Error(String(result.error?.message || result.error));
|
|
544
|
+
}
|
|
545
|
+
if (result.status !== 0) {
|
|
546
|
+
throw new Error(String(result.stderr || result.stdout || `gemini exited with status ${result.status}`));
|
|
547
|
+
}
|
|
548
|
+
return normalizeCliOutput(result.stdout);
|
|
549
|
+
} finally {
|
|
550
|
+
runtime.cleanup();
|
|
409
551
|
}
|
|
410
|
-
return normalizeCliOutput(result.stdout);
|
|
411
552
|
}
|
|
412
553
|
|
|
413
554
|
function runSampleAdapter(payload) {
|
|
@@ -601,6 +742,7 @@ export function runLocalAIClient({
|
|
|
601
742
|
workspaceDir: resolvedWorkspaceDir,
|
|
602
743
|
model: resolvedExecutionModel,
|
|
603
744
|
permissionMode: normalizedPermissionMode,
|
|
745
|
+
reasoningEffort: normalizedReasoningEffort,
|
|
604
746
|
env: nextEnv,
|
|
605
747
|
});
|
|
606
748
|
}
|
|
@@ -229,6 +229,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
229
229
|
const cliPath = String(requireDependency(deps, "cliPath") || "").trim();
|
|
230
230
|
const parseSimpleEnvText = requireDependency(deps, "parseSimpleEnvText");
|
|
231
231
|
const resolveLocalAIExecutionModel = requireDependency(deps, "resolveLocalAIExecutionModel");
|
|
232
|
+
const resolveGeminiReasoningConfig = requireDependency(deps, "resolveGeminiReasoningConfig");
|
|
232
233
|
let tempHome = "";
|
|
233
234
|
let mock = null;
|
|
234
235
|
try {
|
|
@@ -243,13 +244,29 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
243
244
|
&& resolveLocalAIExecutionModel("claude", "Sonnet 4.6r") === "sonnet"
|
|
244
245
|
&& resolveLocalAIExecutionModel("claude", "Haiku 4.5") === "haiku"
|
|
245
246
|
&& resolveLocalAIExecutionModel("claude", "Opus 4.6") === "opus"
|
|
246
|
-
&& resolveLocalAIExecutionModel("gemini", "
|
|
247
|
+
&& resolveLocalAIExecutionModel("gemini", "gemini-3.1-pro") === "auto-gemini-3",
|
|
247
248
|
[
|
|
248
249
|
`gpt54=${resolveLocalAIExecutionModel("codex", "gpt-5.4")}`,
|
|
249
250
|
`gpt53codex=${resolveLocalAIExecutionModel("codex", "gpt-5.3-codex")}`,
|
|
250
251
|
`spark=${resolveLocalAIExecutionModel("codex", "gpt-5.3-codex-spark")}`,
|
|
251
252
|
`claude=${resolveLocalAIExecutionModel("claude", "Sonnet 4.6r")}`,
|
|
252
|
-
`gemini=${resolveLocalAIExecutionModel("gemini", "
|
|
253
|
+
`gemini=${resolveLocalAIExecutionModel("gemini", "gemini-3.1-pro")}`,
|
|
254
|
+
].join(" "),
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const geminiLowReasoning = resolveGeminiReasoningConfig("gemini-3.1-pro", "low");
|
|
258
|
+
const geminiMediumReasoning = resolveGeminiReasoningConfig("gemini-3.1-pro", "medium");
|
|
259
|
+
const geminiHighReasoning = resolveGeminiReasoningConfig("gemini-3.1-pro", "high");
|
|
260
|
+
push(
|
|
261
|
+
"gemini_reasoning_effort_maps_to_runtime_settings_override",
|
|
262
|
+
String(geminiLowReasoning?.model || "") === "auto-gemini-3"
|
|
263
|
+
&& String(safeObject(geminiLowReasoning?.thinkingConfig).thinkingLevel || "") === "LOW"
|
|
264
|
+
&& String(safeObject(geminiMediumReasoning?.thinkingConfig).thinkingLevel || "") === "THINKING_LEVEL_UNSPECIFIED"
|
|
265
|
+
&& String(safeObject(geminiHighReasoning?.thinkingConfig).thinkingLevel || "") === "HIGH",
|
|
266
|
+
[
|
|
267
|
+
`low=${JSON.stringify(geminiLowReasoning?.thinkingConfig || {})}`,
|
|
268
|
+
`medium=${JSON.stringify(geminiMediumReasoning?.thinkingConfig || {})}`,
|
|
269
|
+
`high=${JSON.stringify(geminiHighReasoning?.thinkingConfig || {})}`,
|
|
253
270
|
].join(" "),
|
|
254
271
|
);
|
|
255
272
|
|
|
@@ -393,7 +410,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
393
410
|
"3", // select role to edit: approval
|
|
394
411
|
"2", // approval: edit settings
|
|
395
412
|
"4", // approval AI client: gemini
|
|
396
|
-
"2", // approval AI model:
|
|
413
|
+
"2", // approval AI model: gemini-3.1-pro
|
|
397
414
|
"4", // approval permission: danger_full_access
|
|
398
415
|
"4", // approval reasoning: high
|
|
399
416
|
"n", // stop editing roles
|
|
@@ -416,7 +433,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
416
433
|
&& String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker).permission_mode || "") === "danger_full_access"
|
|
417
434
|
&& String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker).reasoning_effort || "") === "high"
|
|
418
435
|
&& String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval).client || "") === "gemini"
|
|
419
|
-
&& String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval).model || "") === "
|
|
436
|
+
&& String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval).model || "") === "gemini-3.1-pro",
|
|
420
437
|
`worker=${JSON.stringify(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker))} approval=${JSON.stringify(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval))}`,
|
|
421
438
|
);
|
|
422
439
|
|
|
@@ -525,7 +542,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
525
542
|
"2", // change AI client
|
|
526
543
|
"4", // gemini
|
|
527
544
|
"2", // change AI model
|
|
528
|
-
"2", // gemini model:
|
|
545
|
+
"2", // gemini model: gemini-3.1-pro
|
|
529
546
|
"2", // change permission mode
|
|
530
547
|
"3", // workspace_write
|
|
531
548
|
"2", // change reasoning effort
|
|
@@ -544,7 +561,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
544
561
|
push(
|
|
545
562
|
"bot_edit_guided_prompts_update_ai_binding_fields",
|
|
546
563
|
String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_CLIENT || "") === "gemini"
|
|
547
|
-
&& String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_MODEL || "") === "
|
|
564
|
+
&& String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_MODEL || "") === "gemini-3.1-pro"
|
|
548
565
|
&& String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_PERMISSION_MODE || "") === "workspace_write"
|
|
549
566
|
&& String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_REASONING_EFFORT || "") === "medium",
|
|
550
567
|
`client=${String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_CLIENT || "")} model=${String(guidedState.TELEGRAM_BOT_MONITORSELFTESTBOT_AI_MODEL || "")}`,
|