metheus-governance-mcp-cli 0.2.266 → 0.2.267
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.
|
@@ -9,6 +9,73 @@ function ensureArray(value) {
|
|
|
9
9
|
return Array.isArray(value) ? value : [];
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
function normalizeConversationHeuristicText(text) {
|
|
13
|
+
return String(text || "")
|
|
14
|
+
.trim()
|
|
15
|
+
.toLowerCase()
|
|
16
|
+
.replace(/\s+/g, " ");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isImplicitSingleBotConversationContribution(taskText = "") {
|
|
20
|
+
const normalizedText = normalizeConversationHeuristicText(taskText);
|
|
21
|
+
if (!normalizedText) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const workspaceArtifactPatterns = [
|
|
25
|
+
/\bfile\b/,
|
|
26
|
+
/\bfiles\b/,
|
|
27
|
+
/\bcode\b/,
|
|
28
|
+
/\bpatch\b/,
|
|
29
|
+
/\bcommit\b/,
|
|
30
|
+
/\bworkspace\b/,
|
|
31
|
+
/\brepo\b/,
|
|
32
|
+
/\brepository\b/,
|
|
33
|
+
/\bctxpack\b/,
|
|
34
|
+
/\bwork ?item\b/,
|
|
35
|
+
/\bevidence\b/,
|
|
36
|
+
/\bartifact\b/,
|
|
37
|
+
/\bimplement\b/,
|
|
38
|
+
/\bimplementation\b/,
|
|
39
|
+
/\bfix\b/,
|
|
40
|
+
/\bupdate\b/,
|
|
41
|
+
/\bedit\b/,
|
|
42
|
+
/\bcreate\b.*\b(document|doc|guide|plan|readme)\b/,
|
|
43
|
+
/\bwrite\b.*\b(document|doc|guide|plan|readme)\b/,
|
|
44
|
+
/\uD30C\uC77C/,
|
|
45
|
+
/\uCF54\uB4DC/,
|
|
46
|
+
/\uBB38\uC11C/,
|
|
47
|
+
/\uAD6C\uD604/,
|
|
48
|
+
/\uC218\uC815/,
|
|
49
|
+
/\uC791\uC131/,
|
|
50
|
+
/\uC544\uD2F0\uD329\uD2B8/,
|
|
51
|
+
/\uC99D\uAC70/,
|
|
52
|
+
/\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4/,
|
|
53
|
+
/\uCEE4\uBC0B/,
|
|
54
|
+
];
|
|
55
|
+
if (workspaceArtifactPatterns.some((pattern) => pattern.test(normalizedText))) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const conversationalPatterns = [
|
|
59
|
+
/\bgreet\b/,
|
|
60
|
+
/\bhello\b/,
|
|
61
|
+
/\bhi\b/,
|
|
62
|
+
/\bsay hello\b/,
|
|
63
|
+
/\bintroduce yourself\b/,
|
|
64
|
+
/\banswer briefly\b/,
|
|
65
|
+
/\breply briefly\b/,
|
|
66
|
+
/\bin this room\b/,
|
|
67
|
+
/\bone line\b/,
|
|
68
|
+
/\uC778\uC0AC/,
|
|
69
|
+
/\uC548\uB155/,
|
|
70
|
+
/\uD558\uC774/,
|
|
71
|
+
/\uC18C\uAC1C/,
|
|
72
|
+
/\uD55C ?\uC904/,
|
|
73
|
+
/\uC9E7\uAC8C/,
|
|
74
|
+
/\uB2F5\uD574/,
|
|
75
|
+
];
|
|
76
|
+
return conversationalPatterns.some((pattern) => pattern.test(normalizedText));
|
|
77
|
+
}
|
|
78
|
+
|
|
12
79
|
export function resolveInformationalQueryExecutionPlan(executionPlan, directInformationalReply, route) {
|
|
13
80
|
const basePlan = safeObject(executionPlan);
|
|
14
81
|
const override = safeObject(safeObject(directInformationalReply).execution_override);
|
|
@@ -151,6 +218,27 @@ export function summarizeCurrentAssignmentExecutionValidation(
|
|
|
151
218
|
)
|
|
152
219
|
&& Boolean(implicitExecutionTask);
|
|
153
220
|
if (!assignments.length) {
|
|
221
|
+
if (shouldUseImplicitSingleBotExecution && isImplicitSingleBotConversationContribution(implicitExecutionTask)) {
|
|
222
|
+
const implicitConversationAssignment = {
|
|
223
|
+
targetBot: currentSelector,
|
|
224
|
+
task: implicitExecutionTask,
|
|
225
|
+
mode: "conversation_contribution",
|
|
226
|
+
artifactsRequired: false,
|
|
227
|
+
workspaceAction: false,
|
|
228
|
+
requiresExecution: false,
|
|
229
|
+
};
|
|
230
|
+
return {
|
|
231
|
+
status: "conversation_assignment",
|
|
232
|
+
reason: "single-bot public conversational contribution does not require planner/worker execution",
|
|
233
|
+
assignmentModes: ["conversation_contribution"],
|
|
234
|
+
assignments: [implicitConversationAssignment],
|
|
235
|
+
executionAssignments: [],
|
|
236
|
+
conversationAssignments: [implicitConversationAssignment],
|
|
237
|
+
executionTasks: [],
|
|
238
|
+
allTasks: [implicitExecutionTask],
|
|
239
|
+
requiresPlanner: false,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
154
242
|
if (shouldUseImplicitSingleBotExecution) {
|
|
155
243
|
const implicitAssignment = {
|
|
156
244
|
targetBot: currentSelector,
|
|
@@ -6044,15 +6044,159 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
6044
6044
|
&& deliveredText === "I will inspect the project first and come back later.",
|
|
6045
6045
|
`kind=${String(processed.kind || "(none)")} outcome=${String(processed.result?.outcome || "(none)")} ai_calls=${aiCalls} delivery_calls=${deliveryCalls} delivered=${deliveredText} reason=${String(processed.result?.detail || "(none)")}`,
|
|
6046
6046
|
);
|
|
6047
|
-
} catch (err) {
|
|
6048
|
-
push("single_bot_human_work_request_requires_actionable_contract", false, String(err?.message || err));
|
|
6049
|
-
}
|
|
6050
|
-
|
|
6051
|
-
try {
|
|
6052
|
-
let aiCalls = 0;
|
|
6053
|
-
let
|
|
6054
|
-
let
|
|
6055
|
-
let
|
|
6047
|
+
} catch (err) {
|
|
6048
|
+
push("single_bot_human_work_request_requires_actionable_contract", false, String(err?.message || err));
|
|
6049
|
+
}
|
|
6050
|
+
|
|
6051
|
+
try {
|
|
6052
|
+
let aiCalls = 0;
|
|
6053
|
+
let plannerCalls = 0;
|
|
6054
|
+
let deliveryCalls = 0;
|
|
6055
|
+
let deliveredText = "";
|
|
6056
|
+
const processed = await processRunnerSelectedRecord({
|
|
6057
|
+
routeKey: "single-bot-conversation-greeting-request-key",
|
|
6058
|
+
normalizedRoute: normalizeRunnerRoute({
|
|
6059
|
+
name: "telegram-monitor-single-bot-conversation-greeting",
|
|
6060
|
+
project_id: selftestProjectID,
|
|
6061
|
+
provider: "telegram",
|
|
6062
|
+
role: "monitor",
|
|
6063
|
+
role_profile: "monitor",
|
|
6064
|
+
destination_id: "dest-1",
|
|
6065
|
+
destination_label: "Main Room",
|
|
6066
|
+
server_bot_name: "RyoAI_bot",
|
|
6067
|
+
server_bot_id: "bot-lead-1",
|
|
6068
|
+
trigger_policy: {
|
|
6069
|
+
mentions_only: true,
|
|
6070
|
+
direct_messages: true,
|
|
6071
|
+
reply_to_bot_messages: true,
|
|
6072
|
+
},
|
|
6073
|
+
archive_policy: {
|
|
6074
|
+
mirror_replies: true,
|
|
6075
|
+
dedupe_inbound: true,
|
|
6076
|
+
dedupe_outbound: true,
|
|
6077
|
+
skip_bot_messages: true,
|
|
6078
|
+
},
|
|
6079
|
+
dry_run_delivery: true,
|
|
6080
|
+
}),
|
|
6081
|
+
selectedRecord: {
|
|
6082
|
+
id: "comment-single-bot-conversation-greeting-request",
|
|
6083
|
+
createdAt: "2026-03-31T08:37:56.000Z",
|
|
6084
|
+
parsedArchive: {
|
|
6085
|
+
kind: "telegram_message",
|
|
6086
|
+
chatID: "-100123",
|
|
6087
|
+
chatType: "supergroup",
|
|
6088
|
+
senderIsBot: false,
|
|
6089
|
+
body: "@RyoAI_bot 당신이 @SangHoon01_bot 에게 인사해보세요.",
|
|
6090
|
+
mentionUsernames: ["RyoAI_bot", "SangHoon01_bot"],
|
|
6091
|
+
messageID: 1057,
|
|
6092
|
+
},
|
|
6093
|
+
},
|
|
6094
|
+
pendingOrdered: [],
|
|
6095
|
+
bot: {
|
|
6096
|
+
id: "bot-lead-1",
|
|
6097
|
+
name: "RyoAI_bot",
|
|
6098
|
+
username: "RyoAI_bot",
|
|
6099
|
+
role: "monitor",
|
|
6100
|
+
provider: "telegram",
|
|
6101
|
+
},
|
|
6102
|
+
destination: {
|
|
6103
|
+
id: "dest-1",
|
|
6104
|
+
label: "Main Room",
|
|
6105
|
+
provider: "telegram",
|
|
6106
|
+
chatID: "-100123",
|
|
6107
|
+
},
|
|
6108
|
+
archiveThread: {
|
|
6109
|
+
threadID: "thread-1",
|
|
6110
|
+
workItemID: "work-item-1",
|
|
6111
|
+
},
|
|
6112
|
+
executionPlan: {
|
|
6113
|
+
mode: "role_profile",
|
|
6114
|
+
roleProfileName: "monitor",
|
|
6115
|
+
roleProfile: {
|
|
6116
|
+
client: "sample",
|
|
6117
|
+
model: "",
|
|
6118
|
+
permissionMode: "read_only",
|
|
6119
|
+
reasoningEffort: "low",
|
|
6120
|
+
},
|
|
6121
|
+
workspaceDir: path.join(os.tmpdir(), "metheus-runner-selftest-single-bot-conversation-greeting"),
|
|
6122
|
+
workspaceSource: "selftest",
|
|
6123
|
+
usedCommandFallback: false,
|
|
6124
|
+
},
|
|
6125
|
+
runtime: {
|
|
6126
|
+
baseURL: "https://example.test",
|
|
6127
|
+
token: "selftest-token",
|
|
6128
|
+
timeoutSeconds: 30,
|
|
6129
|
+
actor: { user_id: "user-1" },
|
|
6130
|
+
},
|
|
6131
|
+
deps: {
|
|
6132
|
+
saveRunnerRouteState: () => {},
|
|
6133
|
+
startRunnerTypingHeartbeat: () => ({ async stop() {} }),
|
|
6134
|
+
runRunnerAIExecution: async () => {
|
|
6135
|
+
aiCalls += 1;
|
|
6136
|
+
return {
|
|
6137
|
+
skip: false,
|
|
6138
|
+
reply: "@SangHoon01_bot 안녕하세요.",
|
|
6139
|
+
replyToMessageID: 0,
|
|
6140
|
+
};
|
|
6141
|
+
},
|
|
6142
|
+
performLocalBotDelivery: async ({ text }) => {
|
|
6143
|
+
deliveryCalls += 1;
|
|
6144
|
+
deliveredText = String(text || "").trim();
|
|
6145
|
+
return {
|
|
6146
|
+
delivery: { dryRun: true, body: {} },
|
|
6147
|
+
archive: {},
|
|
6148
|
+
};
|
|
6149
|
+
},
|
|
6150
|
+
serializeRunnerTriggerPolicy: (value) => value,
|
|
6151
|
+
serializeRunnerArchivePolicy: (value) => value,
|
|
6152
|
+
buildRunnerExecutionDeps: () => ({
|
|
6153
|
+
analyzeHumanConversationIntentWithAI: async () => ({
|
|
6154
|
+
mode: "single_bot",
|
|
6155
|
+
lead_bot: "ryoai_bot",
|
|
6156
|
+
participants: ["ryoai_bot"],
|
|
6157
|
+
initial_responders: ["ryoai_bot"],
|
|
6158
|
+
allowed_responders: ["ryoai_bot"],
|
|
6159
|
+
summary_bot: "",
|
|
6160
|
+
allow_bot_to_bot: false,
|
|
6161
|
+
reply_expectation: "actionable",
|
|
6162
|
+
intent_type: "general_execution",
|
|
6163
|
+
}),
|
|
6164
|
+
planRoleExecutionWithAI: async () => {
|
|
6165
|
+
plannerCalls += 1;
|
|
6166
|
+
return {
|
|
6167
|
+
requiresExecution: true,
|
|
6168
|
+
summaryRole: "worker",
|
|
6169
|
+
steps: [{ role: "worker", goal: "unexpected", artifactsRequired: true }],
|
|
6170
|
+
};
|
|
6171
|
+
},
|
|
6172
|
+
}),
|
|
6173
|
+
buildRunnerDeliveryDeps: () => ({}),
|
|
6174
|
+
buildRunnerRuntimeDeps: () => ({}),
|
|
6175
|
+
resolveConversationPeerBots: () => [
|
|
6176
|
+
{ id: "bot-lead-1", name: "RyoAI_bot" },
|
|
6177
|
+
],
|
|
6178
|
+
},
|
|
6179
|
+
});
|
|
6180
|
+
push(
|
|
6181
|
+
"single_bot_conversational_greeting_request_skips_planner_and_worker",
|
|
6182
|
+
processed.kind === "replied"
|
|
6183
|
+
&& aiCalls === 1
|
|
6184
|
+
&& plannerCalls === 0
|
|
6185
|
+
&& deliveryCalls === 1
|
|
6186
|
+
&& String(processed.result?.assignment_validation_status || "") === "conversation_assignment"
|
|
6187
|
+
&& ensureArray(processed.result?.assignment_validation_modes).includes("conversation_contribution")
|
|
6188
|
+
&& deliveredText === "@SangHoon01_bot 안녕하세요.",
|
|
6189
|
+
`kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} planner_calls=${plannerCalls} delivery_calls=${deliveryCalls} assignment_status=${String(processed.result?.assignment_validation_status || "(none)")} modes=${JSON.stringify(processed.result?.assignment_validation_modes || [])} delivered=${String(deliveredText || "(none)")}`,
|
|
6190
|
+
);
|
|
6191
|
+
} catch (err) {
|
|
6192
|
+
push("single_bot_conversational_greeting_request_skips_planner_and_worker", false, String(err?.message || err));
|
|
6193
|
+
}
|
|
6194
|
+
|
|
6195
|
+
try {
|
|
6196
|
+
let aiCalls = 0;
|
|
6197
|
+
let deliveryCalls = 0;
|
|
6198
|
+
let deliveredText = "";
|
|
6199
|
+
let capturedFailureFacts = null;
|
|
6056
6200
|
const workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), "metheus-runner-selftest-ai-failure-explainer-"));
|
|
6057
6201
|
const processed = await processRunnerSelectedRecord({
|
|
6058
6202
|
routeKey: "single-bot-human-work-request-ai-failure-explainer-key",
|