metheus-governance-mcp-cli 0.2.202 → 0.2.204
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 +303 -24
- package/lib/local-ai-adapters.mjs +9 -5
- package/lib/runner-data.mjs +22 -0
- package/lib/runner-orchestration.mjs +213 -85
- package/lib/selftest-runner-scenarios.mjs +597 -9
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -2167,6 +2167,33 @@ function normalizeBotRunnerRequests(rawRequests, nowMs = Date.now()) {
|
|
|
2167
2167
|
conversation_allowed_responders: ensureArray(entry.conversation_allowed_responders || entry.conversationAllowedResponders)
|
|
2168
2168
|
.map((value) => normalizeTelegramMentionUsername(value))
|
|
2169
2169
|
.filter(Boolean),
|
|
2170
|
+
conversation_intent_mode: String(entry.conversation_intent_mode || entry.conversationIntentMode || "").trim().toLowerCase(),
|
|
2171
|
+
conversation_lead_bot: normalizeTelegramMentionUsername(entry.conversation_lead_bot || entry.conversationLeadBot),
|
|
2172
|
+
conversation_summary_bot: normalizeTelegramMentionUsername(entry.conversation_summary_bot || entry.conversationSummaryBot),
|
|
2173
|
+
conversation_participants: ensureArray(entry.conversation_participants || entry.conversationParticipants)
|
|
2174
|
+
.map((value) => normalizeTelegramMentionUsername(value))
|
|
2175
|
+
.filter(Boolean),
|
|
2176
|
+
conversation_initial_responders: ensureArray(entry.conversation_initial_responders || entry.conversationInitialResponders)
|
|
2177
|
+
.map((value) => normalizeTelegramMentionUsername(value))
|
|
2178
|
+
.filter(Boolean),
|
|
2179
|
+
conversation_allow_bot_to_bot: boolFromRaw(
|
|
2180
|
+
entry.conversation_allow_bot_to_bot ?? entry.conversationAllowBotToBot,
|
|
2181
|
+
false,
|
|
2182
|
+
),
|
|
2183
|
+
conversation_reply_expectation: String(
|
|
2184
|
+
entry.conversation_reply_expectation || entry.conversationReplyExpectation || "",
|
|
2185
|
+
).trim().toLowerCase(),
|
|
2186
|
+
execution_contract_type: String(entry.execution_contract_type || entry.executionContractType || "").trim().toLowerCase(),
|
|
2187
|
+
execution_contract_actionable: boolFromRaw(
|
|
2188
|
+
entry.execution_contract_actionable ?? entry.executionContractActionable,
|
|
2189
|
+
false,
|
|
2190
|
+
),
|
|
2191
|
+
execution_contract_targets: ensureArray(entry.execution_contract_targets || entry.executionContractTargets)
|
|
2192
|
+
.map((value) => normalizeTelegramMentionUsername(value))
|
|
2193
|
+
.filter(Boolean),
|
|
2194
|
+
next_expected_responders: ensureArray(entry.next_expected_responders || entry.nextExpectedResponders)
|
|
2195
|
+
.map((value) => normalizeTelegramMentionUsername(value))
|
|
2196
|
+
.filter(Boolean),
|
|
2170
2197
|
normalized_intent: String(entry.normalized_intent || entry.normalizedIntent || "").trim().toLowerCase(),
|
|
2171
2198
|
status,
|
|
2172
2199
|
claimed_by_route: String(entry.claimed_by_route || entry.claimedByRoute || "").trim(),
|
|
@@ -2553,6 +2580,86 @@ async function findServerRunnerRequestForMessageID({
|
|
|
2553
2580
|
}
|
|
2554
2581
|
}
|
|
2555
2582
|
|
|
2583
|
+
function runnerRequestHasConversationContractData(entryRaw) {
|
|
2584
|
+
const entry = safeObject(entryRaw);
|
|
2585
|
+
return Boolean(
|
|
2586
|
+
String(entry.conversation_intent_mode || "").trim()
|
|
2587
|
+
|| String(entry.conversation_lead_bot || "").trim()
|
|
2588
|
+
|| String(entry.conversation_summary_bot || "").trim()
|
|
2589
|
+
|| ensureArray(entry.conversation_participants).length
|
|
2590
|
+
|| ensureArray(entry.conversation_initial_responders).length
|
|
2591
|
+
|| ensureArray(entry.conversation_allowed_responders).length
|
|
2592
|
+
|| entry.conversation_allow_bot_to_bot === true
|
|
2593
|
+
|| String(entry.conversation_reply_expectation || "").trim()
|
|
2594
|
+
|| String(entry.execution_contract_type || "").trim()
|
|
2595
|
+
|| entry.execution_contract_actionable === true
|
|
2596
|
+
|| ensureArray(entry.execution_contract_targets).length
|
|
2597
|
+
|| ensureArray(entry.next_expected_responders).length
|
|
2598
|
+
);
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
function pickRunnerSharedConversationSourceRequest(entries = [], excludeRequestKey = "") {
|
|
2602
|
+
const excludedKey = String(excludeRequestKey || "").trim();
|
|
2603
|
+
const matched = sortRunnerRequestEntriesNewestFirst(ensureArray(entries))
|
|
2604
|
+
.filter((entryRaw) => String(safeObject(entryRaw).request_key || "").trim() !== excludedKey)
|
|
2605
|
+
.filter((entryRaw) => {
|
|
2606
|
+
const entry = safeObject(entryRaw);
|
|
2607
|
+
return runnerRequestHasConversationContractData(entry)
|
|
2608
|
+
|| String(entry.root_work_item_id || "").trim()
|
|
2609
|
+
|| String(entry.root_thread_id || "").trim();
|
|
2610
|
+
});
|
|
2611
|
+
return safeObject(matched[0]);
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
async function findServerRunnerConversationSourceRequestForMessageID({
|
|
2615
|
+
normalizedRoute,
|
|
2616
|
+
runtime,
|
|
2617
|
+
chatID,
|
|
2618
|
+
messageID,
|
|
2619
|
+
excludeRequestKey = "",
|
|
2620
|
+
}) {
|
|
2621
|
+
const projectID = String(normalizedRoute?.projectID || "").trim();
|
|
2622
|
+
const provider = String(normalizedRoute?.provider || "").trim();
|
|
2623
|
+
const normalizedChatID = String(chatID || "").trim();
|
|
2624
|
+
const normalizedMessageID = intFromRawAllowZero(messageID, 0);
|
|
2625
|
+
if (
|
|
2626
|
+
!projectID
|
|
2627
|
+
|| !provider
|
|
2628
|
+
|| !normalizedChatID
|
|
2629
|
+
|| normalizedMessageID <= 0
|
|
2630
|
+
|| !runtime?.baseURL
|
|
2631
|
+
|| !runtime?.token
|
|
2632
|
+
) {
|
|
2633
|
+
return null;
|
|
2634
|
+
}
|
|
2635
|
+
try {
|
|
2636
|
+
const serverRequests = await listProjectRunnerRequests({
|
|
2637
|
+
siteBaseURL: runtime.baseURL,
|
|
2638
|
+
projectID,
|
|
2639
|
+
token: runtime.token,
|
|
2640
|
+
timeoutSeconds: runtime.timeoutSeconds,
|
|
2641
|
+
actorUserID: runtime.actor?.user_id,
|
|
2642
|
+
limit: 500,
|
|
2643
|
+
offset: 0,
|
|
2644
|
+
});
|
|
2645
|
+
const matched = serverRequests.filter((entryRaw) => {
|
|
2646
|
+
const entry = safeObject(entryRaw);
|
|
2647
|
+
return (
|
|
2648
|
+
String(entry.project_id || "").trim() === projectID
|
|
2649
|
+
&& String(entry.provider || "").trim() === provider
|
|
2650
|
+
&& String(entry.chat_id || "").trim() === normalizedChatID
|
|
2651
|
+
&& (
|
|
2652
|
+
intFromRawAllowZero(entry.source_message_id, 0) === normalizedMessageID
|
|
2653
|
+
|| intFromRawAllowZero(entry.last_source_message_id, 0) === normalizedMessageID
|
|
2654
|
+
)
|
|
2655
|
+
);
|
|
2656
|
+
});
|
|
2657
|
+
return pickRunnerSharedConversationSourceRequest(matched, excludeRequestKey);
|
|
2658
|
+
} catch {
|
|
2659
|
+
return null;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2556
2663
|
async function loadRunnerArchiveThreadMessageIndex({
|
|
2557
2664
|
runtime,
|
|
2558
2665
|
threadID,
|
|
@@ -2900,7 +3007,6 @@ async function claimRunnerRequestForHumanComment({
|
|
|
2900
3007
|
});
|
|
2901
3008
|
const replyChainContext = safeObject(replyChainResolution.replyChainContext);
|
|
2902
3009
|
const referencedRequest = safeObject(replyChainContext.referencedRequest);
|
|
2903
|
-
const conversationID = String(parsed.conversationID || replyChainContext.conversationID || "").trim();
|
|
2904
3010
|
const resolvedNormalizedIntent = resolveRunnerRequestClaimIntent({
|
|
2905
3011
|
normalizedIntent,
|
|
2906
3012
|
selectedRecord,
|
|
@@ -2912,14 +3018,19 @@ async function claimRunnerRequestForHumanComment({
|
|
|
2912
3018
|
normalizedIntent: resolvedNormalizedIntent,
|
|
2913
3019
|
});
|
|
2914
3020
|
let stateForClaim = safeObject(replyChainResolution.state);
|
|
3021
|
+
const baseConversationID = String(
|
|
3022
|
+
parsed.conversationID
|
|
3023
|
+
|| replyChainContext.conversationID
|
|
3024
|
+
|| "",
|
|
3025
|
+
).trim();
|
|
2915
3026
|
if (
|
|
2916
3027
|
Object.keys(referencedRequest).length > 0
|
|
2917
|
-
&&
|
|
3028
|
+
&& baseConversationID
|
|
2918
3029
|
&& !String(referencedRequest.conversation_id || "").trim()
|
|
2919
3030
|
&& String(referencedRequest.request_key || "").trim()
|
|
2920
3031
|
) {
|
|
2921
3032
|
const backfilled = upsertRunnerRequest(stateForClaim, referencedRequest.request_key, {
|
|
2922
|
-
conversation_id:
|
|
3033
|
+
conversation_id: baseConversationID,
|
|
2923
3034
|
});
|
|
2924
3035
|
stateForClaim = {
|
|
2925
3036
|
...stateForClaim,
|
|
@@ -2928,6 +3039,35 @@ async function claimRunnerRequestForHumanComment({
|
|
|
2928
3039
|
}
|
|
2929
3040
|
const requests = normalizeBotRunnerRequests(stateForClaim.requests);
|
|
2930
3041
|
const existing = safeObject(requests[requestKey]);
|
|
3042
|
+
const currentMessageID = intFromRawAllowZero(parsed.messageID, 0);
|
|
3043
|
+
let sharedConversationSource = currentMessageID > 0
|
|
3044
|
+
? pickRunnerSharedConversationSourceRequest(
|
|
3045
|
+
findRunnerRequestsForMessageID(stateForClaim, normalizedRoute, {
|
|
3046
|
+
chatID: String(parsed.chatID || parsed.chatId || "").trim(),
|
|
3047
|
+
messageID: currentMessageID,
|
|
3048
|
+
}),
|
|
3049
|
+
requestKey,
|
|
3050
|
+
)
|
|
3051
|
+
: {};
|
|
3052
|
+
if (
|
|
3053
|
+
!Object.keys(sharedConversationSource).length
|
|
3054
|
+
&& currentMessageID > 0
|
|
3055
|
+
&& runtime?.baseURL
|
|
3056
|
+
&& runtime?.token
|
|
3057
|
+
) {
|
|
3058
|
+
sharedConversationSource = safeObject(await findServerRunnerConversationSourceRequestForMessageID({
|
|
3059
|
+
normalizedRoute,
|
|
3060
|
+
runtime,
|
|
3061
|
+
chatID: String(parsed.chatID || parsed.chatId || "").trim(),
|
|
3062
|
+
messageID: currentMessageID,
|
|
3063
|
+
excludeRequestKey: requestKey,
|
|
3064
|
+
}));
|
|
3065
|
+
}
|
|
3066
|
+
const resolvedConversationID = String(
|
|
3067
|
+
baseConversationID
|
|
3068
|
+
|| sharedConversationSource.conversation_id
|
|
3069
|
+
|| "",
|
|
3070
|
+
).trim();
|
|
2931
3071
|
if (isFinalRunnerRequestStatus(existing.status)) {
|
|
2932
3072
|
return {
|
|
2933
3073
|
ok: false,
|
|
@@ -2954,23 +3094,87 @@ async function claimRunnerRequestForHumanComment({
|
|
|
2954
3094
|
source_message_id: intFromRawAllowZero(parsed.messageID, 0) || undefined,
|
|
2955
3095
|
root_comment_id: String(selectedRecord?.id || "").trim(),
|
|
2956
3096
|
root_comment_kind: commentKind,
|
|
2957
|
-
conversation_id:
|
|
3097
|
+
conversation_id: resolvedConversationID,
|
|
2958
3098
|
selected_bot_usernames: uniqueOrderedStrings(selectedBotUsernames, normalizeTelegramMentionUsername),
|
|
3099
|
+
conversation_intent_mode: String(
|
|
3100
|
+
existing.conversation_intent_mode || sharedConversationSource.conversation_intent_mode || referencedRequest.conversation_intent_mode || "",
|
|
3101
|
+
).trim().toLowerCase(),
|
|
3102
|
+
conversation_lead_bot: normalizeTelegramMentionUsername(
|
|
3103
|
+
existing.conversation_lead_bot || sharedConversationSource.conversation_lead_bot || referencedRequest.conversation_lead_bot,
|
|
3104
|
+
),
|
|
3105
|
+
conversation_summary_bot: normalizeTelegramMentionUsername(
|
|
3106
|
+
existing.conversation_summary_bot || sharedConversationSource.conversation_summary_bot || referencedRequest.conversation_summary_bot,
|
|
3107
|
+
),
|
|
3108
|
+
conversation_participants: uniqueOrderedStrings(
|
|
3109
|
+
ensureArray(existing.conversation_participants).length
|
|
3110
|
+
? existing.conversation_participants
|
|
3111
|
+
: ensureArray(sharedConversationSource.conversation_participants).length
|
|
3112
|
+
? sharedConversationSource.conversation_participants
|
|
3113
|
+
: referencedRequest.conversation_participants,
|
|
3114
|
+
normalizeTelegramMentionUsername,
|
|
3115
|
+
),
|
|
3116
|
+
conversation_initial_responders: uniqueOrderedStrings(
|
|
3117
|
+
ensureArray(existing.conversation_initial_responders).length
|
|
3118
|
+
? existing.conversation_initial_responders
|
|
3119
|
+
: ensureArray(sharedConversationSource.conversation_initial_responders).length
|
|
3120
|
+
? sharedConversationSource.conversation_initial_responders
|
|
3121
|
+
: referencedRequest.conversation_initial_responders,
|
|
3122
|
+
normalizeTelegramMentionUsername,
|
|
3123
|
+
),
|
|
3124
|
+
conversation_allowed_responders: uniqueOrderedStrings(
|
|
3125
|
+
ensureArray(existing.conversation_allowed_responders).length
|
|
3126
|
+
? existing.conversation_allowed_responders
|
|
3127
|
+
: ensureArray(sharedConversationSource.conversation_allowed_responders).length
|
|
3128
|
+
? sharedConversationSource.conversation_allowed_responders
|
|
3129
|
+
: referencedRequest.conversation_allowed_responders,
|
|
3130
|
+
normalizeTelegramMentionUsername,
|
|
3131
|
+
),
|
|
3132
|
+
conversation_allow_bot_to_bot: existing.conversation_allow_bot_to_bot === true
|
|
3133
|
+
|| sharedConversationSource.conversation_allow_bot_to_bot === true
|
|
3134
|
+
|| referencedRequest.conversation_allow_bot_to_bot === true,
|
|
3135
|
+
conversation_reply_expectation: String(
|
|
3136
|
+
existing.conversation_reply_expectation || sharedConversationSource.conversation_reply_expectation || referencedRequest.conversation_reply_expectation || "",
|
|
3137
|
+
).trim().toLowerCase(),
|
|
3138
|
+
execution_contract_type: String(
|
|
3139
|
+
existing.execution_contract_type || sharedConversationSource.execution_contract_type || referencedRequest.execution_contract_type || "",
|
|
3140
|
+
).trim().toLowerCase(),
|
|
3141
|
+
execution_contract_actionable: existing.execution_contract_actionable === true
|
|
3142
|
+
|| sharedConversationSource.execution_contract_actionable === true
|
|
3143
|
+
|| referencedRequest.execution_contract_actionable === true,
|
|
3144
|
+
execution_contract_targets: uniqueOrderedStrings(
|
|
3145
|
+
ensureArray(existing.execution_contract_targets).length
|
|
3146
|
+
? existing.execution_contract_targets
|
|
3147
|
+
: ensureArray(sharedConversationSource.execution_contract_targets).length
|
|
3148
|
+
? sharedConversationSource.execution_contract_targets
|
|
3149
|
+
: referencedRequest.execution_contract_targets,
|
|
3150
|
+
normalizeTelegramMentionUsername,
|
|
3151
|
+
),
|
|
3152
|
+
next_expected_responders: uniqueOrderedStrings(
|
|
3153
|
+
ensureArray(existing.next_expected_responders).length
|
|
3154
|
+
? existing.next_expected_responders
|
|
3155
|
+
: ensureArray(sharedConversationSource.next_expected_responders).length
|
|
3156
|
+
? sharedConversationSource.next_expected_responders
|
|
3157
|
+
: referencedRequest.next_expected_responders,
|
|
3158
|
+
normalizeTelegramMentionUsername,
|
|
3159
|
+
),
|
|
2959
3160
|
normalized_intent: resolvedNormalizedIntent,
|
|
2960
3161
|
status: "claimed",
|
|
2961
3162
|
claimed_by_route: String(routeKey || "").trim(),
|
|
2962
3163
|
claimed_at: firstNonEmptyString([existing.claimed_at, nowISO]) || nowISO,
|
|
2963
|
-
root_work_item_id: String(existing.root_work_item_id || referencedRequest.root_work_item_id || "").trim(),
|
|
2964
|
-
root_work_item_title: String(existing.root_work_item_title || referencedRequest.root_work_item_title || "").trim(),
|
|
3164
|
+
root_work_item_id: String(existing.root_work_item_id || sharedConversationSource.root_work_item_id || referencedRequest.root_work_item_id || "").trim(),
|
|
3165
|
+
root_work_item_title: String(existing.root_work_item_title || sharedConversationSource.root_work_item_title || referencedRequest.root_work_item_title || "").trim(),
|
|
2965
3166
|
root_work_item_status: normalizeRunnerWorkItemStatus(
|
|
2966
|
-
existing.root_work_item_status || referencedRequest.root_work_item_status,
|
|
3167
|
+
existing.root_work_item_status || sharedConversationSource.root_work_item_status || referencedRequest.root_work_item_status,
|
|
2967
3168
|
),
|
|
2968
|
-
root_thread_id: String(existing.root_thread_id || referencedRequest.root_thread_id || "").trim(),
|
|
3169
|
+
root_thread_id: String(existing.root_thread_id || sharedConversationSource.root_thread_id || referencedRequest.root_thread_id || "").trim(),
|
|
2969
3170
|
root_work_item_created_at: firstNonEmptyString([
|
|
2970
3171
|
existing.root_work_item_created_at,
|
|
3172
|
+
sharedConversationSource.root_work_item_created_at,
|
|
2971
3173
|
referencedRequest.root_work_item_created_at,
|
|
2972
3174
|
]),
|
|
2973
|
-
root_work_item_last_error: String(
|
|
3175
|
+
root_work_item_last_error: String(
|
|
3176
|
+
existing.root_work_item_last_error || sharedConversationSource.root_work_item_last_error || "",
|
|
3177
|
+
).trim(),
|
|
2974
3178
|
last_comment_id: String(selectedRecord?.id || "").trim(),
|
|
2975
3179
|
last_comment_kind: commentKind,
|
|
2976
3180
|
last_source_message_id: intFromRawAllowZero(parsed.messageID, 0) || undefined,
|
|
@@ -2980,7 +3184,7 @@ async function claimRunnerRequestForHumanComment({
|
|
|
2980
3184
|
provider: String(normalizedRoute?.provider || "").trim(),
|
|
2981
3185
|
request_key: requestKey,
|
|
2982
3186
|
route_key: String(routeKey || "").trim(),
|
|
2983
|
-
conversation_id:
|
|
3187
|
+
conversation_id: resolvedConversationID,
|
|
2984
3188
|
source_message_id: intFromRawAllowZero(parsed.messageID, 0) || undefined,
|
|
2985
3189
|
comment_kind: commentKind,
|
|
2986
3190
|
request_status: "claimed",
|
|
@@ -3728,11 +3932,18 @@ function markRunnerRequestLifecycle({
|
|
|
3728
3932
|
outcome,
|
|
3729
3933
|
conversationIDRaw = "",
|
|
3730
3934
|
allowedResponders = [],
|
|
3935
|
+
conversationParticipants = [],
|
|
3936
|
+
conversationInitialResponders = [],
|
|
3731
3937
|
executionContractType = "",
|
|
3938
|
+
executionContractActionable = false,
|
|
3732
3939
|
executionContractTargets = [],
|
|
3733
3940
|
nextExpectedResponders = [],
|
|
3734
3941
|
currentBotSelector = "",
|
|
3735
3942
|
conversationIntentMode = "",
|
|
3943
|
+
conversationLeadBot = "",
|
|
3944
|
+
conversationSummaryBot = "",
|
|
3945
|
+
conversationAllowBotToBot = false,
|
|
3946
|
+
conversationReplyExpectation = "",
|
|
3736
3947
|
normalizedIntent = "",
|
|
3737
3948
|
closedReason = "",
|
|
3738
3949
|
}) {
|
|
@@ -3777,6 +3988,16 @@ function markRunnerRequestLifecycle({
|
|
|
3777
3988
|
const nowISO = new Date().toISOString();
|
|
3778
3989
|
const patch = {
|
|
3779
3990
|
conversation_id: conversationID,
|
|
3991
|
+
conversation_participants: uniqueOrderedStrings(
|
|
3992
|
+
ensureArray(conversationParticipants).length ? conversationParticipants : existing.conversation_participants,
|
|
3993
|
+
normalizeTelegramMentionUsername,
|
|
3994
|
+
),
|
|
3995
|
+
conversation_initial_responders: uniqueOrderedStrings(
|
|
3996
|
+
ensureArray(conversationInitialResponders).length
|
|
3997
|
+
? conversationInitialResponders
|
|
3998
|
+
: existing.conversation_initial_responders,
|
|
3999
|
+
normalizeTelegramMentionUsername,
|
|
4000
|
+
),
|
|
3780
4001
|
conversation_allowed_responders: uniqueOrderedStrings(
|
|
3781
4002
|
ensureArray(allowedResponders).length ? allowedResponders : existing.conversation_allowed_responders,
|
|
3782
4003
|
normalizeTelegramMentionUsername,
|
|
@@ -3786,11 +4007,30 @@ function markRunnerRequestLifecycle({
|
|
|
3786
4007
|
|| existing.conversation_intent_mode
|
|
3787
4008
|
|| "",
|
|
3788
4009
|
).trim().toLowerCase(),
|
|
4010
|
+
conversation_lead_bot: normalizeTelegramMentionUsername(
|
|
4011
|
+
conversationLeadBot
|
|
4012
|
+
|| existing.conversation_lead_bot
|
|
4013
|
+
|| "",
|
|
4014
|
+
),
|
|
4015
|
+
conversation_summary_bot: normalizeTelegramMentionUsername(
|
|
4016
|
+
conversationSummaryBot
|
|
4017
|
+
|| existing.conversation_summary_bot
|
|
4018
|
+
|| "",
|
|
4019
|
+
),
|
|
4020
|
+
conversation_allow_bot_to_bot: conversationAllowBotToBot === true
|
|
4021
|
+
|| existing.conversation_allow_bot_to_bot === true,
|
|
4022
|
+
conversation_reply_expectation: String(
|
|
4023
|
+
conversationReplyExpectation
|
|
4024
|
+
|| existing.conversation_reply_expectation
|
|
4025
|
+
|| "",
|
|
4026
|
+
).trim().toLowerCase(),
|
|
3789
4027
|
execution_contract_type: String(
|
|
3790
4028
|
executionContractType
|
|
3791
4029
|
|| existing.execution_contract_type
|
|
3792
4030
|
|| "",
|
|
3793
4031
|
).trim().toLowerCase(),
|
|
4032
|
+
execution_contract_actionable: executionContractActionable === true
|
|
4033
|
+
|| existing.execution_contract_actionable === true,
|
|
3794
4034
|
execution_contract_targets: uniqueOrderedStrings(
|
|
3795
4035
|
ensureArray(executionContractTargets).length ? executionContractTargets : existing.execution_contract_targets,
|
|
3796
4036
|
normalizeTelegramMentionUsername,
|
|
@@ -3999,13 +4239,36 @@ function mergeRunnerRequestForServerHydration(localEntryRaw, serverEntryRaw) {
|
|
|
3999
4239
|
merged[fieldName] = localValue;
|
|
4000
4240
|
}
|
|
4001
4241
|
};
|
|
4242
|
+
const preserveLocalArrayWhenServerEmpty = (fieldName) => {
|
|
4243
|
+
const serverValues = ensureArray(serverEntry[fieldName]).filter(Boolean);
|
|
4244
|
+
const localValues = ensureArray(localEntry[fieldName]).filter(Boolean);
|
|
4245
|
+
if (serverValues.length === 0 && localValues.length > 0) {
|
|
4246
|
+
merged[fieldName] = localValues;
|
|
4247
|
+
}
|
|
4248
|
+
};
|
|
4002
4249
|
preserveLocalStringWhenServerBlank("conversation_id");
|
|
4250
|
+
preserveLocalStringWhenServerBlank("conversation_intent_mode");
|
|
4251
|
+
preserveLocalStringWhenServerBlank("conversation_lead_bot");
|
|
4252
|
+
preserveLocalStringWhenServerBlank("conversation_summary_bot");
|
|
4253
|
+
preserveLocalStringWhenServerBlank("conversation_reply_expectation");
|
|
4254
|
+
preserveLocalStringWhenServerBlank("execution_contract_type");
|
|
4003
4255
|
preserveLocalStringWhenServerBlank("root_work_item_id");
|
|
4004
4256
|
preserveLocalStringWhenServerBlank("root_work_item_title");
|
|
4005
4257
|
preserveLocalStringWhenServerBlank("root_work_item_status");
|
|
4006
4258
|
preserveLocalStringWhenServerBlank("root_thread_id");
|
|
4007
4259
|
preserveLocalStringWhenServerBlank("root_work_item_created_at");
|
|
4008
4260
|
preserveLocalStringWhenServerBlank("root_work_item_last_error");
|
|
4261
|
+
preserveLocalArrayWhenServerEmpty("conversation_participants");
|
|
4262
|
+
preserveLocalArrayWhenServerEmpty("conversation_initial_responders");
|
|
4263
|
+
preserveLocalArrayWhenServerEmpty("conversation_allowed_responders");
|
|
4264
|
+
preserveLocalArrayWhenServerEmpty("execution_contract_targets");
|
|
4265
|
+
preserveLocalArrayWhenServerEmpty("next_expected_responders");
|
|
4266
|
+
if (serverEntry.conversation_allow_bot_to_bot !== true && localEntry.conversation_allow_bot_to_bot === true) {
|
|
4267
|
+
merged.conversation_allow_bot_to_bot = true;
|
|
4268
|
+
}
|
|
4269
|
+
if (serverEntry.execution_contract_actionable !== true && localEntry.execution_contract_actionable === true) {
|
|
4270
|
+
merged.execution_contract_actionable = true;
|
|
4271
|
+
}
|
|
4009
4272
|
const localStatus = normalizeRunnerRequestStatus(localEntry.status);
|
|
4010
4273
|
const serverStatus = normalizeRunnerRequestStatus(serverEntry.status);
|
|
4011
4274
|
if (isFinalRunnerRequestStatus(localStatus) && !isFinalRunnerRequestStatus(serverStatus)) {
|
|
@@ -6365,8 +6628,8 @@ function buildInformationalMiniExecutionOverride({ route, executionPlan } = {})
|
|
|
6365
6628
|
safeExecutionPlan.roleProfileName || safeRoute.roleProfile || safeRoute.role || "monitor",
|
|
6366
6629
|
) || "monitor";
|
|
6367
6630
|
const lightweightModel = String(
|
|
6368
|
-
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: process.env }) || "gpt-5.
|
|
6369
|
-
).trim() || "gpt-5.
|
|
6631
|
+
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: process.env }) || "gpt-5.4-mini",
|
|
6632
|
+
).trim() || "gpt-5.4-mini";
|
|
6370
6633
|
return {
|
|
6371
6634
|
mode: "role_profile",
|
|
6372
6635
|
role_profile_name: roleProfileName,
|
|
@@ -7832,6 +8095,7 @@ async function processRunnerRouteOnce(route, runtime, mode, options = {}) {
|
|
|
7832
8095
|
runtime,
|
|
7833
8096
|
triggerDecision,
|
|
7834
8097
|
responderAdjudication: inlineAdjudication,
|
|
8098
|
+
persistedHumanIntentRequest: claimedRequest,
|
|
7835
8099
|
deps: {
|
|
7836
8100
|
saveRunnerRouteState,
|
|
7837
8101
|
startRunnerTypingHeartbeat,
|
|
@@ -7886,8 +8150,15 @@ async function processRunnerRouteOnce(route, runtime, mode, options = {}) {
|
|
|
7886
8150
|
routeKey,
|
|
7887
8151
|
outcome: String(processed.result?.outcome || "replied").trim().toLowerCase(),
|
|
7888
8152
|
conversationIDRaw: String(processed.result?.conversation_id || "").trim(),
|
|
8153
|
+
conversationParticipants: ensureArray(processed.result?.conversation_participants),
|
|
8154
|
+
conversationInitialResponders: ensureArray(processed.result?.conversation_initial_responders),
|
|
7889
8155
|
allowedResponders: ensureArray(processed.result?.conversation_allowed_responders),
|
|
8156
|
+
conversationLeadBot: String(processed.result?.conversation_lead_bot || "").trim(),
|
|
8157
|
+
conversationSummaryBot: String(processed.result?.conversation_summary_bot || "").trim(),
|
|
8158
|
+
conversationAllowBotToBot: processed.result?.conversation_allow_bot_to_bot === true,
|
|
8159
|
+
conversationReplyExpectation: String(processed.result?.conversation_reply_expectation || "").trim(),
|
|
7890
8160
|
executionContractType: String(processed.result?.execution_contract_type || "").trim(),
|
|
8161
|
+
executionContractActionable: processed.result?.execution_contract_actionable === true,
|
|
7891
8162
|
executionContractTargets: ensureArray(processed.result?.execution_contract_targets),
|
|
7892
8163
|
nextExpectedResponders: ensureArray(processed.result?.next_expected_responders),
|
|
7893
8164
|
currentBotSelector,
|
|
@@ -10193,6 +10464,7 @@ async function runRunnerStartResolvedRoutes(routes, flags, options = {}) {
|
|
|
10193
10464
|
runtime: deferredExecution.runtime,
|
|
10194
10465
|
triggerDecision: deferredExecution.triggerDecision,
|
|
10195
10466
|
responderAdjudication: deferredExecution.responderAdjudication,
|
|
10467
|
+
persistedHumanIntentRequest: loadRunnerRequestByKey(deferredExecution.requestKey),
|
|
10196
10468
|
deps: {
|
|
10197
10469
|
saveRunnerRouteState,
|
|
10198
10470
|
startRunnerTypingHeartbeat,
|
|
@@ -10278,8 +10550,15 @@ async function runRunnerStartResolvedRoutes(routes, flags, options = {}) {
|
|
|
10278
10550
|
routeKey: deferredExecution.routeKey,
|
|
10279
10551
|
outcome: String(processed.result?.outcome || "replied").trim().toLowerCase(),
|
|
10280
10552
|
conversationIDRaw: String(processed.result?.conversation_id || "").trim(),
|
|
10553
|
+
conversationParticipants: ensureArray(processed.result?.conversation_participants),
|
|
10554
|
+
conversationInitialResponders: ensureArray(processed.result?.conversation_initial_responders),
|
|
10281
10555
|
allowedResponders: ensureArray(processed.result?.conversation_allowed_responders),
|
|
10556
|
+
conversationLeadBot: String(processed.result?.conversation_lead_bot || "").trim(),
|
|
10557
|
+
conversationSummaryBot: String(processed.result?.conversation_summary_bot || "").trim(),
|
|
10558
|
+
conversationAllowBotToBot: processed.result?.conversation_allow_bot_to_bot === true,
|
|
10559
|
+
conversationReplyExpectation: String(processed.result?.conversation_reply_expectation || "").trim(),
|
|
10282
10560
|
executionContractType: String(processed.result?.execution_contract_type || "").trim(),
|
|
10561
|
+
executionContractActionable: processed.result?.execution_contract_actionable === true,
|
|
10283
10562
|
executionContractTargets: ensureArray(processed.result?.execution_contract_targets),
|
|
10284
10563
|
nextExpectedResponders: ensureArray(processed.result?.next_expected_responders),
|
|
10285
10564
|
currentBotSelector: normalizeTelegramMentionUsername(
|
|
@@ -14550,28 +14829,28 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
14550
14829
|
summarizeProviderSupport("kakaotalk"),
|
|
14551
14830
|
);
|
|
14552
14831
|
push(
|
|
14553
|
-
"
|
|
14554
|
-
resolveIntentParserModelDisplayName({ client: "gpt", env: {} }) === "gpt-5.
|
|
14832
|
+
"intent_parser_default_model_uses_gpt_5_4_mini_without_openai_api_key",
|
|
14833
|
+
resolveIntentParserModelDisplayName({ client: "gpt", env: {} }) === "gpt-5.4-mini",
|
|
14555
14834
|
resolveIntentParserModelDisplayName({ client: "gpt", env: {} }),
|
|
14556
14835
|
);
|
|
14557
14836
|
push(
|
|
14558
|
-
"
|
|
14559
|
-
resolveIntentParserModelDisplayName({ client: "gpt", env: { OPENAI_API_KEY: "sk-selftest" } }) === "gpt-5-mini",
|
|
14837
|
+
"intent_parser_defaults_to_gpt_5_4_mini_when_openai_api_key_present",
|
|
14838
|
+
resolveIntentParserModelDisplayName({ client: "gpt", env: { OPENAI_API_KEY: "sk-selftest" } }) === "gpt-5.4-mini",
|
|
14560
14839
|
resolveIntentParserModelDisplayName({ client: "gpt", env: { OPENAI_API_KEY: "sk-selftest" } }),
|
|
14561
14840
|
);
|
|
14562
14841
|
push(
|
|
14563
|
-
"
|
|
14564
|
-
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: {} }) === "gpt-5.
|
|
14842
|
+
"responder_adjudicator_default_model_uses_gpt_5_4_mini_without_openai_api_key",
|
|
14843
|
+
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: {} }) === "gpt-5.4-mini",
|
|
14565
14844
|
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: {} }),
|
|
14566
14845
|
);
|
|
14567
14846
|
push(
|
|
14568
|
-
"
|
|
14569
|
-
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: { OPENAI_API_KEY: "sk-selftest" } }) === "gpt-5-mini",
|
|
14847
|
+
"responder_adjudicator_defaults_to_gpt_5_4_mini_when_openai_api_key_present",
|
|
14848
|
+
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: { OPENAI_API_KEY: "sk-selftest" } }) === "gpt-5.4-mini",
|
|
14570
14849
|
resolveResponderAdjudicatorModelDisplayName({ client: "gpt", env: { OPENAI_API_KEY: "sk-selftest" } }),
|
|
14571
14850
|
);
|
|
14572
14851
|
push(
|
|
14573
|
-
"
|
|
14574
|
-
resolveRolePlannerModelDisplayName({ client: "gpt", env: {} }) === "gpt-5-mini",
|
|
14852
|
+
"role_planner_default_model_uses_gpt_5_4_mini",
|
|
14853
|
+
resolveRolePlannerModelDisplayName({ client: "gpt", env: {} }) === "gpt-5.4-mini",
|
|
14575
14854
|
resolveRolePlannerModelDisplayName({ client: "gpt", env: {} }),
|
|
14576
14855
|
);
|
|
14577
14856
|
push(
|
|
@@ -15931,7 +16210,7 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
15931
16210
|
client: "gpt",
|
|
15932
16211
|
model: "gpt-5.4",
|
|
15933
16212
|
planner_client: "gpt",
|
|
15934
|
-
planner_model: "gpt-5-mini",
|
|
16213
|
+
planner_model: "gpt-5.4-mini",
|
|
15935
16214
|
intent_type: "status_query",
|
|
15936
16215
|
source_message_id: 128,
|
|
15937
16216
|
next_run_at: Date.now() + 5000,
|
|
@@ -15961,7 +16240,7 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
15961
16240
|
&& frame.includes("telegram-monitor-self...")
|
|
15962
16241
|
&& frame.includes("AI_RUNNING")
|
|
15963
16242
|
&& frame.includes("gpt/gpt-5.4")
|
|
15964
|
-
&& frame.includes("planner=gpt/gpt-5-mini")
|
|
16243
|
+
&& frame.includes("planner=gpt/gpt-5.4-mini")
|
|
15965
16244
|
&& frame.includes("status_query")
|
|
15966
16245
|
&& frame.includes("warning=active execution is taking longer than expected"),
|
|
15967
16246
|
frame.replace(/\r?\n/g, " | "),
|
|
@@ -25,6 +25,11 @@ const LOCAL_AI_MODEL_MAPPINGS = {
|
|
|
25
25
|
execution: "gpt-5.4",
|
|
26
26
|
aliases: ["gpt-5.4", "gpt 5.4", "GPT-5.4"],
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
display: "gpt-5.4-mini",
|
|
30
|
+
execution: "gpt-5.4-mini",
|
|
31
|
+
aliases: ["gpt-5.4-mini", "gpt 5.4 mini", "GPT-5.4-mini", "gpt5.4-mini", "gpt54-mini"],
|
|
32
|
+
},
|
|
28
33
|
{
|
|
29
34
|
display: "gpt-5-mini",
|
|
30
35
|
execution: "gpt-5-mini",
|
|
@@ -1068,12 +1073,11 @@ function truthyEnvFlag(value) {
|
|
|
1068
1073
|
function defaultAdjudicationModelForClient(clientName, env = process.env) {
|
|
1069
1074
|
const normalizedClient = normalizeLocalAIClientName(clientName, "");
|
|
1070
1075
|
if (normalizedClient === "gpt") {
|
|
1071
|
-
const hasOpenAIAPIKey = String(env?.OPENAI_API_KEY || "").trim().length > 0;
|
|
1072
1076
|
const prefersMini = truthyEnvFlag(env?.METHEUS_PREFER_GPT_5_MINI_ADJUDICATOR);
|
|
1073
|
-
if (
|
|
1077
|
+
if (prefersMini) {
|
|
1074
1078
|
return "gpt-5-mini";
|
|
1075
1079
|
}
|
|
1076
|
-
return "gpt-5.
|
|
1080
|
+
return "gpt-5.4-mini";
|
|
1077
1081
|
}
|
|
1078
1082
|
return suggestLocalAIModelDisplayName(normalizedClient, "");
|
|
1079
1083
|
}
|
|
@@ -1081,7 +1085,7 @@ function defaultAdjudicationModelForClient(clientName, env = process.env) {
|
|
|
1081
1085
|
function defaultRolePlannerModelForClient(clientName) {
|
|
1082
1086
|
const normalizedClient = normalizeLocalAIClientName(clientName, "");
|
|
1083
1087
|
if (normalizedClient === "gpt") {
|
|
1084
|
-
return "gpt-5-mini";
|
|
1088
|
+
return "gpt-5.4-mini";
|
|
1085
1089
|
}
|
|
1086
1090
|
return suggestLocalAIModelDisplayName(normalizedClient, "");
|
|
1087
1091
|
}
|
|
@@ -2660,7 +2664,7 @@ export function adjudicateRunnerStartupLoopWithAI({
|
|
|
2660
2664
|
|| env?.METHEUS_STARTUP_LOOP_ADJUDICATOR_MODEL
|
|
2661
2665
|
|| env?.METHEUS_RESPONDER_ADJUDICATOR_MODEL
|
|
2662
2666
|
|| env?.METHEUS_INTENT_PARSER_MODEL
|
|
2663
|
-
|| (adjudicatorClient === "gpt" ? "gpt-5.
|
|
2667
|
+
|| (adjudicatorClient === "gpt" ? "gpt-5.4-mini" : suggestLocalAIModelDisplayName(adjudicatorClient, ""))
|
|
2664
2668
|
|| "",
|
|
2665
2669
|
).trim();
|
|
2666
2670
|
const rawText = runLocalAIPromptRawText({
|
package/lib/runner-data.mjs
CHANGED
|
@@ -339,8 +339,19 @@ export async function listProjectRunnerRequests(
|
|
|
339
339
|
root_comment_kind: String(row.root_comment_kind || row.rootCommentKind || row.RootCommentKind || "").trim(),
|
|
340
340
|
conversation_id: String(row.conversation_id || row.conversationID || row.ConversationID || "").trim(),
|
|
341
341
|
selected_bot_usernames: ensureArray(row.selected_bot_usernames || row.selectedBotUsernames || row.SelectedBotUsernames).map((value) => String(value || "").trim()).filter(Boolean),
|
|
342
|
+
conversation_intent_mode: String(row.conversation_intent_mode || row.conversationIntentMode || row.ConversationIntentMode || "").trim(),
|
|
343
|
+
conversation_lead_bot: String(row.conversation_lead_bot || row.conversationLeadBot || row.ConversationLeadBot || "").trim(),
|
|
344
|
+
conversation_summary_bot: String(row.conversation_summary_bot || row.conversationSummaryBot || row.ConversationSummaryBot || "").trim(),
|
|
345
|
+
conversation_participants: ensureArray(row.conversation_participants || row.conversationParticipants || row.ConversationParticipants).map((value) => String(value || "").trim()).filter(Boolean),
|
|
346
|
+
conversation_initial_responders: ensureArray(row.conversation_initial_responders || row.conversationInitialResponders || row.ConversationInitialResponders).map((value) => String(value || "").trim()).filter(Boolean),
|
|
342
347
|
conversation_allowed_responders: ensureArray(row.conversation_allowed_responders || row.conversationAllowedResponders || row.ConversationAllowedResponders).map((value) => String(value || "").trim()).filter(Boolean),
|
|
348
|
+
conversation_allow_bot_to_bot: row.conversation_allow_bot_to_bot === true || row.conversationAllowBotToBot === true || row.ConversationAllowBotToBot === true,
|
|
349
|
+
conversation_reply_expectation: String(row.conversation_reply_expectation || row.conversationReplyExpectation || row.ConversationReplyExpectation || "").trim(),
|
|
343
350
|
normalized_intent: String(row.normalized_intent || row.normalizedIntent || row.NormalizedIntent || "").trim(),
|
|
351
|
+
execution_contract_type: String(row.execution_contract_type || row.executionContractType || row.ExecutionContractType || "").trim(),
|
|
352
|
+
execution_contract_actionable: row.execution_contract_actionable === true || row.executionContractActionable === true || row.ExecutionContractActionable === true,
|
|
353
|
+
execution_contract_targets: ensureArray(row.execution_contract_targets || row.executionContractTargets || row.ExecutionContractTargets).map((value) => String(value || "").trim()).filter(Boolean),
|
|
354
|
+
next_expected_responders: ensureArray(row.next_expected_responders || row.nextExpectedResponders || row.NextExpectedResponders).map((value) => String(value || "").trim()).filter(Boolean),
|
|
344
355
|
status: String(row.status || row.Status || "").trim(),
|
|
345
356
|
claimed_by_route: String(row.claimed_by_route || row.claimedByRoute || row.ClaimedByRoute || "").trim(),
|
|
346
357
|
claimed_at: String(row.claimed_at || row.claimedAt || row.ClaimedAt || "").trim(),
|
|
@@ -390,8 +401,19 @@ export async function upsertProjectRunnerRequest(
|
|
|
390
401
|
root_comment_kind: String(raw.root_comment_kind || "").trim(),
|
|
391
402
|
conversation_id: String(raw.conversation_id || "").trim(),
|
|
392
403
|
selected_bot_usernames: ensureArray(raw.selected_bot_usernames).map((value) => String(value || "").trim()).filter(Boolean),
|
|
404
|
+
conversation_intent_mode: String(raw.conversation_intent_mode || "").trim(),
|
|
405
|
+
conversation_lead_bot: String(raw.conversation_lead_bot || "").trim(),
|
|
406
|
+
conversation_summary_bot: String(raw.conversation_summary_bot || "").trim(),
|
|
407
|
+
conversation_participants: ensureArray(raw.conversation_participants).map((value) => String(value || "").trim()).filter(Boolean),
|
|
408
|
+
conversation_initial_responders: ensureArray(raw.conversation_initial_responders).map((value) => String(value || "").trim()).filter(Boolean),
|
|
393
409
|
conversation_allowed_responders: ensureArray(raw.conversation_allowed_responders).map((value) => String(value || "").trim()).filter(Boolean),
|
|
410
|
+
conversation_allow_bot_to_bot: raw.conversation_allow_bot_to_bot === true,
|
|
411
|
+
conversation_reply_expectation: String(raw.conversation_reply_expectation || "").trim(),
|
|
394
412
|
normalized_intent: String(raw.normalized_intent || "").trim(),
|
|
413
|
+
execution_contract_type: String(raw.execution_contract_type || "").trim(),
|
|
414
|
+
execution_contract_actionable: raw.execution_contract_actionable === true,
|
|
415
|
+
execution_contract_targets: ensureArray(raw.execution_contract_targets).map((value) => String(value || "").trim()).filter(Boolean),
|
|
416
|
+
next_expected_responders: ensureArray(raw.next_expected_responders).map((value) => String(value || "").trim()).filter(Boolean),
|
|
395
417
|
status: String(raw.status || "").trim(),
|
|
396
418
|
claimed_by_route: String(raw.claimed_by_route || "").trim(),
|
|
397
419
|
claimed_at: String(raw.claimed_at || "").trim() || undefined,
|