metheus-governance-mcp-cli 0.2.210 → 0.2.212
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 +82 -2
- package/lib/runner-orchestration.mjs +22 -2
- package/lib/runner-trigger.mjs +18 -1
- package/lib/selftest-runner-scenarios.mjs +58 -17
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -2764,6 +2764,62 @@ function sessionAllowsConversationResponder(sessionRaw, responderSelectorRaw = "
|
|
|
2764
2764
|
return allowedResponders.includes(responderSelector);
|
|
2765
2765
|
}
|
|
2766
2766
|
|
|
2767
|
+
function shouldBypassRunnerStartupLoopForContractFollowup({
|
|
2768
|
+
selectedRecord,
|
|
2769
|
+
bot,
|
|
2770
|
+
conversationSessionFacts = null,
|
|
2771
|
+
}) {
|
|
2772
|
+
const parsed = safeObject(selectedRecord?.parsedArchive);
|
|
2773
|
+
if (String(parsed.kind || "").trim().toLowerCase() !== "bot_reply") {
|
|
2774
|
+
return false;
|
|
2775
|
+
}
|
|
2776
|
+
const currentBotSelector = normalizeTelegramMentionUsername(bot?.username || bot?.name);
|
|
2777
|
+
if (!currentBotSelector) {
|
|
2778
|
+
return false;
|
|
2779
|
+
}
|
|
2780
|
+
const conversationID = String(parsed.conversationID || "").trim();
|
|
2781
|
+
if (!conversationID) {
|
|
2782
|
+
return false;
|
|
2783
|
+
}
|
|
2784
|
+
const executionContractType = String(parsed.executionContractType || "").trim().toLowerCase();
|
|
2785
|
+
if (executionContractType !== "delegation") {
|
|
2786
|
+
return false;
|
|
2787
|
+
}
|
|
2788
|
+
const senderBotSelector = normalizeTelegramMentionUsername(
|
|
2789
|
+
parsed.botUsername
|
|
2790
|
+
|| parsed.botName
|
|
2791
|
+
|| parsed.username
|
|
2792
|
+
|| parsed.sender,
|
|
2793
|
+
);
|
|
2794
|
+
if (!senderBotSelector || senderBotSelector === currentBotSelector) {
|
|
2795
|
+
return false;
|
|
2796
|
+
}
|
|
2797
|
+
const assignmentTargets = ensureArray(parsed.executionContractAssignments)
|
|
2798
|
+
.map((item) => normalizeTelegramMentionUsername(safeObject(item).targetBot || safeObject(item).target_bot))
|
|
2799
|
+
.filter(Boolean);
|
|
2800
|
+
const nextResponders = ensureArray(parsed.executionContractNextResponders)
|
|
2801
|
+
.map((item) => normalizeTelegramMentionUsername(item))
|
|
2802
|
+
.filter(Boolean);
|
|
2803
|
+
const conversationTargetBot = normalizeTelegramMentionUsername(parsed.conversationTargetBotUsername);
|
|
2804
|
+
const currentBotIsExpectedResponder = assignmentTargets.includes(currentBotSelector)
|
|
2805
|
+
|| nextResponders.includes(currentBotSelector)
|
|
2806
|
+
|| conversationTargetBot === currentBotSelector;
|
|
2807
|
+
if (!currentBotIsExpectedResponder) {
|
|
2808
|
+
return false;
|
|
2809
|
+
}
|
|
2810
|
+
const sessionFacts = safeObject(conversationSessionFacts);
|
|
2811
|
+
const sessionExpectedResponders = ensureArray(sessionFacts.next_expected_responders)
|
|
2812
|
+
.map((item) => normalizeTelegramMentionUsername(item))
|
|
2813
|
+
.filter(Boolean);
|
|
2814
|
+
if (sessionExpectedResponders.length > 0 && !sessionExpectedResponders.includes(currentBotSelector)) {
|
|
2815
|
+
return false;
|
|
2816
|
+
}
|
|
2817
|
+
if (sessionFacts.any_closed === true && sessionFacts.any_open !== true) {
|
|
2818
|
+
return false;
|
|
2819
|
+
}
|
|
2820
|
+
return true;
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2767
2823
|
function findRunnerRequestsForMessageID(state, normalizedRoute, selectors = {}) {
|
|
2768
2824
|
const chatID = String(selectors.chatID || "").trim();
|
|
2769
2825
|
const messageID = intFromRawAllowZero(selectors.messageID, 0);
|
|
@@ -3591,13 +3647,29 @@ function runnerRequestRequiresActionableContract(requestRaw) {
|
|
|
3591
3647
|
const request = safeObject(requestRaw);
|
|
3592
3648
|
const replyExpectation = String(request.conversation_reply_expectation || "").trim().toLowerCase();
|
|
3593
3649
|
const executionContractType = String(request.execution_contract_type || "").trim().toLowerCase();
|
|
3650
|
+
const intentMode = String(request.conversation_intent_mode || "").trim().toLowerCase();
|
|
3651
|
+
const intentType = String(
|
|
3652
|
+
request.conversation_intent_type
|
|
3653
|
+
|| request.intent_type
|
|
3654
|
+
|| request.normalized_intent
|
|
3655
|
+
|| "",
|
|
3656
|
+
).trim().toLowerCase();
|
|
3657
|
+
const hasExecutionIntent = [
|
|
3658
|
+
"general_execution",
|
|
3659
|
+
"ctxpack_mutation",
|
|
3660
|
+
"workitem_mutation",
|
|
3661
|
+
].includes(intentType);
|
|
3594
3662
|
if (request.execution_contract_actionable === true) {
|
|
3595
3663
|
return true;
|
|
3596
3664
|
}
|
|
3597
|
-
if (
|
|
3665
|
+
if (["delegation", "direct_result", "summary_request", "final_summary"].includes(executionContractType)) {
|
|
3598
3666
|
return true;
|
|
3599
3667
|
}
|
|
3600
|
-
if (
|
|
3668
|
+
if (
|
|
3669
|
+
intentMode === "single_bot"
|
|
3670
|
+
&& replyExpectation === "actionable"
|
|
3671
|
+
&& hasExecutionIntent
|
|
3672
|
+
) {
|
|
3601
3673
|
return true;
|
|
3602
3674
|
}
|
|
3603
3675
|
return false;
|
|
@@ -7691,6 +7763,13 @@ async function maybeHandleRunnerStartupLoopCandidate({
|
|
|
7691
7763
|
}
|
|
7692
7764
|
const conversationID = String(parsed.conversationID || "").trim();
|
|
7693
7765
|
const conversationSessionFacts = collectBotRunnerConversationSessionFacts(normalizedRoute, conversationID);
|
|
7766
|
+
if (shouldBypassRunnerStartupLoopForContractFollowup({
|
|
7767
|
+
selectedRecord,
|
|
7768
|
+
bot,
|
|
7769
|
+
conversationSessionFacts,
|
|
7770
|
+
})) {
|
|
7771
|
+
return null;
|
|
7772
|
+
}
|
|
7694
7773
|
const adjudication = await resolveRunnerStartupLoopAdjudication({
|
|
7695
7774
|
selectedRecord,
|
|
7696
7775
|
pendingOrdered,
|
|
@@ -15472,6 +15551,7 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
15472
15551
|
selectRunnerPendingWork,
|
|
15473
15552
|
processRunnerSelectedRecord,
|
|
15474
15553
|
resolveRunnerStartupLoopAdjudication,
|
|
15554
|
+
shouldBypassRunnerStartupLoopForContractFollowup,
|
|
15475
15555
|
claimRunnerRequestForHumanComment,
|
|
15476
15556
|
markRunnerRequestLifecycle,
|
|
15477
15557
|
resolveRunnerContinuationRequestForBotReply,
|
|
@@ -1294,7 +1294,6 @@ export async function resolveHumanIntentContext({
|
|
|
1294
1294
|
executionPlan,
|
|
1295
1295
|
contractGuardrail: {
|
|
1296
1296
|
require_complete_contract: true,
|
|
1297
|
-
require_explicit_actionable_intent: true,
|
|
1298
1297
|
reason: "Return a complete human intent contract for this managed-bot conversation.",
|
|
1299
1298
|
},
|
|
1300
1299
|
});
|
|
@@ -2584,6 +2583,11 @@ async function maybeExecuteDynamicRolePlan({
|
|
|
2584
2583
|
safeObject(directHumanResponseContract).intentType
|
|
2585
2584
|
|| safeObject(safeObject(humanIntentContext).humanIntent).intentType,
|
|
2586
2585
|
);
|
|
2586
|
+
const humanIntentMode = normalizeIntentMode(
|
|
2587
|
+
safeObject(directHumanResponseContract).intentMode
|
|
2588
|
+
|| safeObject(safeObject(humanIntentContext).humanIntent).intentMode,
|
|
2589
|
+
);
|
|
2590
|
+
const actionableConversationRequiresContract = safeObject(directHumanResponseContract).requiresActionableContract === true;
|
|
2587
2591
|
const plannerContextComments = ensureArray(contextWindow).length
|
|
2588
2592
|
? ensureArray(contextWindow)
|
|
2589
2593
|
: buildRunnerContextWindow(
|
|
@@ -2595,6 +2599,13 @@ async function maybeExecuteDynamicRolePlan({
|
|
|
2595
2599
|
if (!assignmentTasks.length && isInformationalHumanIntentType(humanIntentType)) {
|
|
2596
2600
|
return null;
|
|
2597
2601
|
}
|
|
2602
|
+
if (
|
|
2603
|
+
!assignmentTasks.length
|
|
2604
|
+
&& actionableConversationRequiresContract
|
|
2605
|
+
&& ["delegated_single_lead", "multi_bot_collab", "multi_bot_direct"].includes(humanIntentMode)
|
|
2606
|
+
) {
|
|
2607
|
+
return null;
|
|
2608
|
+
}
|
|
2598
2609
|
const executionIntentRequested = [
|
|
2599
2610
|
"general_execution",
|
|
2600
2611
|
"ctxpack_mutation",
|
|
@@ -5193,6 +5204,14 @@ export async function processRunnerSelectedRecord({
|
|
|
5193
5204
|
}
|
|
5194
5205
|
}
|
|
5195
5206
|
const normalizedExecutionContractType = String(executionContract?.type || "").trim().toLowerCase();
|
|
5207
|
+
const effectiveResolvedIntentType = normalizeHumanIntentType(
|
|
5208
|
+
directHumanResponseContract.intentType || resolvedIntentType,
|
|
5209
|
+
);
|
|
5210
|
+
const effectiveResolvedIntentMode = normalizeIntentMode(
|
|
5211
|
+
directHumanResponseContract.intentMode
|
|
5212
|
+
|| conversationContext?.intentMode
|
|
5213
|
+
|| safeObject(safeObject(humanIntentContext).humanIntent).intentMode,
|
|
5214
|
+
);
|
|
5196
5215
|
const shouldEnforceArtifactValidation = Boolean(
|
|
5197
5216
|
(artifactValidationOverride && Object.keys(artifactValidationOverride).length > 0)
|
|
5198
5217
|
|| ensureArray(aiResult?.artifacts).length > 0
|
|
@@ -5202,7 +5221,8 @@ export async function processRunnerSelectedRecord({
|
|
|
5202
5221
|
"general_execution",
|
|
5203
5222
|
"ctxpack_mutation",
|
|
5204
5223
|
"workitem_mutation",
|
|
5205
|
-
].includes(
|
|
5224
|
+
].includes(effectiveResolvedIntentType)
|
|
5225
|
+
&& !["delegated_single_lead", "multi_bot_collab", "multi_bot_direct"].includes(effectiveResolvedIntentMode)
|
|
5206
5226
|
);
|
|
5207
5227
|
const artifactValidation = shouldEnforceArtifactValidation
|
|
5208
5228
|
? artifactValidationOverride && Object.keys(artifactValidationOverride).length > 0
|
package/lib/runner-trigger.mjs
CHANGED
|
@@ -96,12 +96,29 @@ function buildRunnerTaskName(humanIntentType, humanIntentContract = null) {
|
|
|
96
96
|
const contract = safeObject(humanIntentContract);
|
|
97
97
|
const replyExpectation = String(contract.replyExpectation || contract.reply_expectation || "").trim().toLowerCase();
|
|
98
98
|
const executionContractType = String(contract.executionContractType || contract.execution_contract_type || "").trim().toLowerCase();
|
|
99
|
+
const intentMode = String(contract.intentMode || contract.intent_mode || "").trim().toLowerCase();
|
|
100
|
+
const executionIntentRequested = [
|
|
101
|
+
"general_execution",
|
|
102
|
+
"ctxpack_mutation",
|
|
103
|
+
"workitem_mutation",
|
|
104
|
+
].includes(normalizedIntentType);
|
|
105
|
+
const collaborativeIntentMode = [
|
|
106
|
+
"delegated_single_lead",
|
|
107
|
+
"multi_bot_collab",
|
|
108
|
+
"multi_bot_direct",
|
|
109
|
+
].includes(intentMode);
|
|
99
110
|
if (normalizedIntentType === "status_query") return "answer_project_status_query";
|
|
100
111
|
if (normalizedIntentType === "workspace_query") return "answer_project_workspace_query";
|
|
101
112
|
if (normalizedIntentType === "bot_role_query") return "answer_project_bot_role_query";
|
|
102
113
|
if (normalizedIntentType === "artifact_location_query") return "answer_project_artifact_location_query";
|
|
103
114
|
if (normalizedIntentType === "small_talk") return "reply_to_project_chat_greeting";
|
|
104
|
-
if (executionContractType
|
|
115
|
+
if (executionContractType) {
|
|
116
|
+
return "reply_to_project_actionable_message";
|
|
117
|
+
}
|
|
118
|
+
if (collaborativeIntentMode && replyExpectation === "actionable") {
|
|
119
|
+
return "reply_to_project_chat_message";
|
|
120
|
+
}
|
|
121
|
+
if (executionIntentRequested) {
|
|
105
122
|
return "reply_to_project_actionable_message";
|
|
106
123
|
}
|
|
107
124
|
return "reply_to_project_chat_message";
|
|
@@ -118,16 +118,17 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
118
118
|
const safeObject = requireDependency(deps, "safeObject");
|
|
119
119
|
const normalizeRunnerTriggerPolicy = requireDependency(deps, "normalizeRunnerTriggerPolicy");
|
|
120
120
|
const evaluateTelegramRunnerTrigger = requireDependency(deps, "evaluateTelegramRunnerTrigger");
|
|
121
|
-
const resolveRunnerResponderAdjudication = requireDependency(deps, "resolveRunnerResponderAdjudication");
|
|
122
|
-
const selectPendingArchiveComments = requireDependency(deps, "selectPendingArchiveComments");
|
|
123
|
-
const selectRunnerPendingWork = requireDependency(deps, "selectRunnerPendingWork");
|
|
124
|
-
const processRunnerSelectedRecord = requireDependency(deps, "processRunnerSelectedRecord");
|
|
125
|
-
const resolveRunnerStartupLoopAdjudication = requireDependency(deps, "resolveRunnerStartupLoopAdjudication");
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
const
|
|
130
|
-
const
|
|
121
|
+
const resolveRunnerResponderAdjudication = requireDependency(deps, "resolveRunnerResponderAdjudication");
|
|
122
|
+
const selectPendingArchiveComments = requireDependency(deps, "selectPendingArchiveComments");
|
|
123
|
+
const selectRunnerPendingWork = requireDependency(deps, "selectRunnerPendingWork");
|
|
124
|
+
const processRunnerSelectedRecord = requireDependency(deps, "processRunnerSelectedRecord");
|
|
125
|
+
const resolveRunnerStartupLoopAdjudication = requireDependency(deps, "resolveRunnerStartupLoopAdjudication");
|
|
126
|
+
const shouldBypassRunnerStartupLoopForContractFollowup = requireDependency(deps, "shouldBypassRunnerStartupLoopForContractFollowup");
|
|
127
|
+
const runRunnerAIExecution = requireDependency(deps, "runRunnerAIExecution");
|
|
128
|
+
const formatBotReplyArchiveComment = requireDependency(deps, "formatBotReplyArchiveComment");
|
|
129
|
+
const findArchivedBotReplyRecord = requireDependency(deps, "findArchivedBotReplyRecord");
|
|
130
|
+
const parseArchivedChatComment = requireDependency(deps, "parseArchivedChatComment");
|
|
131
|
+
const validateWorkspaceArtifacts = requireDependency(deps, "validateWorkspaceArtifacts");
|
|
131
132
|
const buildLocalBotPrompt = requireDependency(deps, "buildLocalBotPrompt");
|
|
132
133
|
|
|
133
134
|
try {
|
|
@@ -367,13 +368,53 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
367
368
|
&& adjudication?.startup_facts?.repeated_same_delegation_without_new_human === true,
|
|
368
369
|
`decision=${String(adjudication?.decision || "")} action=${String(adjudication?.action || "")} imported=${String(adjudication?.startup_facts?.imported_on_current_poll)} repeated_delegation=${String(adjudication?.startup_facts?.repeated_same_delegation_without_new_human)}`,
|
|
369
370
|
);
|
|
370
|
-
} catch (err) {
|
|
371
|
-
push(
|
|
372
|
-
"runner_loop_adjudication_detects_repeated_same_delegation_without_new_human_input",
|
|
373
|
-
false,
|
|
374
|
-
String(err?.message || err),
|
|
375
|
-
);
|
|
376
|
-
}
|
|
371
|
+
} catch (err) {
|
|
372
|
+
push(
|
|
373
|
+
"runner_loop_adjudication_detects_repeated_same_delegation_without_new_human_input",
|
|
374
|
+
false,
|
|
375
|
+
String(err?.message || err),
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
try {
|
|
380
|
+
const shouldBypass = shouldBypassRunnerStartupLoopForContractFollowup({
|
|
381
|
+
selectedRecord: {
|
|
382
|
+
id: "bot-reply-4",
|
|
383
|
+
parsedArchive: {
|
|
384
|
+
kind: "bot_reply",
|
|
385
|
+
messageID: 52,
|
|
386
|
+
senderIsBot: true,
|
|
387
|
+
botUsername: "@bot-a",
|
|
388
|
+
conversationID: "conv-4",
|
|
389
|
+
executionContractType: "delegation",
|
|
390
|
+
executionContractAssignments: [
|
|
391
|
+
{ targetBot: "@bot-b", task: "say hello" },
|
|
392
|
+
],
|
|
393
|
+
executionContractNextResponders: ["@bot-b"],
|
|
394
|
+
conversationTargetBotUsername: "@bot-b",
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
bot: {
|
|
398
|
+
username: "@bot-b",
|
|
399
|
+
},
|
|
400
|
+
conversationSessionFacts: {
|
|
401
|
+
any_open: true,
|
|
402
|
+
any_closed: false,
|
|
403
|
+
next_expected_responders: ["bot-b"],
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
push(
|
|
407
|
+
"runner_startup_loop_bypasses_expected_delegation_followup_for_target_bot",
|
|
408
|
+
shouldBypass === true,
|
|
409
|
+
`should_bypass=${String(shouldBypass)}`,
|
|
410
|
+
);
|
|
411
|
+
} catch (err) {
|
|
412
|
+
push(
|
|
413
|
+
"runner_startup_loop_bypasses_expected_delegation_followup_for_target_bot",
|
|
414
|
+
false,
|
|
415
|
+
String(err?.message || err),
|
|
416
|
+
);
|
|
417
|
+
}
|
|
377
418
|
|
|
378
419
|
try {
|
|
379
420
|
const pendingSelection = selectPendingArchiveComments(
|