metheus-governance-mcp-cli 0.2.295 → 0.2.296
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.
|
@@ -383,6 +383,19 @@ function buildRunnerRequestFollowupSyntheticRecord(requestRaw, currentBotSelecto
|
|
|
383
383
|
.map((value) => normalizeMentionSelector(value))
|
|
384
384
|
.filter(Boolean),
|
|
385
385
|
));
|
|
386
|
+
const normalizedExecutionContractType = String(
|
|
387
|
+
request.execution_contract_type || request.normalized_execution_contract_type || "",
|
|
388
|
+
).trim().toLowerCase() || "direct_result";
|
|
389
|
+
const normalizedSummaryBotSelector = normalizeMentionSelector(request.conversation_summary_bot);
|
|
390
|
+
const executionContract = {
|
|
391
|
+
type: normalizedExecutionContractType,
|
|
392
|
+
actionable: request.execution_contract_actionable === true,
|
|
393
|
+
assignments: executionTargets.map((targetBot) => ({
|
|
394
|
+
target_bot: targetBot,
|
|
395
|
+
})),
|
|
396
|
+
...(normalizedSummaryBotSelector ? { summary_bot: normalizedSummaryBotSelector } : {}),
|
|
397
|
+
...(nextResponders.length > 0 ? { next_responders: nextResponders } : {}),
|
|
398
|
+
};
|
|
386
399
|
const replyOccurredAtMs = Date.parse(occurredAt);
|
|
387
400
|
const maxPendingAgeMs = intFromRawAllowZero(safeObject(pendingSelectionOptions).maxPendingAgeMs, 0);
|
|
388
401
|
const staleAfterAt = maxPendingAgeMs > 0 && Number.isFinite(replyOccurredAtMs)
|
|
@@ -412,27 +425,33 @@ function buildRunnerRequestFollowupSyntheticRecord(requestRaw, currentBotSelecto
|
|
|
412
425
|
senderIsBot: true,
|
|
413
426
|
username: senderSelector,
|
|
414
427
|
botUsername: senderSelector,
|
|
415
|
-
mentionUsernames:
|
|
428
|
+
mentionUsernames: uniqueOrdered([
|
|
429
|
+
...ensureArray(replyEnvelope.mention_usernames)
|
|
430
|
+
.map((value) => normalizeMentionSelector(value))
|
|
431
|
+
.filter(Boolean),
|
|
432
|
+
...nextResponders,
|
|
433
|
+
]),
|
|
416
434
|
occurredAt,
|
|
417
435
|
body: String(replyEnvelope.body || "").trim(),
|
|
418
436
|
conversationID: String(request.conversation_id || "").trim(),
|
|
419
|
-
conversationMode:
|
|
437
|
+
conversationMode: "public_multi_bot",
|
|
420
438
|
conversationStage: "bot_reply",
|
|
439
|
+
conversationIntentMode: String(request.conversation_intent_mode || "").trim(),
|
|
421
440
|
conversationAllowBotToBot: request.conversation_allow_bot_to_bot === true,
|
|
422
441
|
conversationLeadBotUsername: normalizeMentionSelector(request.conversation_lead_bot),
|
|
423
|
-
conversationSummaryBotUsername:
|
|
442
|
+
conversationSummaryBotUsername: normalizedSummaryBotSelector,
|
|
424
443
|
conversationTargetBotUsername: nextResponders.length === 1 ? nextResponders[0] : "",
|
|
425
444
|
conversationParticipants: participants,
|
|
426
445
|
conversationInitialResponders: initialResponders,
|
|
427
446
|
conversationAllowedResponders: allowedResponders,
|
|
428
447
|
conversationReplyExpectation: String(request.conversation_reply_expectation || "").trim().toLowerCase(),
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
).trim().toLowerCase(),
|
|
448
|
+
executionContract,
|
|
449
|
+
executionContractType: normalizedExecutionContractType,
|
|
432
450
|
executionContractActionable: request.execution_contract_actionable === true,
|
|
433
451
|
executionContractAssignments: executionTargets.map((targetBot) => ({
|
|
434
452
|
targetBot,
|
|
435
453
|
})),
|
|
454
|
+
executionContractSummaryBot: normalizedSummaryBotSelector,
|
|
436
455
|
executionContractNextResponders: nextResponders,
|
|
437
456
|
sourceOrigin: "request_followup_replay",
|
|
438
457
|
sourceRouteKey: String(request.claimed_by_route || "").trim(),
|
|
@@ -22236,7 +22236,10 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
22236
22236
|
&& ensureArray(safeObject(pendingWork.pending).pending).length === 1
|
|
22237
22237
|
&& String(safeObject(ensureArray(pendingWork.requestFollowupPending)[0]).id || "").startsWith("request-followup:request-followup-1:498:ryoai_bot")
|
|
22238
22238
|
&& safeObject(safeObject(ensureArray(pendingWork.requestFollowupPending)[0]).parsedArchive).kind === "bot_reply"
|
|
22239
|
-
&&
|
|
22239
|
+
&& String(safeObject(safeObject(ensureArray(pendingWork.requestFollowupPending)[0]).parsedArchive).conversationMode || "") === "public_multi_bot"
|
|
22240
|
+
&& String(safeObject(safeObject(ensureArray(pendingWork.requestFollowupPending)[0]).parsedArchive).conversationIntentMode || "") === "multi_bot_direct"
|
|
22241
|
+
&& ensureArray(safeObject(safeObject(ensureArray(pendingWork.requestFollowupPending)[0]).parsedArchive).executionContractNextResponders).includes("ryoai_bot")
|
|
22242
|
+
&& ensureArray(safeObject(safeObject(safeObject(ensureArray(pendingWork.requestFollowupPending)[0]).parsedArchive).executionContract).next_responders).includes("ryoai_bot"),
|
|
22240
22243
|
`replay=${ensureArray(pendingWork.requestFollowupPending).map((item) => String(safeObject(item).id || "")).join(",") || "(none)"} pending=${ensureArray(safeObject(pendingWork.pending).pending).map((item) => String(safeObject(item).id || "")).join(",") || "(none)"}`,
|
|
22241
22244
|
);
|
|
22242
22245
|
} catch (err) {
|
|
@@ -22310,6 +22313,174 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
22310
22313
|
push("runner_entrypoint_does_not_replay_request_followup_after_route_cursor", false, String(err?.message || err));
|
|
22311
22314
|
}
|
|
22312
22315
|
|
|
22316
|
+
try {
|
|
22317
|
+
const pendingWork = selectRunnerPendingWorkEntrypoint({
|
|
22318
|
+
comments: [],
|
|
22319
|
+
importOutcome: {
|
|
22320
|
+
importedCommentIDs: [],
|
|
22321
|
+
importedComments: [],
|
|
22322
|
+
currentPollLocalInboundReceipts: [],
|
|
22323
|
+
},
|
|
22324
|
+
refreshedState: {
|
|
22325
|
+
last_processed_comment_id: "comment-before-followup-3",
|
|
22326
|
+
last_processed_created_at: "2026-04-06T00:12:00.000Z",
|
|
22327
|
+
},
|
|
22328
|
+
mode: "continue",
|
|
22329
|
+
parseArchivedChatComment,
|
|
22330
|
+
deps: {
|
|
22331
|
+
normalizeArchiveCommentRecord: (record) => ({
|
|
22332
|
+
id: String(record?.id || "").trim(),
|
|
22333
|
+
body: String(record?.body || "").trim(),
|
|
22334
|
+
createdAt: String(record?.created_at || record?.createdAt || record?.updated_at || record?.updatedAt || "").trim(),
|
|
22335
|
+
updatedAt: String(record?.updated_at || record?.updatedAt || "").trim(),
|
|
22336
|
+
parsedArchive: safeObject(record?.parsedArchive),
|
|
22337
|
+
}),
|
|
22338
|
+
applyPendingAgeSelection: (selection) => selection,
|
|
22339
|
+
},
|
|
22340
|
+
pendingSelectionOptions: {},
|
|
22341
|
+
followupRequests: [
|
|
22342
|
+
{
|
|
22343
|
+
request_key: "request-followup-3",
|
|
22344
|
+
status: "running",
|
|
22345
|
+
project_id: selftestProjectID,
|
|
22346
|
+
provider: "telegram",
|
|
22347
|
+
chat_id: "-100126",
|
|
22348
|
+
conversation_id: "conversation-followup-3",
|
|
22349
|
+
conversation_intent_mode: "multi_bot_direct",
|
|
22350
|
+
conversation_allow_bot_to_bot: true,
|
|
22351
|
+
conversation_participants: ["ryoai2_bot", "ryoai3_bot"],
|
|
22352
|
+
conversation_initial_responders: ["ryoai2_bot", "ryoai3_bot"],
|
|
22353
|
+
conversation_allowed_responders: ["ryoai2_bot", "ryoai3_bot"],
|
|
22354
|
+
execution_contract_type: "direct_result",
|
|
22355
|
+
execution_contract_actionable: true,
|
|
22356
|
+
execution_contract_targets: ["ryoai2_bot", "ryoai3_bot"],
|
|
22357
|
+
next_expected_responders: ["ryoai3_bot"],
|
|
22358
|
+
updated_at: "2026-04-06T00:12:00.000Z",
|
|
22359
|
+
last_reply_message_envelope: {
|
|
22360
|
+
chat_id: "-100126",
|
|
22361
|
+
message_id: 515,
|
|
22362
|
+
reply_to_message_id: 514,
|
|
22363
|
+
body: "안녕하세요, RyoAI2_bot입니다.",
|
|
22364
|
+
sender: "@RyoAI2_bot",
|
|
22365
|
+
sender_username: "ryoai2_bot",
|
|
22366
|
+
sender_is_bot: true,
|
|
22367
|
+
occurred_at: "2026-04-06T00:12:00.000Z",
|
|
22368
|
+
canonical_human_message_key: "shared-human-key-515",
|
|
22369
|
+
},
|
|
22370
|
+
},
|
|
22371
|
+
],
|
|
22372
|
+
currentBotSelector: "ryoai3_bot",
|
|
22373
|
+
});
|
|
22374
|
+
let aiCalls = 0;
|
|
22375
|
+
const deliveredConversation = [];
|
|
22376
|
+
const processed = await processRunnerSelectedRecord({
|
|
22377
|
+
routeKey: "runner-followup-public-multi-bot-peer-key",
|
|
22378
|
+
normalizedRoute: normalizeRunnerRoute({
|
|
22379
|
+
name: "telegram-monitor-runner-followup-public-multi-bot-peer",
|
|
22380
|
+
project_id: selftestProjectID,
|
|
22381
|
+
provider: "telegram",
|
|
22382
|
+
role: "monitor",
|
|
22383
|
+
role_profile: "monitor",
|
|
22384
|
+
destination_id: "dest-1",
|
|
22385
|
+
destination_label: "Main Room",
|
|
22386
|
+
server_bot_name: "RyoAI3_bot",
|
|
22387
|
+
server_bot_id: "bot-peer-2",
|
|
22388
|
+
trigger_policy: {
|
|
22389
|
+
mentions_only: true,
|
|
22390
|
+
direct_messages: true,
|
|
22391
|
+
reply_to_bot_messages: true,
|
|
22392
|
+
},
|
|
22393
|
+
archive_policy: {
|
|
22394
|
+
mirror_replies: true,
|
|
22395
|
+
dedupe_inbound: true,
|
|
22396
|
+
dedupe_outbound: true,
|
|
22397
|
+
skip_bot_messages: true,
|
|
22398
|
+
},
|
|
22399
|
+
dry_run_delivery: true,
|
|
22400
|
+
}),
|
|
22401
|
+
selectedRecord: ensureArray(pendingWork.requestFollowupPending)[0],
|
|
22402
|
+
pendingOrdered: ensureArray(pendingWork.pending?.pending),
|
|
22403
|
+
bot: {
|
|
22404
|
+
id: "bot-peer-2",
|
|
22405
|
+
name: "RyoAI3_bot",
|
|
22406
|
+
username: "RyoAI3_bot",
|
|
22407
|
+
role: "monitor",
|
|
22408
|
+
provider: "telegram",
|
|
22409
|
+
},
|
|
22410
|
+
destination: {
|
|
22411
|
+
id: "dest-1",
|
|
22412
|
+
label: "Main Room",
|
|
22413
|
+
provider: "telegram",
|
|
22414
|
+
chatID: "-100126",
|
|
22415
|
+
},
|
|
22416
|
+
archiveThread: {
|
|
22417
|
+
threadID: "thread-1",
|
|
22418
|
+
workItemID: "work-item-1",
|
|
22419
|
+
},
|
|
22420
|
+
executionPlan: {
|
|
22421
|
+
mode: "role_profile",
|
|
22422
|
+
roleProfileName: "monitor",
|
|
22423
|
+
roleProfile: {
|
|
22424
|
+
client: "sample",
|
|
22425
|
+
model: "",
|
|
22426
|
+
permissionMode: "read_only",
|
|
22427
|
+
reasoningEffort: "low",
|
|
22428
|
+
},
|
|
22429
|
+
workspaceDir: path.join(os.tmpdir(), "metheus-runner-selftest-followup-public-multi-bot-peer"),
|
|
22430
|
+
workspaceSource: "selftest",
|
|
22431
|
+
usedCommandFallback: false,
|
|
22432
|
+
},
|
|
22433
|
+
runtime: {
|
|
22434
|
+
baseURL: "https://example.test",
|
|
22435
|
+
token: "selftest-token",
|
|
22436
|
+
timeoutSeconds: 30,
|
|
22437
|
+
actor: { user_id: "user-1" },
|
|
22438
|
+
},
|
|
22439
|
+
deps: {
|
|
22440
|
+
saveRunnerRouteState: () => {},
|
|
22441
|
+
startRunnerTypingHeartbeat: () => ({ async stop() {} }),
|
|
22442
|
+
runRunnerAIExecution: async () => {
|
|
22443
|
+
aiCalls += 1;
|
|
22444
|
+
return {
|
|
22445
|
+
skip: false,
|
|
22446
|
+
reply: "안녕하세요, RyoAI3_bot입니다.",
|
|
22447
|
+
};
|
|
22448
|
+
},
|
|
22449
|
+
performLocalBotDelivery: async ({ archiveConversation, archiveConversationContext, archiveExecutionContract }) => {
|
|
22450
|
+
deliveredConversation.push(buildSelftestArchiveConversation({
|
|
22451
|
+
archiveConversation,
|
|
22452
|
+
archiveConversationContext,
|
|
22453
|
+
archiveExecutionContract,
|
|
22454
|
+
}));
|
|
22455
|
+
return {
|
|
22456
|
+
delivery: { dryRun: true, body: {} },
|
|
22457
|
+
archive: {},
|
|
22458
|
+
};
|
|
22459
|
+
},
|
|
22460
|
+
serializeRunnerTriggerPolicy: (value) => value,
|
|
22461
|
+
serializeRunnerArchivePolicy: (value) => value,
|
|
22462
|
+
buildRunnerExecutionDeps: () => ({}),
|
|
22463
|
+
buildRunnerDeliveryDeps: () => ({}),
|
|
22464
|
+
buildRunnerRuntimeDeps: () => ({}),
|
|
22465
|
+
resolveConversationPeerBots: () => [
|
|
22466
|
+
{ id: "bot-peer-1", name: "RyoAI2_bot" },
|
|
22467
|
+
{ id: "bot-peer-2", name: "RyoAI3_bot" },
|
|
22468
|
+
],
|
|
22469
|
+
},
|
|
22470
|
+
});
|
|
22471
|
+
push(
|
|
22472
|
+
"runner_request_followup_public_multi_bot_continuation_is_authorized",
|
|
22473
|
+
processed.kind === "replied"
|
|
22474
|
+
&& aiCalls === 1
|
|
22475
|
+
&& String(deliveredConversation[0]?.mode || "") === "public_multi_bot"
|
|
22476
|
+
&& String(deliveredConversation[0]?.intentMode || "") === "multi_bot_direct"
|
|
22477
|
+
&& ensureArray(deliveredConversation[0]?.allowedResponderSelectors).includes("ryoai3_bot"),
|
|
22478
|
+
`kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} mode=${String(deliveredConversation[0]?.mode || "(none)")} intent=${String(deliveredConversation[0]?.intentMode || "(none)")} reason=${String(processed.skippedRecord?.reason || "(none)")}`,
|
|
22479
|
+
);
|
|
22480
|
+
} catch (err) {
|
|
22481
|
+
push("runner_request_followup_public_multi_bot_continuation_is_authorized", false, String(err?.message || err));
|
|
22482
|
+
}
|
|
22483
|
+
|
|
22313
22484
|
try {
|
|
22314
22485
|
const deliveryContext = await prepareLocalBotDeliveryContext({
|
|
22315
22486
|
siteBaseURL: "https://example.test",
|