metheus-governance-mcp-cli 0.2.208 → 0.2.210
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 +161 -47
- package/lib/local-ai-adapters.mjs +25 -0
- package/lib/runner-orchestration.mjs +319 -161
- package/lib/runner-trigger.mjs +8 -2
- package/lib/selftest-runner-scenarios.mjs +12442 -12282
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -2634,7 +2634,8 @@ function resolveRunnerRequestClaimIntent({
|
|
|
2634
2634
|
if (explicitIntent) {
|
|
2635
2635
|
return explicitIntent;
|
|
2636
2636
|
}
|
|
2637
|
-
|
|
2637
|
+
const inferredIntent = inferRunnerRequestClaimIntent(selectedRecord);
|
|
2638
|
+
return inferredIntent === "status_query" ? inferredIntent : "";
|
|
2638
2639
|
}
|
|
2639
2640
|
|
|
2640
2641
|
function buildSyntheticReplyChainConversationID(normalizedRoute, chatID, anchorMessageID) {
|
|
@@ -3339,8 +3340,6 @@ async function claimRunnerRequestForHumanComment({
|
|
|
3339
3340
|
).trim();
|
|
3340
3341
|
const preferredNormalizedIntent = String(
|
|
3341
3342
|
normalizedSharedHumanIntent.intentType
|
|
3342
|
-
|| sharedConversationSource.normalized_intent
|
|
3343
|
-
|| referencedRequest.normalized_intent
|
|
3344
3343
|
|| resolvedNormalizedIntent
|
|
3345
3344
|
|| "",
|
|
3346
3345
|
).trim().toLowerCase();
|
|
@@ -3381,50 +3380,70 @@ async function claimRunnerRequestForHumanComment({
|
|
|
3381
3380
|
conversation_id: resolvedConversationID,
|
|
3382
3381
|
selected_bot_usernames: uniqueOrderedStrings(selectedBotUsernames, normalizeTelegramMentionUsername),
|
|
3383
3382
|
conversation_intent_mode: String(
|
|
3384
|
-
|
|
3383
|
+
normalizedSharedHumanIntent.intentMode
|
|
3384
|
+
|| existing.conversation_intent_mode
|
|
3385
|
+
|| sharedConversationSource.conversation_intent_mode
|
|
3386
|
+
|| referencedRequest.conversation_intent_mode
|
|
3387
|
+
|| "",
|
|
3385
3388
|
).trim().toLowerCase(),
|
|
3386
3389
|
conversation_lead_bot: normalizeTelegramMentionUsername(
|
|
3387
|
-
|
|
3390
|
+
normalizedSharedHumanIntent.leadBotSelector
|
|
3391
|
+
|| existing.conversation_lead_bot
|
|
3392
|
+
|| sharedConversationSource.conversation_lead_bot
|
|
3393
|
+
|| referencedRequest.conversation_lead_bot,
|
|
3388
3394
|
),
|
|
3389
3395
|
conversation_summary_bot: normalizeTelegramMentionUsername(
|
|
3390
|
-
|
|
3396
|
+
normalizedSharedHumanIntent.summaryBotSelector
|
|
3397
|
+
|| existing.conversation_summary_bot
|
|
3398
|
+
|| sharedConversationSource.conversation_summary_bot
|
|
3399
|
+
|| referencedRequest.conversation_summary_bot,
|
|
3391
3400
|
),
|
|
3392
3401
|
conversation_participants: uniqueOrderedStrings(
|
|
3393
|
-
ensureArray(
|
|
3394
|
-
?
|
|
3395
|
-
: ensureArray(
|
|
3396
|
-
?
|
|
3397
|
-
: ensureArray(
|
|
3398
|
-
?
|
|
3399
|
-
:
|
|
3402
|
+
ensureArray(normalizedSharedHumanIntent.participantSelectors).length
|
|
3403
|
+
? normalizedSharedHumanIntent.participantSelectors
|
|
3404
|
+
: ensureArray(existing.conversation_participants).length
|
|
3405
|
+
? existing.conversation_participants
|
|
3406
|
+
: ensureArray(sharedConversationSource.conversation_participants).length
|
|
3407
|
+
? sharedConversationSource.conversation_participants
|
|
3408
|
+
: ensureArray(referencedRequest.conversation_participants).length
|
|
3409
|
+
? referencedRequest.conversation_participants
|
|
3410
|
+
: [],
|
|
3400
3411
|
normalizeTelegramMentionUsername,
|
|
3401
3412
|
),
|
|
3402
3413
|
conversation_initial_responders: uniqueOrderedStrings(
|
|
3403
|
-
ensureArray(
|
|
3404
|
-
?
|
|
3405
|
-
: ensureArray(
|
|
3406
|
-
?
|
|
3407
|
-
: ensureArray(
|
|
3408
|
-
?
|
|
3409
|
-
:
|
|
3414
|
+
ensureArray(normalizedSharedHumanIntent.initialResponderSelectors).length
|
|
3415
|
+
? normalizedSharedHumanIntent.initialResponderSelectors
|
|
3416
|
+
: ensureArray(existing.conversation_initial_responders).length
|
|
3417
|
+
? existing.conversation_initial_responders
|
|
3418
|
+
: ensureArray(sharedConversationSource.conversation_initial_responders).length
|
|
3419
|
+
? sharedConversationSource.conversation_initial_responders
|
|
3420
|
+
: ensureArray(referencedRequest.conversation_initial_responders).length
|
|
3421
|
+
? referencedRequest.conversation_initial_responders
|
|
3422
|
+
: [],
|
|
3410
3423
|
normalizeTelegramMentionUsername,
|
|
3411
3424
|
),
|
|
3412
3425
|
conversation_allowed_responders: uniqueOrderedStrings(
|
|
3413
|
-
ensureArray(
|
|
3414
|
-
?
|
|
3415
|
-
: ensureArray(
|
|
3416
|
-
?
|
|
3417
|
-
: ensureArray(
|
|
3418
|
-
?
|
|
3419
|
-
:
|
|
3426
|
+
ensureArray(normalizedSharedHumanIntent.allowedResponderSelectors).length
|
|
3427
|
+
? normalizedSharedHumanIntent.allowedResponderSelectors
|
|
3428
|
+
: ensureArray(existing.conversation_allowed_responders).length
|
|
3429
|
+
? existing.conversation_allowed_responders
|
|
3430
|
+
: ensureArray(sharedConversationSource.conversation_allowed_responders).length
|
|
3431
|
+
? sharedConversationSource.conversation_allowed_responders
|
|
3432
|
+
: ensureArray(referencedRequest.conversation_allowed_responders).length
|
|
3433
|
+
? referencedRequest.conversation_allowed_responders
|
|
3434
|
+
: [],
|
|
3420
3435
|
normalizeTelegramMentionUsername,
|
|
3421
3436
|
),
|
|
3422
|
-
conversation_allow_bot_to_bot:
|
|
3437
|
+
conversation_allow_bot_to_bot: normalizedSharedHumanIntent.allowBotToBot === true
|
|
3438
|
+
|| existing.conversation_allow_bot_to_bot === true
|
|
3423
3439
|
|| sharedConversationSource.conversation_allow_bot_to_bot === true
|
|
3424
|
-
|| referencedRequest.conversation_allow_bot_to_bot === true
|
|
3425
|
-
|| normalizedSharedHumanIntent.allowBotToBot === true,
|
|
3440
|
+
|| referencedRequest.conversation_allow_bot_to_bot === true,
|
|
3426
3441
|
conversation_reply_expectation: String(
|
|
3427
|
-
|
|
3442
|
+
normalizedSharedHumanIntent.replyExpectation
|
|
3443
|
+
|| existing.conversation_reply_expectation
|
|
3444
|
+
|| sharedConversationSource.conversation_reply_expectation
|
|
3445
|
+
|| referencedRequest.conversation_reply_expectation
|
|
3446
|
+
|| "",
|
|
3428
3447
|
).trim().toLowerCase(),
|
|
3429
3448
|
execution_contract_type: String(
|
|
3430
3449
|
existing.execution_contract_type || sharedConversationSource.execution_contract_type || referencedRequest.execution_contract_type || "",
|
|
@@ -3450,7 +3469,7 @@ async function claimRunnerRequestForHumanComment({
|
|
|
3450
3469
|
: [],
|
|
3451
3470
|
normalizeTelegramMentionUsername,
|
|
3452
3471
|
),
|
|
3453
|
-
normalized_intent: preferredNormalizedIntent,
|
|
3472
|
+
normalized_intent: String(preferredNormalizedIntent || existing.normalized_intent || "").trim().toLowerCase(),
|
|
3454
3473
|
status: "claimed",
|
|
3455
3474
|
claimed_by_route: String(routeKey || "").trim(),
|
|
3456
3475
|
claimed_at: firstNonEmptyString([existing.claimed_at, nowISO]) || nowISO,
|
|
@@ -3501,6 +3520,89 @@ function isActionableRunnerRequestIntent(rawIntent) {
|
|
|
3501
3520
|
return Boolean(normalizedIntent) && !isInformationalRunnerRequestIntent(normalizedIntent);
|
|
3502
3521
|
}
|
|
3503
3522
|
|
|
3523
|
+
function runnerRequestHasConversationContract(requestRaw) {
|
|
3524
|
+
const request = safeObject(requestRaw);
|
|
3525
|
+
return Boolean(
|
|
3526
|
+
String(request.conversation_id || "").trim()
|
|
3527
|
+
|| String(request.conversation_intent_mode || "").trim()
|
|
3528
|
+
|| String(request.conversation_reply_expectation || "").trim()
|
|
3529
|
+
|| ensureArray(request.conversation_participants).length
|
|
3530
|
+
|| ensureArray(request.conversation_initial_responders).length
|
|
3531
|
+
|| ensureArray(request.conversation_allowed_responders).length
|
|
3532
|
+
);
|
|
3533
|
+
}
|
|
3534
|
+
|
|
3535
|
+
function runnerRequestHasCompleteConversationContract(requestRaw) {
|
|
3536
|
+
const request = safeObject(requestRaw);
|
|
3537
|
+
const intentMode = String(request.conversation_intent_mode || "").trim().toLowerCase();
|
|
3538
|
+
const conversationID = String(request.conversation_id || "").trim();
|
|
3539
|
+
const replyExpectation = String(request.conversation_reply_expectation || "").trim().toLowerCase();
|
|
3540
|
+
const participants = ensureArray(request.conversation_participants);
|
|
3541
|
+
const initialResponders = ensureArray(request.conversation_initial_responders);
|
|
3542
|
+
const allowedResponders = ensureArray(request.conversation_allowed_responders);
|
|
3543
|
+
if (!runnerRequestHasConversationContract(request)) {
|
|
3544
|
+
return false;
|
|
3545
|
+
}
|
|
3546
|
+
if (!conversationID || !intentMode || !replyExpectation) {
|
|
3547
|
+
return false;
|
|
3548
|
+
}
|
|
3549
|
+
if (intentMode === "single_bot") {
|
|
3550
|
+
return allowedResponders.length > 0 || participants.length > 0;
|
|
3551
|
+
}
|
|
3552
|
+
return participants.length > 0 && initialResponders.length > 0 && allowedResponders.length > 0;
|
|
3553
|
+
}
|
|
3554
|
+
|
|
3555
|
+
function runnerRequestHasExecutionContract(requestRaw) {
|
|
3556
|
+
const request = safeObject(requestRaw);
|
|
3557
|
+
return Boolean(
|
|
3558
|
+
String(request.execution_contract_type || "").trim()
|
|
3559
|
+
|| request.execution_contract_actionable === true
|
|
3560
|
+
|| ensureArray(request.execution_contract_targets).length
|
|
3561
|
+
|| ensureArray(request.next_expected_responders).length
|
|
3562
|
+
);
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
function runnerRequestHasCompleteExecutionContract(requestRaw) {
|
|
3566
|
+
const request = safeObject(requestRaw);
|
|
3567
|
+
const executionContractType = String(request.execution_contract_type || "").trim().toLowerCase();
|
|
3568
|
+
const executionTargets = ensureArray(request.execution_contract_targets);
|
|
3569
|
+
const nextExpectedResponders = ensureArray(request.next_expected_responders);
|
|
3570
|
+
if (!runnerRequestHasExecutionContract(request)) {
|
|
3571
|
+
return false;
|
|
3572
|
+
}
|
|
3573
|
+
if (!executionContractType) {
|
|
3574
|
+
return false;
|
|
3575
|
+
}
|
|
3576
|
+
if (executionContractType === "delegation") {
|
|
3577
|
+
return executionTargets.length > 0 || nextExpectedResponders.length > 0;
|
|
3578
|
+
}
|
|
3579
|
+
if (executionContractType === "summary_request") {
|
|
3580
|
+
return nextExpectedResponders.length > 0 || executionTargets.length > 0;
|
|
3581
|
+
}
|
|
3582
|
+
return true;
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3585
|
+
function runnerRequestHasContractSignals(requestRaw) {
|
|
3586
|
+
const request = safeObject(requestRaw);
|
|
3587
|
+
return runnerRequestHasConversationContract(request) || runnerRequestHasExecutionContract(request);
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3590
|
+
function runnerRequestRequiresActionableContract(requestRaw) {
|
|
3591
|
+
const request = safeObject(requestRaw);
|
|
3592
|
+
const replyExpectation = String(request.conversation_reply_expectation || "").trim().toLowerCase();
|
|
3593
|
+
const executionContractType = String(request.execution_contract_type || "").trim().toLowerCase();
|
|
3594
|
+
if (request.execution_contract_actionable === true) {
|
|
3595
|
+
return true;
|
|
3596
|
+
}
|
|
3597
|
+
if (replyExpectation === "actionable") {
|
|
3598
|
+
return true;
|
|
3599
|
+
}
|
|
3600
|
+
if (["delegation", "direct_result"].includes(executionContractType)) {
|
|
3601
|
+
return true;
|
|
3602
|
+
}
|
|
3603
|
+
return false;
|
|
3604
|
+
}
|
|
3605
|
+
|
|
3504
3606
|
function loadRunnerRequestByKey(requestKey) {
|
|
3505
3607
|
const key = String(requestKey || "").trim();
|
|
3506
3608
|
if (!key) {
|
|
@@ -3512,7 +3614,7 @@ function loadRunnerRequestByKey(requestKey) {
|
|
|
3512
3614
|
function actionableRunnerRequestMissingRootWorkItem(requestRaw) {
|
|
3513
3615
|
const request = safeObject(requestRaw);
|
|
3514
3616
|
return (
|
|
3515
|
-
|
|
3617
|
+
runnerRequestRequiresActionableContract(request)
|
|
3516
3618
|
&& !String(request.root_work_item_id || "").trim()
|
|
3517
3619
|
);
|
|
3518
3620
|
}
|
|
@@ -3824,7 +3926,7 @@ async function ensureRunnerRootWorkItemForRequest({
|
|
|
3824
3926
|
requestKey: key,
|
|
3825
3927
|
};
|
|
3826
3928
|
}
|
|
3827
|
-
if (!
|
|
3929
|
+
if (!runnerRequestRequiresActionableContract(existing)) {
|
|
3828
3930
|
return {
|
|
3829
3931
|
ok: true,
|
|
3830
3932
|
requestKey: key,
|
|
@@ -4216,7 +4318,7 @@ function resolveRunnerContinuationRequestForBotReply({
|
|
|
4216
4318
|
execution_contract_actionable: session.last_execution_contract_actionable === true,
|
|
4217
4319
|
execution_contract_targets: ensureArray(session.last_execution_contract_targets),
|
|
4218
4320
|
next_expected_responders: ensureArray(session.next_expected_responders),
|
|
4219
|
-
normalized_intent: String(
|
|
4321
|
+
normalized_intent: String(fallbackRequest.normalized_intent || "").trim().toLowerCase(),
|
|
4220
4322
|
status: "running",
|
|
4221
4323
|
claimed_by_route: String(sessionMatch.routeKey || "").trim(),
|
|
4222
4324
|
claimed_at: firstNonEmptyString([session.started_at, nowISO]),
|
|
@@ -4333,6 +4435,26 @@ function markRunnerRequestLifecycle({
|
|
|
4333
4435
|
normalizeTelegramMentionUsername,
|
|
4334
4436
|
).filter((selector) => selector && selector !== normalizedCurrentBotSelector);
|
|
4335
4437
|
const shouldRemainRunningAfterReply = continuationSelectors.length > 0;
|
|
4438
|
+
const nextConversationIntentMode = String(
|
|
4439
|
+
conversationIntentMode
|
|
4440
|
+
|| existing.conversation_intent_mode
|
|
4441
|
+
|| "",
|
|
4442
|
+
).trim().toLowerCase();
|
|
4443
|
+
const nextExecutionContractType = String(
|
|
4444
|
+
executionContractType
|
|
4445
|
+
|| existing.execution_contract_type
|
|
4446
|
+
|| "",
|
|
4447
|
+
).trim().toLowerCase();
|
|
4448
|
+
const nextNormalizedIntent = (() => {
|
|
4449
|
+
const explicitIntent = String(normalizedIntent || "").trim().toLowerCase();
|
|
4450
|
+
if (explicitIntent) {
|
|
4451
|
+
return explicitIntent;
|
|
4452
|
+
}
|
|
4453
|
+
if (nextConversationIntentMode && !nextExecutionContractType) {
|
|
4454
|
+
return "";
|
|
4455
|
+
}
|
|
4456
|
+
return String(existing.normalized_intent || "").trim().toLowerCase();
|
|
4457
|
+
})();
|
|
4336
4458
|
const normalizedOutcome = String(outcome || "").trim().toLowerCase();
|
|
4337
4459
|
const nextStatus = (() => {
|
|
4338
4460
|
if (normalizedOutcome === "claimed") return "claimed";
|
|
@@ -4364,11 +4486,7 @@ function markRunnerRequestLifecycle({
|
|
|
4364
4486
|
ensureArray(allowedResponders).length ? allowedResponders : existing.conversation_allowed_responders,
|
|
4365
4487
|
normalizeTelegramMentionUsername,
|
|
4366
4488
|
),
|
|
4367
|
-
conversation_intent_mode:
|
|
4368
|
-
conversationIntentMode
|
|
4369
|
-
|| existing.conversation_intent_mode
|
|
4370
|
-
|| "",
|
|
4371
|
-
).trim().toLowerCase(),
|
|
4489
|
+
conversation_intent_mode: nextConversationIntentMode,
|
|
4372
4490
|
conversation_lead_bot: normalizeTelegramMentionUsername(
|
|
4373
4491
|
conversationLeadBot
|
|
4374
4492
|
|| existing.conversation_lead_bot
|
|
@@ -4386,11 +4504,7 @@ function markRunnerRequestLifecycle({
|
|
|
4386
4504
|
|| existing.conversation_reply_expectation
|
|
4387
4505
|
|| "",
|
|
4388
4506
|
).trim().toLowerCase(),
|
|
4389
|
-
execution_contract_type:
|
|
4390
|
-
executionContractType
|
|
4391
|
-
|| existing.execution_contract_type
|
|
4392
|
-
|| "",
|
|
4393
|
-
).trim().toLowerCase(),
|
|
4507
|
+
execution_contract_type: nextExecutionContractType,
|
|
4394
4508
|
execution_contract_actionable: executionContractActionable === true
|
|
4395
4509
|
|| existing.execution_contract_actionable === true,
|
|
4396
4510
|
execution_contract_targets: uniqueOrderedStrings(
|
|
@@ -4401,7 +4515,7 @@ function markRunnerRequestLifecycle({
|
|
|
4401
4515
|
ensureArray(nextExpectedResponders).length ? nextExpectedResponders : existing.next_expected_responders,
|
|
4402
4516
|
normalizeTelegramMentionUsername,
|
|
4403
4517
|
),
|
|
4404
|
-
normalized_intent:
|
|
4518
|
+
normalized_intent: nextNormalizedIntent,
|
|
4405
4519
|
status: nextStatus,
|
|
4406
4520
|
started_at: firstNonEmptyString([existing.started_at, nowISO]),
|
|
4407
4521
|
completed_at: nextStatus === "completed" ? nowISO : String(existing.completed_at || "").trim(),
|
|
@@ -4842,7 +4956,7 @@ async function syncRunnerRequestLedgerForProjectToServer({ normalizedRoute, runt
|
|
|
4842
4956
|
})[String(request.request_key || "").trim()]
|
|
4843
4957
|
: request;
|
|
4844
4958
|
if (
|
|
4845
|
-
|
|
4959
|
+
runnerRequestRequiresActionableContract(recoveredRequest)
|
|
4846
4960
|
&& !String(recoveredRequest.root_work_item_id || "").trim()
|
|
4847
4961
|
) {
|
|
4848
4962
|
continue;
|
|
@@ -1896,6 +1896,17 @@ export function buildLocalBotPrompt(payload, { terse = true } = {}) {
|
|
|
1896
1896
|
responseContract.require_actionable_contract === true && Array.isArray(responseContract.allowed_contract_types) && responseContract.allowed_contract_types.length > 0
|
|
1897
1897
|
? `Allowed execution contract types for this reply: ${responseContract.allowed_contract_types.join(", ")}.`
|
|
1898
1898
|
: "",
|
|
1899
|
+
"If you mention any other managed bot @username anywhere in the reply, you must include a contract for that mention.",
|
|
1900
|
+
"Do not mention another managed bot unless the contract explicitly names that bot in assignments or next_responders.",
|
|
1901
|
+
"Without a matching contract, mentioned bots will not act.",
|
|
1902
|
+
"When delegating to another managed bot, use contract.type=\"delegation\" with actionable=true, assignments, and next_responders.",
|
|
1903
|
+
"Delegation contract example: {\"type\":\"delegation\",\"actionable\":true,\"assignments\":[{\"target_bot\":\"ryoai2_bot\",\"task\":\"briefly greet in one line\"}],\"next_responders\":[\"ryoai2_bot\"]}.",
|
|
1904
|
+
ensureArray(responseContract.required_delegation_targets).length > 0
|
|
1905
|
+
? `This reply must delegate to these exact managed bots now: ${ensureArray(responseContract.required_delegation_targets).map((item) => `@${String(item || "").trim().replace(/^@+/, "")}`).join(", ")}.`
|
|
1906
|
+
: "",
|
|
1907
|
+
String(responseContract.contract_hint || "").trim()
|
|
1908
|
+
? `Contract requirement hint: ${String(responseContract.contract_hint || "").trim()}`
|
|
1909
|
+
: "",
|
|
1899
1910
|
"",
|
|
1900
1911
|
);
|
|
1901
1912
|
}
|
|
@@ -2042,6 +2053,7 @@ export function buildLocalBotPrompt(payload, { terse = true } = {}) {
|
|
|
2042
2053
|
lines.push(
|
|
2043
2054
|
"As the lead bot, your first public reply must be immediately actionable.",
|
|
2044
2055
|
"If you are delegating, include contract.type=\"delegation\" with concrete assignments for the exact bots you are tasking now.",
|
|
2056
|
+
"If you mention any allowed responder in the reply text, the contract must name that responder in assignments or next_responders.",
|
|
2045
2057
|
"If you are completing the work yourself now, include contract.type=\"direct_result\".",
|
|
2046
2058
|
"Do not say you will come back later, wait, or plan first without producing an actionable contract in this same reply.",
|
|
2047
2059
|
);
|
|
@@ -2085,7 +2097,9 @@ export function serializeLocalAIResult(result) {
|
|
|
2085
2097
|
function buildConversationIntentAnalysisPrompt({
|
|
2086
2098
|
messageText,
|
|
2087
2099
|
managedBots,
|
|
2100
|
+
contractGuardrail = null,
|
|
2088
2101
|
}) {
|
|
2102
|
+
const guardrail = safeObject(contractGuardrail);
|
|
2089
2103
|
const bots = ensureArray(managedBots).map((item) => {
|
|
2090
2104
|
const bot = safeObject(item);
|
|
2091
2105
|
return {
|
|
@@ -2129,6 +2143,15 @@ function buildConversationIntentAnalysisPrompt({
|
|
|
2129
2143
|
"- If the human asks bots to discuss, debate, review, brainstorm, compare opinions, or hold a conversation about a topic, default to reply_expectation=informational unless they explicitly ask for concrete execution/output now.",
|
|
2130
2144
|
"- reply_expectation=actionable when the human is asking the bot(s) to actually do work now, produce concrete results, create/update files, delegate concrete tasks, or otherwise execute immediately.",
|
|
2131
2145
|
"- reply_expectation=informational when the human is only asking for explanation, status, location, clarification, discussion, review, brainstorming, or other non-execution information.",
|
|
2146
|
+
guardrail.require_complete_contract === true
|
|
2147
|
+
? "- Contract guardrail: do not leave intent_type, reply_expectation, participants, initial_responders, or allowed_responders empty when the message clearly addresses managed bots."
|
|
2148
|
+
: "",
|
|
2149
|
+
guardrail.require_explicit_actionable_intent === true
|
|
2150
|
+
? "- Contract guardrail: if reply_expectation=actionable, intent_type must be exactly one of ctxpack_mutation, workitem_mutation, or general_execution."
|
|
2151
|
+
: "",
|
|
2152
|
+
String(guardrail.reason || "").trim()
|
|
2153
|
+
? `- Contract guardrail reason: ${String(guardrail.reason || "").trim()}`
|
|
2154
|
+
: "",
|
|
2132
2155
|
"",
|
|
2133
2156
|
`managed_bots=${JSON.stringify(bots)}`,
|
|
2134
2157
|
`human_message=${JSON.stringify(String(messageText || "").trim())}`,
|
|
@@ -2471,6 +2494,7 @@ export function analyzeHumanConversationIntentWithAI({
|
|
|
2471
2494
|
messageText,
|
|
2472
2495
|
managedBots,
|
|
2473
2496
|
workspaceDir,
|
|
2497
|
+
contractGuardrail = null,
|
|
2474
2498
|
client = "",
|
|
2475
2499
|
model = "",
|
|
2476
2500
|
env = process.env,
|
|
@@ -2498,6 +2522,7 @@ export function analyzeHumanConversationIntentWithAI({
|
|
|
2498
2522
|
promptText: buildConversationIntentAnalysisPrompt({
|
|
2499
2523
|
messageText,
|
|
2500
2524
|
managedBots: bots,
|
|
2525
|
+
contractGuardrail,
|
|
2501
2526
|
}),
|
|
2502
2527
|
workspaceDir,
|
|
2503
2528
|
model: parserModel,
|