metheus-governance-mcp-cli 0.2.282 → 0.2.283
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
CHANGED
|
@@ -25,9 +25,10 @@ import {
|
|
|
25
25
|
resolveRolePlannerAuditorModelDisplayName,
|
|
26
26
|
resolveRolePlannerModelDisplayName,
|
|
27
27
|
resolveRolePlannerRepairModelDisplayName,
|
|
28
|
-
resolveResponderAdjudicatorModelDisplayName,
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
resolveResponderAdjudicatorModelDisplayName,
|
|
29
|
+
resolveGeminiHeadlessExecutionModel,
|
|
30
|
+
resolveGeminiReasoningConfig,
|
|
31
|
+
suggestLocalAIModelDisplayName,
|
|
31
32
|
SUPPORTED_LOCAL_AI_CLIENTS,
|
|
32
33
|
normalizeLocalAIClientName,
|
|
33
34
|
normalizeLocalAIPermissionMode,
|
|
@@ -4144,12 +4145,14 @@ function buildRunnerValidationAndDeliverySummary({
|
|
|
4144
4145
|
responseContractValidationStatus = "",
|
|
4145
4146
|
responseContractValidationReason = "",
|
|
4146
4147
|
responseContractValidationTargets = [],
|
|
4147
|
-
assignmentValidationStatus = "",
|
|
4148
|
-
assignmentValidationReason = "",
|
|
4149
|
-
assignmentValidationModes = [],
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4148
|
+
assignmentValidationStatus = "",
|
|
4149
|
+
assignmentValidationReason = "",
|
|
4150
|
+
assignmentValidationModes = [],
|
|
4151
|
+
failureReplyClassification = "",
|
|
4152
|
+
failureFacts = {},
|
|
4153
|
+
deliveryStatus = "",
|
|
4154
|
+
archiveStatus = "",
|
|
4155
|
+
transportError = "",
|
|
4153
4156
|
archiveError = "",
|
|
4154
4157
|
sourceMessageEnvelope = {},
|
|
4155
4158
|
lastReplyMessageEnvelope = {},
|
|
@@ -6381,12 +6384,14 @@ function markRunnerRequestLifecycle({
|
|
|
6381
6384
|
responseContractValidationStatus = "",
|
|
6382
6385
|
responseContractValidationReason = "",
|
|
6383
6386
|
responseContractValidationTargets = [],
|
|
6384
|
-
assignmentValidationStatus = "",
|
|
6385
|
-
assignmentValidationReason = "",
|
|
6386
|
-
assignmentValidationModes = [],
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6387
|
+
assignmentValidationStatus = "",
|
|
6388
|
+
assignmentValidationReason = "",
|
|
6389
|
+
assignmentValidationModes = [],
|
|
6390
|
+
failureReplyClassification = "",
|
|
6391
|
+
failureFacts = {},
|
|
6392
|
+
deliveryStatus = "",
|
|
6393
|
+
archiveStatus = "",
|
|
6394
|
+
transportError = "",
|
|
6390
6395
|
archiveError = "",
|
|
6391
6396
|
lastReplyMessageID = 0,
|
|
6392
6397
|
lastReplyMessageThreadID = 0,
|
|
@@ -6497,6 +6502,8 @@ function markRunnerRequestLifecycle({
|
|
|
6497
6502
|
|| "",
|
|
6498
6503
|
).trim().toLowerCase();
|
|
6499
6504
|
const normalizedOutcome = String(outcome || "").trim().toLowerCase();
|
|
6505
|
+
const normalizedFailureReplyClassification = String(failureReplyClassification || "").trim().toLowerCase();
|
|
6506
|
+
const normalizedFailureFacts = safeObject(failureFacts);
|
|
6500
6507
|
const shouldRemainRunningAfterReply = authoritativeDecisionBundle.should_close_after_reply === true
|
|
6501
6508
|
? false
|
|
6502
6509
|
: authoritativeDecisionBundle.should_close_after_reply === false
|
|
@@ -6511,6 +6518,18 @@ function markRunnerRequestLifecycle({
|
|
|
6511
6518
|
|| rootEffectiveNextExpectedResponders.length > 0
|
|
6512
6519
|
|| continuationSelectors.length > 0
|
|
6513
6520
|
);
|
|
6521
|
+
const shouldRemainRunningAfterError = ["error", "execution_failed"].includes(normalizedOutcome)
|
|
6522
|
+
&& (
|
|
6523
|
+
normalizedFailureFacts.retryable === true
|
|
6524
|
+
|| normalizedFailureReplyClassification === "retryable_failure"
|
|
6525
|
+
)
|
|
6526
|
+
&& authoritativeDecisionBundle.should_close_after_reply !== true
|
|
6527
|
+
&& (
|
|
6528
|
+
nextExecutionContractType === "delegation"
|
|
6529
|
+
|| rootEffectiveExecutionContractTargets.length > 0
|
|
6530
|
+
|| rootEffectiveNextExpectedResponders.length > 0
|
|
6531
|
+
|| continuationSelectors.length > 0
|
|
6532
|
+
);
|
|
6514
6533
|
const nextConversationIntentMode = String(
|
|
6515
6534
|
authoritativeDecisionBundle.conversation_intent_mode
|
|
6516
6535
|
|| conversationIntentMode
|
|
@@ -6547,7 +6566,7 @@ function markRunnerRequestLifecycle({
|
|
|
6547
6566
|
|| normalizedOutcome === "execution_failed"
|
|
6548
6567
|
|| normalizedOutcome === "policy_violation"
|
|
6549
6568
|
) {
|
|
6550
|
-
return "closed";
|
|
6569
|
+
return shouldRemainRunningAfterError ? "running" : "closed";
|
|
6551
6570
|
}
|
|
6552
6571
|
return normalizeRunnerRequestStatus(existing.status);
|
|
6553
6572
|
})();
|
|
@@ -19554,12 +19573,13 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
19554
19573
|
push("runner_tui_frame_renders_route_statuses", false, String(err?.message || err));
|
|
19555
19574
|
}
|
|
19556
19575
|
|
|
19557
|
-
await runSelftestBotCommands(push, {
|
|
19558
|
-
cliPath: fileURLToPath(import.meta.url),
|
|
19559
|
-
parseSimpleEnvText,
|
|
19560
|
-
resolveLocalAIExecutionModel,
|
|
19561
|
-
|
|
19562
|
-
|
|
19576
|
+
await runSelftestBotCommands(push, {
|
|
19577
|
+
cliPath: fileURLToPath(import.meta.url),
|
|
19578
|
+
parseSimpleEnvText,
|
|
19579
|
+
resolveLocalAIExecutionModel,
|
|
19580
|
+
resolveGeminiHeadlessExecutionModel,
|
|
19581
|
+
suggestLocalAIModelDisplayName,
|
|
19582
|
+
resolveGeminiReasoningConfig,
|
|
19563
19583
|
stripLocalOnlyToolArgs: (requestObj, toolName) =>
|
|
19564
19584
|
stripLocalOnlyToolArgs(requestObj, toolName),
|
|
19565
19585
|
applyProxyResponsePatches: (params, deps = buildProxyResponsePipelineDeps()) =>
|
|
@@ -19,6 +19,7 @@ const GEMINI_HOME_SYNC_FILES = [
|
|
|
19
19
|
];
|
|
20
20
|
const GEMINI_STDIN_BRIDGE_PROMPT = "Use the full task provided on standard input as the authoritative prompt. Follow it exactly and output only the final answer.";
|
|
21
21
|
const GEMINI_CLI_TIMEOUT_MS = 90 * 1000;
|
|
22
|
+
const GEMINI_RUNNER_STABLE_EXECUTION_MODEL = "gemini-3-flash-preview";
|
|
22
23
|
const LOCAL_AI_MODEL_MAPPINGS = {
|
|
23
24
|
gpt: [
|
|
24
25
|
{
|
|
@@ -880,7 +881,12 @@ function runLocalAIPromptRawText({
|
|
|
880
881
|
const normalizedClient = normalizeLocalAIClientName(client);
|
|
881
882
|
const normalizedPermissionMode = normalizeLocalAIPermissionMode(permissionMode);
|
|
882
883
|
const normalizedReasoningEffort = normalizeLocalAIReasoningEffort(reasoningEffort, "low");
|
|
883
|
-
const resolvedExecutionModel =
|
|
884
|
+
const resolvedExecutionModel = normalizedClient === "gemini"
|
|
885
|
+
? resolveGeminiHeadlessExecutionModel(model, {
|
|
886
|
+
permissionMode: normalizedPermissionMode,
|
|
887
|
+
reasoningEffort: normalizedReasoningEffort,
|
|
888
|
+
})
|
|
889
|
+
: resolveLocalAIExecutionModel(normalizedClient, model);
|
|
884
890
|
const resolvedWorkspaceDir = ensureWorkspaceDir(workspaceDir);
|
|
885
891
|
const nextEnv = {
|
|
886
892
|
...process.env,
|
|
@@ -1386,6 +1392,23 @@ export function resolveLocalAIExecutionModel(clientName, rawModelValue = "") {
|
|
|
1386
1392
|
return match ? String(match.execution || "").trim() : modelValue;
|
|
1387
1393
|
}
|
|
1388
1394
|
|
|
1395
|
+
export function resolveGeminiHeadlessExecutionModel(
|
|
1396
|
+
rawModelValue = "",
|
|
1397
|
+
{ permissionMode = "read_only", reasoningEffort = "low" } = {},
|
|
1398
|
+
) {
|
|
1399
|
+
const resolvedExecutionModel = resolveLocalAIExecutionModel("gemini", rawModelValue);
|
|
1400
|
+
const normalizedExecutionModel = normalizeModelAliasText(resolvedExecutionModel);
|
|
1401
|
+
void normalizeLocalAIPermissionMode(permissionMode);
|
|
1402
|
+
void normalizeLocalAIReasoningEffort(reasoningEffort, "low");
|
|
1403
|
+
if (normalizedExecutionModel !== "auto-gemini-3") {
|
|
1404
|
+
return resolvedExecutionModel;
|
|
1405
|
+
}
|
|
1406
|
+
// Headless runner turns should not depend on Gemini CLI's internal auto-router.
|
|
1407
|
+
// Under heavier prompts it can escalate to capacity-constrained preview models,
|
|
1408
|
+
// which makes one bot path look flaky even though the routing logic is correct.
|
|
1409
|
+
return GEMINI_RUNNER_STABLE_EXECUTION_MODEL;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1389
1412
|
function buildCodexArgs({ workspaceDir, model, permissionMode, reasoningEffort, outputPath }) {
|
|
1390
1413
|
const args = ["exec"];
|
|
1391
1414
|
if (model) {
|
|
@@ -1513,7 +1536,10 @@ function buildGeminiThinkingConfig(model, reasoningEffort) {
|
|
|
1513
1536
|
}
|
|
1514
1537
|
|
|
1515
1538
|
export function resolveGeminiReasoningConfig(rawModelValue = "", reasoningEffort = "medium") {
|
|
1516
|
-
const executionModel =
|
|
1539
|
+
const executionModel = resolveGeminiHeadlessExecutionModel(rawModelValue, {
|
|
1540
|
+
permissionMode: "read_only",
|
|
1541
|
+
reasoningEffort,
|
|
1542
|
+
});
|
|
1517
1543
|
if (!executionModel) {
|
|
1518
1544
|
return null;
|
|
1519
1545
|
}
|
|
@@ -3256,7 +3282,12 @@ export function runLocalAIClient({
|
|
|
3256
3282
|
const normalizedClient = normalizeLocalAIClientName(client);
|
|
3257
3283
|
const normalizedPermissionMode = normalizeLocalAIPermissionMode(permissionMode);
|
|
3258
3284
|
const normalizedReasoningEffort = normalizeLocalAIReasoningEffort(reasoningEffort);
|
|
3259
|
-
const resolvedExecutionModel =
|
|
3285
|
+
const resolvedExecutionModel = normalizedClient === "gemini"
|
|
3286
|
+
? resolveGeminiHeadlessExecutionModel(model, {
|
|
3287
|
+
permissionMode: normalizedPermissionMode,
|
|
3288
|
+
reasoningEffort: normalizedReasoningEffort,
|
|
3289
|
+
})
|
|
3290
|
+
: resolveLocalAIExecutionModel(normalizedClient, model);
|
|
3260
3291
|
const resolvedWorkspaceDir = ensureWorkspaceDir(workspaceDir);
|
|
3261
3292
|
const promptText = buildLocalBotPrompt(inputPayload);
|
|
3262
3293
|
if (normalizedClient === "sample") {
|
|
@@ -26,11 +26,14 @@ export function classifyExecutionFailureFacts(detail) {
|
|
|
26
26
|
const normalizedDetail = String(detail || "").trim();
|
|
27
27
|
const networkReset = /ECONNRESET|socket hang up|read ECONNRESET/i.test(normalizedDetail);
|
|
28
28
|
const networkTimeout = /ETIMEDOUT|http timeout|ECONNABORTED|aborted/i.test(normalizedDetail);
|
|
29
|
-
const
|
|
29
|
+
const providerCapacityExhausted = /MODEL_CAPACITY_EXHAUSTED|RESOURCE_EXHAUSTED|No capacity available for model|rateLimitExceeded/i.test(normalizedDetail);
|
|
30
|
+
const retryable = networkReset || networkTimeout || providerCapacityExhausted;
|
|
30
31
|
const base = {
|
|
31
32
|
stage: "execution",
|
|
32
33
|
operation: "runner_execution",
|
|
33
|
-
errorType:
|
|
34
|
+
errorType: providerCapacityExhausted
|
|
35
|
+
? "provider_capacity_exhausted"
|
|
36
|
+
: retryable
|
|
34
37
|
? (networkTimeout ? "network_timeout" : "network_reset")
|
|
35
38
|
: "execution_failed",
|
|
36
39
|
retryable,
|
|
@@ -42,6 +45,15 @@ export function classifyExecutionFailureFacts(detail) {
|
|
|
42
45
|
if (!normalizedDetail) {
|
|
43
46
|
return base;
|
|
44
47
|
}
|
|
48
|
+
if (providerCapacityExhausted) {
|
|
49
|
+
return {
|
|
50
|
+
...base,
|
|
51
|
+
stage: "provider_call",
|
|
52
|
+
operation: "local_ai_model_request",
|
|
53
|
+
errorType: "provider_capacity_exhausted",
|
|
54
|
+
retryable: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
45
57
|
if (/permission_mode=read_only|read[_ -]?only/i.test(normalizedDetail)) {
|
|
46
58
|
return {
|
|
47
59
|
...base,
|
|
@@ -88,6 +88,7 @@ export function buildRunnerProcessedLifecycleInput({
|
|
|
88
88
|
const processed = safeObject(processedRaw);
|
|
89
89
|
const result = safeObject(processed.result);
|
|
90
90
|
const normalizedOutcome = normalizeRunnerProcessedLifecycleOutcome(processed);
|
|
91
|
+
const normalizedFailureFacts = safeObject(result.failure_facts);
|
|
91
92
|
return {
|
|
92
93
|
requestKey,
|
|
93
94
|
selectedRecord,
|
|
@@ -95,6 +96,8 @@ export function buildRunnerProcessedLifecycleInput({
|
|
|
95
96
|
outcome: normalizedOutcome,
|
|
96
97
|
closedReason: normalizedOutcome === "skipped"
|
|
97
98
|
? String(processed.skippedRecord?.reason || result.detail || "skipped").trim() || "skipped"
|
|
99
|
+
: ["error", "execution_failed", "policy_violation"].includes(normalizedOutcome)
|
|
100
|
+
? String(result.detail || "execution_error").trim() || "execution_error"
|
|
98
101
|
: "",
|
|
99
102
|
conversationIDRaw: String(result.conversation_id || "").trim(),
|
|
100
103
|
conversationParticipants: ensureArray(result.conversation_participants),
|
|
@@ -126,6 +129,8 @@ export function buildRunnerProcessedLifecycleInput({
|
|
|
126
129
|
assignmentValidationStatus: String(result.assignment_validation_status || "").trim(),
|
|
127
130
|
assignmentValidationReason: String(result.assignment_validation_reason || "").trim(),
|
|
128
131
|
assignmentValidationModes: ensureArray(result.assignment_validation_modes),
|
|
132
|
+
failureReplyClassification: String(result.failure_reply_classification || "").trim(),
|
|
133
|
+
failureFacts: normalizedFailureFacts,
|
|
129
134
|
deliveryStatus: String(result.delivery_status || "").trim(),
|
|
130
135
|
archiveStatus: String(result.archive_status || "").trim(),
|
|
131
136
|
transportError: String(result.transport_error || "").trim(),
|
|
@@ -361,6 +361,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
361
361
|
const cliPath = String(requireDependency(deps, "cliPath") || "").trim();
|
|
362
362
|
const parseSimpleEnvText = requireDependency(deps, "parseSimpleEnvText");
|
|
363
363
|
const resolveLocalAIExecutionModel = requireDependency(deps, "resolveLocalAIExecutionModel");
|
|
364
|
+
const resolveGeminiHeadlessExecutionModel = requireDependency(deps, "resolveGeminiHeadlessExecutionModel");
|
|
364
365
|
const suggestLocalAIModelDisplayName = requireDependency(deps, "suggestLocalAIModelDisplayName");
|
|
365
366
|
const resolveGeminiReasoningConfig = requireDependency(deps, "resolveGeminiReasoningConfig");
|
|
366
367
|
const stripLocalOnlyToolArgs = requireDependency(deps, "stripLocalOnlyToolArgs");
|
|
@@ -392,6 +393,18 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
392
393
|
].join(" "),
|
|
393
394
|
);
|
|
394
395
|
|
|
396
|
+
push(
|
|
397
|
+
"gemini_headless_runner_uses_explicit_stable_execution_model",
|
|
398
|
+
resolveGeminiHeadlessExecutionModel("gemini-3.1-pro", {
|
|
399
|
+
permissionMode: "read_only",
|
|
400
|
+
reasoningEffort: "low",
|
|
401
|
+
}) === "gemini-3-flash-preview",
|
|
402
|
+
`gemini_headless=${resolveGeminiHeadlessExecutionModel("gemini-3.1-pro", {
|
|
403
|
+
permissionMode: "read_only",
|
|
404
|
+
reasoningEffort: "low",
|
|
405
|
+
})}`,
|
|
406
|
+
);
|
|
407
|
+
|
|
395
408
|
push(
|
|
396
409
|
"blank_model_defaults_to_first_display_model_for_each_client",
|
|
397
410
|
suggestLocalAIModelDisplayName("gpt", "") === "gpt-5.4"
|
|
@@ -409,7 +422,7 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
409
422
|
const geminiHighReasoning = resolveGeminiReasoningConfig("gemini-3.1-pro", "high");
|
|
410
423
|
push(
|
|
411
424
|
"gemini_reasoning_effort_maps_to_runtime_settings_override",
|
|
412
|
-
String(geminiLowReasoning?.model || "") === "
|
|
425
|
+
String(geminiLowReasoning?.model || "") === "gemini-3-flash-preview"
|
|
413
426
|
&& String(safeObject(geminiLowReasoning?.thinkingConfig).thinkingLevel || "") === "LOW"
|
|
414
427
|
&& String(safeObject(geminiMediumReasoning?.thinkingConfig).thinkingLevel || "") === "THINKING_LEVEL_UNSPECIFIED"
|
|
415
428
|
&& String(safeObject(geminiHighReasoning?.thinkingConfig).thinkingLevel || "") === "HIGH",
|
|
@@ -3245,6 +3245,73 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
3245
3245
|
`status=${String(failedRequest?.status || "(none)")} reason=${String(failedRequest?.closed_reason || "(none)")} closed_at=${String(failedRequest?.closed_at || "(none)")}`,
|
|
3246
3246
|
);
|
|
3247
3247
|
|
|
3248
|
+
saveBotRunnerState({
|
|
3249
|
+
routes: {
|
|
3250
|
+
[requestRouteKey]: {},
|
|
3251
|
+
},
|
|
3252
|
+
sharedInboxes: {},
|
|
3253
|
+
excludedComments: {},
|
|
3254
|
+
requests: {
|
|
3255
|
+
"request-key-2f": {
|
|
3256
|
+
request_key: "request-key-2f",
|
|
3257
|
+
project_id: selftestProjectID,
|
|
3258
|
+
provider: "telegram",
|
|
3259
|
+
chat_id: "-100123",
|
|
3260
|
+
source_message_id: 751,
|
|
3261
|
+
conversation_id: "conv-request-2f",
|
|
3262
|
+
execution_contract_type: "delegation",
|
|
3263
|
+
execution_contract_targets: ["ryoai3_bot"],
|
|
3264
|
+
next_expected_responders: ["ryoai3_bot"],
|
|
3265
|
+
authoritative_decision_bundle: {
|
|
3266
|
+
schema_version: "runner_conversation_decision.v1",
|
|
3267
|
+
decision_type: "reply_outcome",
|
|
3268
|
+
conversation_intent_mode: "delegated_single_lead",
|
|
3269
|
+
allowed_responders: ["ryoai_bot", "ryoai2_bot", "ryoai3_bot"],
|
|
3270
|
+
initial_responders: ["ryoai_bot"],
|
|
3271
|
+
selected_bot_usernames: ["ryoai2_bot"],
|
|
3272
|
+
allow_bot_to_bot: true,
|
|
3273
|
+
execution_contract_type: "delegation",
|
|
3274
|
+
execution_contract_targets: ["ryoai3_bot"],
|
|
3275
|
+
next_expected_responders: ["ryoai3_bot"],
|
|
3276
|
+
should_close_after_reply: false,
|
|
3277
|
+
},
|
|
3278
|
+
decision_bundle_validation_status: "valid",
|
|
3279
|
+
status: "running",
|
|
3280
|
+
claimed_by_route: requestRouteKey,
|
|
3281
|
+
},
|
|
3282
|
+
},
|
|
3283
|
+
consumedComments: {},
|
|
3284
|
+
});
|
|
3285
|
+
const retryableFailedDelegation = markRunnerRequestLifecycle({
|
|
3286
|
+
normalizedRoute: requestRoute,
|
|
3287
|
+
requestKey: "request-key-2f",
|
|
3288
|
+
selectedRecord: {
|
|
3289
|
+
id: "comment-request-finish-2f",
|
|
3290
|
+
parsedArchive: {
|
|
3291
|
+
kind: "bot_reply",
|
|
3292
|
+
chatID: "-100123",
|
|
3293
|
+
messageID: 752,
|
|
3294
|
+
conversationID: "conv-request-2f",
|
|
3295
|
+
},
|
|
3296
|
+
},
|
|
3297
|
+
routeKey: requestRouteKey,
|
|
3298
|
+
outcome: "error",
|
|
3299
|
+
closedReason: "Gemini CLI timed out after 90s while waiting for a model response (No capacity available for model gemini-3.1-pro-preview on the server)",
|
|
3300
|
+
currentBotSelector: "@RyoAI2_bot",
|
|
3301
|
+
failureReplyClassification: "retryable_failure",
|
|
3302
|
+
failureFacts: {
|
|
3303
|
+
retryable: true,
|
|
3304
|
+
error_type: "provider_capacity_exhausted",
|
|
3305
|
+
},
|
|
3306
|
+
});
|
|
3307
|
+
push(
|
|
3308
|
+
"runner_request_lifecycle_retryable_delegated_error_stays_running",
|
|
3309
|
+
String(retryableFailedDelegation?.status || "") === "running"
|
|
3310
|
+
&& ensureArray(retryableFailedDelegation?.next_expected_responders).includes("ryoai3_bot")
|
|
3311
|
+
&& String(retryableFailedDelegation?.closed_reason || "").trim() === "",
|
|
3312
|
+
`status=${String(retryableFailedDelegation?.status || "(none)")} next=${ensureArray(retryableFailedDelegation?.next_expected_responders).join(",")} closed_reason=${String(retryableFailedDelegation?.closed_reason || "(none)")}`,
|
|
3313
|
+
);
|
|
3314
|
+
|
|
3248
3315
|
saveBotRunnerState({
|
|
3249
3316
|
routes: {
|
|
3250
3317
|
[requestRouteKey]: {},
|