metheus-governance-mcp-cli 0.2.242 → 0.2.248
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 +367 -177
- package/lib/runner-helpers.mjs +124 -0
- package/lib/runner-orchestration.mjs +36 -14
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -133,16 +133,19 @@ import {
|
|
|
133
133
|
tryRegister,
|
|
134
134
|
withWorkspaceDirArg,
|
|
135
135
|
} from "./lib/client-registration.mjs";
|
|
136
|
-
import {
|
|
137
|
-
applyPendingAgeSelection,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
136
|
+
import {
|
|
137
|
+
applyPendingAgeSelection,
|
|
138
|
+
buildTelegramBotReplyEnvelope,
|
|
139
|
+
buildTelegramMessageEnvelopeFromParsedArchive as buildRunnerTelegramMessageEnvelopeFromParsedArchive,
|
|
140
|
+
buildRunnerRouteStateFromComment,
|
|
141
|
+
buildProcessableArchiveLogicalKey,
|
|
142
|
+
findEarlierProcessableArchiveDuplicate,
|
|
143
|
+
isInboundArchiveKind,
|
|
144
|
+
normalizeTelegramMessageEnvelope as normalizeRunnerTelegramMessageEnvelope,
|
|
145
|
+
normalizeArchiveCommentRecord,
|
|
146
|
+
selectPendingArchiveComments,
|
|
147
|
+
printRunnerResult,
|
|
148
|
+
} from "./lib/runner-helpers.mjs";
|
|
146
149
|
import {
|
|
147
150
|
createProjectContextItem as createProjectContextItemImpl,
|
|
148
151
|
createProjectEvidence as createProjectEvidenceImpl,
|
|
@@ -1915,15 +1918,24 @@ function mergeRunnerStateRecords(preferred, fallback) {
|
|
|
1915
1918
|
}
|
|
1916
1919
|
return allowUndefined ? undefined : 0;
|
|
1917
1920
|
};
|
|
1918
|
-
const pickArrayField = (key, normalizer = (value) => String(value || "").trim()) => {
|
|
1919
|
-
if (hasOwn(primary, key)) {
|
|
1920
|
-
const value = uniqueOrderedStrings(ensureArray(primary[key]), normalizer).filter(Boolean);
|
|
1921
|
-
if (value.length) {
|
|
1922
|
-
return value;
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
|
-
return uniqueOrderedStrings(ensureArray(secondary[key]), normalizer).filter(Boolean);
|
|
1926
|
-
};
|
|
1921
|
+
const pickArrayField = (key, normalizer = (value) => String(value || "").trim()) => {
|
|
1922
|
+
if (hasOwn(primary, key)) {
|
|
1923
|
+
const value = uniqueOrderedStrings(ensureArray(primary[key]), normalizer).filter(Boolean);
|
|
1924
|
+
if (value.length) {
|
|
1925
|
+
return value;
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
return uniqueOrderedStrings(ensureArray(secondary[key]), normalizer).filter(Boolean);
|
|
1929
|
+
};
|
|
1930
|
+
const pickObjectField = (key) => {
|
|
1931
|
+
if (hasOwn(primary, key)) {
|
|
1932
|
+
const value = safeObject(primary[key]);
|
|
1933
|
+
if (Object.keys(value).length) {
|
|
1934
|
+
return value;
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
return safeObject(secondary[key]);
|
|
1938
|
+
};
|
|
1927
1939
|
return {
|
|
1928
1940
|
last_processed_comment_id: pickStringField("last_processed_comment_id"),
|
|
1929
1941
|
last_processed_created_at: pickStringField("last_processed_created_at"),
|
|
@@ -1970,11 +1982,14 @@ function mergeRunnerStateRecords(preferred, fallback) {
|
|
|
1970
1982
|
last_followup_response_contract_validation_reason: pickStringField("last_followup_response_contract_validation_reason"),
|
|
1971
1983
|
last_followup_assignment_validation_status: pickStringField("last_followup_assignment_validation_status"),
|
|
1972
1984
|
last_followup_assignment_validation_reason: pickStringField("last_followup_assignment_validation_reason"),
|
|
1973
|
-
last_followup_delivery_status: pickStringField("last_followup_delivery_status"),
|
|
1974
|
-
last_followup_archive_status: pickStringField("last_followup_archive_status"),
|
|
1975
|
-
last_followup_transport_error: pickStringField("last_followup_transport_error"),
|
|
1976
|
-
last_followup_archive_error: pickStringField("last_followup_archive_error"),
|
|
1977
|
-
|
|
1985
|
+
last_followup_delivery_status: pickStringField("last_followup_delivery_status"),
|
|
1986
|
+
last_followup_archive_status: pickStringField("last_followup_archive_status"),
|
|
1987
|
+
last_followup_transport_error: pickStringField("last_followup_transport_error"),
|
|
1988
|
+
last_followup_archive_error: pickStringField("last_followup_archive_error"),
|
|
1989
|
+
last_followup_source_message_envelope: pickObjectField("last_followup_source_message_envelope"),
|
|
1990
|
+
last_followup_last_reply_message_envelope: pickObjectField("last_followup_last_reply_message_envelope"),
|
|
1991
|
+
last_followup_attempted_delivery_envelope: pickObjectField("last_followup_attempted_delivery_envelope"),
|
|
1992
|
+
last_contract_validation_targets: pickArrayField("last_contract_validation_targets", normalizeTelegramMentionUsername),
|
|
1978
1993
|
last_normalized_execution_contract_targets: pickArrayField("last_normalized_execution_contract_targets", normalizeTelegramMentionUsername),
|
|
1979
1994
|
last_normalized_execution_next_responders: pickArrayField("last_normalized_execution_next_responders", normalizeTelegramMentionUsername),
|
|
1980
1995
|
last_followup_execution_contract_targets: pickArrayField("last_followup_execution_contract_targets", normalizeTelegramMentionUsername),
|
|
@@ -2114,11 +2129,11 @@ function loadBotRunnerState() {
|
|
|
2114
2129
|
}
|
|
2115
2130
|
}
|
|
2116
2131
|
|
|
2117
|
-
function writeTextFileAtomic(filePath, text) {
|
|
2118
|
-
const normalizedPath = String(filePath || "").trim();
|
|
2119
|
-
if (!normalizedPath) {
|
|
2120
|
-
throw new Error("filePath is required");
|
|
2121
|
-
}
|
|
2132
|
+
function writeTextFileAtomic(filePath, text) {
|
|
2133
|
+
const normalizedPath = String(filePath || "").trim();
|
|
2134
|
+
if (!normalizedPath) {
|
|
2135
|
+
throw new Error("filePath is required");
|
|
2136
|
+
}
|
|
2122
2137
|
const directoryPath = path.dirname(normalizedPath);
|
|
2123
2138
|
fs.mkdirSync(directoryPath, { recursive: true });
|
|
2124
2139
|
const tempPath = path.join(
|
|
@@ -2130,31 +2145,39 @@ function writeTextFileAtomic(filePath, text) {
|
|
|
2130
2145
|
const sleepBuffer = new SharedArrayBuffer(4);
|
|
2131
2146
|
const sleepArray = new Int32Array(sleepBuffer);
|
|
2132
2147
|
let lastRenameError = null;
|
|
2133
|
-
try {
|
|
2134
|
-
for (const delayMs of renameRetryDelaysMs) {
|
|
2135
|
-
if (delayMs > 0) {
|
|
2136
|
-
Atomics.wait(sleepArray, 0, 0, delayMs);
|
|
2137
|
-
}
|
|
2138
|
-
try {
|
|
2139
|
-
fs.renameSync(tempPath, normalizedPath);
|
|
2140
|
-
lastRenameError = null;
|
|
2141
|
-
break;
|
|
2142
|
-
} catch (error) {
|
|
2143
|
-
lastRenameError = error;
|
|
2144
|
-
try {
|
|
2145
|
-
fs.
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
}
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2148
|
+
try {
|
|
2149
|
+
for (const delayMs of renameRetryDelaysMs) {
|
|
2150
|
+
if (delayMs > 0) {
|
|
2151
|
+
Atomics.wait(sleepArray, 0, 0, delayMs);
|
|
2152
|
+
}
|
|
2153
|
+
try {
|
|
2154
|
+
fs.renameSync(tempPath, normalizedPath);
|
|
2155
|
+
lastRenameError = null;
|
|
2156
|
+
break;
|
|
2157
|
+
} catch (error) {
|
|
2158
|
+
lastRenameError = error;
|
|
2159
|
+
try {
|
|
2160
|
+
fs.copyFileSync(tempPath, normalizedPath);
|
|
2161
|
+
lastRenameError = null;
|
|
2162
|
+
break;
|
|
2163
|
+
} catch (copyError) {
|
|
2164
|
+
lastRenameError = copyError;
|
|
2165
|
+
try {
|
|
2166
|
+
fs.writeFileSync(normalizedPath, text, "utf8");
|
|
2167
|
+
lastRenameError = null;
|
|
2168
|
+
break;
|
|
2169
|
+
} catch (writeError) {
|
|
2170
|
+
lastRenameError = writeError;
|
|
2171
|
+
}
|
|
2172
|
+
const errorCode = String(
|
|
2173
|
+
lastRenameError?.code || copyError?.code || error?.code || "",
|
|
2174
|
+
).trim().toUpperCase();
|
|
2175
|
+
if (!["EPERM", "EBUSY", "ENOTEMPTY"].includes(errorCode)) {
|
|
2176
|
+
throw lastRenameError;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2158
2181
|
if (lastRenameError) {
|
|
2159
2182
|
throw lastRenameError;
|
|
2160
2183
|
}
|
|
@@ -2468,6 +2491,28 @@ function normalizeRunnerReplyChainSnapshot(rawSnapshot) {
|
|
|
2468
2491
|
};
|
|
2469
2492
|
}
|
|
2470
2493
|
|
|
2494
|
+
function buildRunnerReplyChainSnapshotFromMessageEnvelope(envelopeRaw, overrides = {}) {
|
|
2495
|
+
const envelope = normalizeRunnerTelegramMessageEnvelope(envelopeRaw);
|
|
2496
|
+
if (!Object.keys(envelope).length) {
|
|
2497
|
+
return null;
|
|
2498
|
+
}
|
|
2499
|
+
return normalizeRunnerReplyChainSnapshot({
|
|
2500
|
+
message_id: envelope.message_id,
|
|
2501
|
+
message_thread_id: envelope.message_thread_id,
|
|
2502
|
+
reply_to_message_id: envelope.reply_to_message_id,
|
|
2503
|
+
speaker_type: firstNonEmptyString([
|
|
2504
|
+
overrides.speaker_type,
|
|
2505
|
+
envelope.sender_is_bot === true ? "bot" : "human",
|
|
2506
|
+
]),
|
|
2507
|
+
speaker_label: firstNonEmptyString([
|
|
2508
|
+
overrides.speaker_label,
|
|
2509
|
+
envelope.sender_username ? `@${String(envelope.sender_username || "").trim().replace(/^@+/, "")}` : "",
|
|
2510
|
+
envelope.sender,
|
|
2511
|
+
]),
|
|
2512
|
+
body: firstNonEmptyString([overrides.body, envelope.body]),
|
|
2513
|
+
});
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2471
2516
|
function normalizeRunnerReplyChainContext(rawContext) {
|
|
2472
2517
|
const context = safeObject(rawContext);
|
|
2473
2518
|
const normalized = {
|
|
@@ -2530,6 +2575,20 @@ function normalizeBotRunnerRequests(rawRequests, nowMs = Date.now()) {
|
|
|
2530
2575
|
0,
|
|
2531
2576
|
) || undefined,
|
|
2532
2577
|
source_message_body: String(entry.source_message_body || entry.sourceMessageBody || "").trim(),
|
|
2578
|
+
source_message_envelope: normalizeRunnerTelegramMessageEnvelope(
|
|
2579
|
+
entry.source_message_envelope
|
|
2580
|
+
|| entry.sourceMessageEnvelope
|
|
2581
|
+
|| (intFromRawAllowZero(entry.source_message_id || entry.sourceMessageID, 0) > 0
|
|
2582
|
+
? {
|
|
2583
|
+
chat_id: entry.chat_id || entry.chatID,
|
|
2584
|
+
message_id: entry.source_message_id || entry.sourceMessageID,
|
|
2585
|
+
message_thread_id: entry.source_message_thread_id || entry.sourceMessageThreadID,
|
|
2586
|
+
body: entry.source_message_body || entry.sourceMessageBody,
|
|
2587
|
+
sender: "human",
|
|
2588
|
+
sender_is_bot: false,
|
|
2589
|
+
}
|
|
2590
|
+
: {}),
|
|
2591
|
+
),
|
|
2533
2592
|
root_comment_id: String(entry.root_comment_id || entry.rootCommentID || "").trim(),
|
|
2534
2593
|
root_comment_kind: String(entry.root_comment_kind || entry.rootCommentKind || "").trim().toLowerCase(),
|
|
2535
2594
|
conversation_id: String(entry.conversation_id || entry.conversationId || "").trim(),
|
|
@@ -2662,11 +2721,43 @@ function normalizeBotRunnerRequests(rawRequests, nowMs = Date.now()) {
|
|
|
2662
2721
|
entry.last_reply_message_thread_id || entry.lastReplyMessageThreadID,
|
|
2663
2722
|
0,
|
|
2664
2723
|
) || undefined,
|
|
2724
|
+
last_reply_to_message_id: intFromRawAllowZero(
|
|
2725
|
+
entry.last_reply_to_message_id || entry.lastReplyToMessageID,
|
|
2726
|
+
0,
|
|
2727
|
+
) || undefined,
|
|
2728
|
+
last_reply_message_envelope: normalizeRunnerTelegramMessageEnvelope(
|
|
2729
|
+
entry.last_reply_message_envelope
|
|
2730
|
+
|| entry.lastReplyMessageEnvelope
|
|
2731
|
+
|| (intFromRawAllowZero(entry.last_reply_message_id || entry.lastReplyMessageID, 0) > 0
|
|
2732
|
+
? buildTelegramBotReplyEnvelope({
|
|
2733
|
+
chatID: entry.chat_id || entry.chatID,
|
|
2734
|
+
messageID: entry.last_reply_message_id || entry.lastReplyMessageID,
|
|
2735
|
+
messageThreadID: entry.last_reply_message_thread_id || entry.lastReplyMessageThreadID,
|
|
2736
|
+
replyToMessageID: entry.last_reply_to_message_id || entry.lastReplyToMessageID,
|
|
2737
|
+
senderUsername: entry.conversation_summary_bot || ensureArray(entry.selected_bot_usernames || entry.selectedBotUsernames)[0] || "",
|
|
2738
|
+
body: entry.followup_ai_reply_preview || entry.followupAiReplyPreview || entry.ai_reply_preview || entry.aiReplyPreview,
|
|
2739
|
+
})
|
|
2740
|
+
: {}),
|
|
2741
|
+
),
|
|
2742
|
+
attempted_delivery_envelope: normalizeRunnerTelegramMessageEnvelope(
|
|
2743
|
+
entry.attempted_delivery_envelope
|
|
2744
|
+
|| entry.attemptedDeliveryEnvelope
|
|
2745
|
+
|| ((intFromRawAllowZero(entry.last_reply_to_message_id || entry.lastReplyToMessageID, 0) > 0
|
|
2746
|
+
|| intFromRawAllowZero(entry.last_reply_message_thread_id || entry.lastReplyMessageThreadID, 0) > 0)
|
|
2747
|
+
? buildTelegramBotReplyEnvelope({
|
|
2748
|
+
chatID: entry.chat_id || entry.chatID,
|
|
2749
|
+
messageThreadID: entry.last_reply_message_thread_id || entry.lastReplyMessageThreadID,
|
|
2750
|
+
replyToMessageID: entry.last_reply_to_message_id || entry.lastReplyToMessageID,
|
|
2751
|
+
senderUsername: entry.conversation_summary_bot || ensureArray(entry.selected_bot_usernames || entry.selectedBotUsernames)[0] || "",
|
|
2752
|
+
body: entry.followup_ai_reply_preview || entry.followupAiReplyPreview || entry.ai_reply_preview || entry.aiReplyPreview,
|
|
2753
|
+
})
|
|
2754
|
+
: {}),
|
|
2755
|
+
),
|
|
2665
2756
|
updated_at: updatedAt || new Date(nowMs).toISOString(),
|
|
2666
|
-
};
|
|
2667
|
-
}
|
|
2668
|
-
return normalized;
|
|
2669
|
-
}
|
|
2757
|
+
};
|
|
2758
|
+
}
|
|
2759
|
+
return normalized;
|
|
2760
|
+
}
|
|
2670
2761
|
|
|
2671
2762
|
function normalizeBotRunnerConsumedComments(rawConsumed, nowMs = Date.now()) {
|
|
2672
2763
|
const normalized = {};
|
|
@@ -3366,23 +3457,26 @@ function runnerRequestPreferredArchiveError(entryRaw) {
|
|
|
3366
3457
|
).trim();
|
|
3367
3458
|
}
|
|
3368
3459
|
|
|
3369
|
-
function buildRunnerValidationAndDeliverySummary({
|
|
3370
|
-
aiReplyPreview = "",
|
|
3371
|
-
executionContractType = "",
|
|
3372
|
-
executionContractTargets = [],
|
|
3373
|
-
nextExpectedResponders = [],
|
|
3460
|
+
function buildRunnerValidationAndDeliverySummary({
|
|
3461
|
+
aiReplyPreview = "",
|
|
3462
|
+
executionContractType = "",
|
|
3463
|
+
executionContractTargets = [],
|
|
3464
|
+
nextExpectedResponders = [],
|
|
3374
3465
|
responseContractValidationStatus = "",
|
|
3375
3466
|
responseContractValidationReason = "",
|
|
3376
3467
|
responseContractValidationTargets = [],
|
|
3377
3468
|
assignmentValidationStatus = "",
|
|
3378
3469
|
assignmentValidationReason = "",
|
|
3379
3470
|
assignmentValidationModes = [],
|
|
3380
|
-
deliveryStatus = "",
|
|
3381
|
-
archiveStatus = "",
|
|
3382
|
-
transportError = "",
|
|
3383
|
-
archiveError = "",
|
|
3384
|
-
|
|
3385
|
-
|
|
3471
|
+
deliveryStatus = "",
|
|
3472
|
+
archiveStatus = "",
|
|
3473
|
+
transportError = "",
|
|
3474
|
+
archiveError = "",
|
|
3475
|
+
sourceMessageEnvelope = {},
|
|
3476
|
+
lastReplyMessageEnvelope = {},
|
|
3477
|
+
attemptedDeliveryEnvelope = {},
|
|
3478
|
+
} = {}) {
|
|
3479
|
+
return {
|
|
3386
3480
|
ai_reply_preview: String(aiReplyPreview || "").trim(),
|
|
3387
3481
|
execution_contract_type: String(executionContractType || "").trim().toLowerCase(),
|
|
3388
3482
|
execution_contract_targets: uniqueOrderedStrings(
|
|
@@ -3405,12 +3499,15 @@ function buildRunnerValidationAndDeliverySummary({
|
|
|
3405
3499
|
ensureArray(assignmentValidationModes),
|
|
3406
3500
|
(value) => String(value || "").trim().toLowerCase(),
|
|
3407
3501
|
),
|
|
3408
|
-
delivery_status: String(deliveryStatus || "").trim().toLowerCase(),
|
|
3409
|
-
archive_status: String(archiveStatus || "").trim().toLowerCase(),
|
|
3410
|
-
transport_error: String(transportError || "").trim(),
|
|
3411
|
-
archive_error: String(archiveError || "").trim(),
|
|
3412
|
-
|
|
3413
|
-
|
|
3502
|
+
delivery_status: String(deliveryStatus || "").trim().toLowerCase(),
|
|
3503
|
+
archive_status: String(archiveStatus || "").trim().toLowerCase(),
|
|
3504
|
+
transport_error: String(transportError || "").trim(),
|
|
3505
|
+
archive_error: String(archiveError || "").trim(),
|
|
3506
|
+
source_message_envelope: safeObject(sourceMessageEnvelope),
|
|
3507
|
+
last_reply_message_envelope: safeObject(lastReplyMessageEnvelope),
|
|
3508
|
+
attempted_delivery_envelope: safeObject(attemptedDeliveryEnvelope),
|
|
3509
|
+
};
|
|
3510
|
+
}
|
|
3414
3511
|
|
|
3415
3512
|
function buildRunnerRequestRootWorkItemSummary(entryRaw) {
|
|
3416
3513
|
const entry = safeObject(entryRaw);
|
|
@@ -3489,12 +3586,15 @@ function buildRunnerRouteLastResultSummary(routeStateRaw) {
|
|
|
3489
3586
|
responseContractValidationTargets,
|
|
3490
3587
|
assignmentValidationStatus,
|
|
3491
3588
|
assignmentValidationReason,
|
|
3492
|
-
assignmentValidationModes,
|
|
3493
|
-
deliveryStatus: routeState.last_followup_delivery_status,
|
|
3494
|
-
archiveStatus: routeState.last_followup_archive_status,
|
|
3495
|
-
transportError: routeState.last_followup_transport_error,
|
|
3496
|
-
archiveError: routeState.last_followup_archive_error,
|
|
3497
|
-
|
|
3589
|
+
assignmentValidationModes,
|
|
3590
|
+
deliveryStatus: routeState.last_followup_delivery_status,
|
|
3591
|
+
archiveStatus: routeState.last_followup_archive_status,
|
|
3592
|
+
transportError: routeState.last_followup_transport_error,
|
|
3593
|
+
archiveError: routeState.last_followup_archive_error,
|
|
3594
|
+
sourceMessageEnvelope: routeState.last_followup_source_message_envelope,
|
|
3595
|
+
lastReplyMessageEnvelope: routeState.last_followup_last_reply_message_envelope,
|
|
3596
|
+
attemptedDeliveryEnvelope: routeState.last_followup_attempted_delivery_envelope,
|
|
3597
|
+
}),
|
|
3498
3598
|
workspace_dir: String(routeState.last_workspace_dir || "").trim(),
|
|
3499
3599
|
artifact_validation: String(routeState.last_artifact_validation || "").trim(),
|
|
3500
3600
|
artifact_paths: ensureArray(routeState.last_artifact_paths).map((item) => String(item || "").trim()).filter(Boolean),
|
|
@@ -3677,35 +3777,22 @@ async function findRunnerArchiveThreadMessageByID({
|
|
|
3677
3777
|
|
|
3678
3778
|
function buildRunnerReplyChainSnapshotFromParsedArchive(parsedArchiveRaw, overrides = {}) {
|
|
3679
3779
|
const parsedArchive = safeObject(parsedArchiveRaw);
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3780
|
+
return buildRunnerReplyChainSnapshotFromMessageEnvelope(
|
|
3781
|
+
buildRunnerTelegramMessageEnvelopeFromParsedArchive(parsedArchive, overrides),
|
|
3782
|
+
{
|
|
3783
|
+
speaker_type: firstNonEmptyString([
|
|
3784
|
+
overrides.speaker_type,
|
|
3785
|
+
buildRunnerReplyChainSpeakerType(parsedArchive),
|
|
3786
|
+
]),
|
|
3787
|
+
speaker_label: firstNonEmptyString([
|
|
3788
|
+
overrides.speaker_label,
|
|
3789
|
+
buildRunnerReplyChainSpeakerLabel(parsedArchive),
|
|
3790
|
+
]),
|
|
3791
|
+
body: truncateRunnerReplyChainText(
|
|
3792
|
+
firstNonEmptyString([overrides.body, parsedArchive.body]),
|
|
3793
|
+
),
|
|
3794
|
+
},
|
|
3684
3795
|
);
|
|
3685
|
-
const replyToMessageID = intFromRawAllowZero(
|
|
3686
|
-
overrides.reply_to_message_id ?? parsedArchive.replyToMessageID,
|
|
3687
|
-
0,
|
|
3688
|
-
);
|
|
3689
|
-
const body = truncateRunnerReplyChainText(
|
|
3690
|
-
firstNonEmptyString([overrides.body, parsedArchive.body]),
|
|
3691
|
-
);
|
|
3692
|
-
if (!(messageID > 0) && !body) {
|
|
3693
|
-
return null;
|
|
3694
|
-
}
|
|
3695
|
-
return normalizeRunnerReplyChainSnapshot({
|
|
3696
|
-
message_id: messageID,
|
|
3697
|
-
message_thread_id: messageThreadID,
|
|
3698
|
-
reply_to_message_id: replyToMessageID,
|
|
3699
|
-
speaker_type: firstNonEmptyString([
|
|
3700
|
-
overrides.speaker_type,
|
|
3701
|
-
buildRunnerReplyChainSpeakerType(parsedArchive),
|
|
3702
|
-
]),
|
|
3703
|
-
speaker_label: firstNonEmptyString([
|
|
3704
|
-
overrides.speaker_label,
|
|
3705
|
-
buildRunnerReplyChainSpeakerLabel(parsedArchive),
|
|
3706
|
-
]),
|
|
3707
|
-
body,
|
|
3708
|
-
});
|
|
3709
3796
|
}
|
|
3710
3797
|
|
|
3711
3798
|
function buildRunnerReplyChainSnapshotFromArchiveRecord(recordRaw) {
|
|
@@ -3716,16 +3803,28 @@ function buildRunnerReplyChainSnapshotFromArchiveRecord(recordRaw) {
|
|
|
3716
3803
|
|
|
3717
3804
|
function buildRunnerReplyChainSnapshotFromRequestSource(requestRaw) {
|
|
3718
3805
|
const request = safeObject(requestRaw);
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3806
|
+
const explicitEnvelope = normalizeRunnerTelegramMessageEnvelope(
|
|
3807
|
+
request.source_message_envelope || request.sourceMessageEnvelope,
|
|
3808
|
+
);
|
|
3809
|
+
const fallbackEnvelope = intFromRawAllowZero(request.source_message_id, 0) > 0
|
|
3810
|
+
? {
|
|
3811
|
+
chat_id: request.chat_id,
|
|
3812
|
+
message_id: request.source_message_id,
|
|
3813
|
+
message_thread_id: request.source_message_thread_id,
|
|
3814
|
+
body: request.source_message_body,
|
|
3815
|
+
sender: "human",
|
|
3816
|
+
sender_is_bot: false,
|
|
3817
|
+
}
|
|
3818
|
+
: null;
|
|
3819
|
+
return buildRunnerReplyChainSnapshotFromMessageEnvelope(
|
|
3820
|
+
explicitEnvelope && Object.keys(explicitEnvelope).length
|
|
3821
|
+
? explicitEnvelope
|
|
3822
|
+
: fallbackEnvelope,
|
|
3823
|
+
{
|
|
3824
|
+
speaker_type: "human",
|
|
3825
|
+
speaker_label: "human",
|
|
3826
|
+
},
|
|
3827
|
+
);
|
|
3729
3828
|
}
|
|
3730
3829
|
|
|
3731
3830
|
function buildRunnerReplyChainSnapshotFromRequestReply(requestRaw) {
|
|
@@ -3734,20 +3833,35 @@ function buildRunnerReplyChainSnapshotFromRequestReply(requestRaw) {
|
|
|
3734
3833
|
if (!preview) {
|
|
3735
3834
|
return null;
|
|
3736
3835
|
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
: "",
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3836
|
+
const explicitEnvelope = normalizeRunnerTelegramMessageEnvelope(
|
|
3837
|
+
request.last_reply_message_envelope || request.lastReplyMessageEnvelope,
|
|
3838
|
+
);
|
|
3839
|
+
const fallbackEnvelope = intFromRawAllowZero(request.last_reply_message_id, 0) > 0
|
|
3840
|
+
? buildTelegramBotReplyEnvelope({
|
|
3841
|
+
chatID: request.chat_id,
|
|
3842
|
+
messageID: request.last_reply_message_id,
|
|
3843
|
+
messageThreadID: request.last_reply_message_thread_id,
|
|
3844
|
+
replyToMessageID: request.last_reply_to_message_id || request.last_source_message_id || request.source_message_id,
|
|
3845
|
+
senderUsername: request.conversation_summary_bot || ensureArray(request.selected_bot_usernames)[0] || "",
|
|
3846
|
+
body: preview,
|
|
3847
|
+
})
|
|
3848
|
+
: null;
|
|
3849
|
+
return buildRunnerReplyChainSnapshotFromMessageEnvelope(
|
|
3850
|
+
explicitEnvelope && intFromRawAllowZero(explicitEnvelope.message_id, 0) > 0
|
|
3851
|
+
? explicitEnvelope
|
|
3852
|
+
: fallbackEnvelope,
|
|
3853
|
+
{
|
|
3854
|
+
speaker_type: "bot",
|
|
3855
|
+
speaker_label: firstNonEmptyString([
|
|
3856
|
+
request.conversation_summary_bot ? `@${String(request.conversation_summary_bot || "").trim().replace(/^@+/, "")}` : "",
|
|
3857
|
+
ensureArray(request.selected_bot_usernames)[0]
|
|
3858
|
+
? `@${String(ensureArray(request.selected_bot_usernames)[0] || "").trim().replace(/^@+/, "")}`
|
|
3859
|
+
: "",
|
|
3860
|
+
"bot",
|
|
3861
|
+
]),
|
|
3862
|
+
body: preview,
|
|
3863
|
+
},
|
|
3864
|
+
);
|
|
3751
3865
|
}
|
|
3752
3866
|
|
|
3753
3867
|
function uniqueRunnerReplyChainSnapshots(snapshots, limit = 4) {
|
|
@@ -4361,6 +4475,7 @@ async function claimRunnerRequestForHumanComment({
|
|
|
4361
4475
|
source_message_id: intFromRawAllowZero(parsed.messageID, 0) || undefined,
|
|
4362
4476
|
source_message_thread_id: intFromRawAllowZero(parsed.messageThreadID, 0) || undefined,
|
|
4363
4477
|
source_message_body: String(parsed.body || "").trim(),
|
|
4478
|
+
source_message_envelope: buildRunnerTelegramMessageEnvelopeFromParsedArchive(parsed),
|
|
4364
4479
|
root_comment_id: String(selectedRecord?.id || "").trim(),
|
|
4365
4480
|
root_comment_kind: commentKind,
|
|
4366
4481
|
conversation_id: resolvedConversationID,
|
|
@@ -4971,7 +5086,7 @@ function buildRunnerRootWorkItemTransitionPath(currentStatusRaw, targetStatusRaw
|
|
|
4971
5086
|
return [];
|
|
4972
5087
|
}
|
|
4973
5088
|
|
|
4974
|
-
function buildRunnerRouteFollowupSnapshotPatch(selectedRecordRaw, resultRaw = {}) {
|
|
5089
|
+
function buildRunnerRouteFollowupSnapshotPatch(selectedRecordRaw, resultRaw = {}) {
|
|
4975
5090
|
const parsed = safeObject(safeObject(selectedRecordRaw).parsedArchive);
|
|
4976
5091
|
const commentKind = String(parsed.kind || "").trim().toLowerCase();
|
|
4977
5092
|
if (["telegram_message", "telegram_edited_message"].includes(commentKind)) {
|
|
@@ -5010,12 +5125,15 @@ function buildRunnerRouteFollowupSnapshotPatch(selectedRecordRaw, resultRaw = {}
|
|
|
5010
5125
|
ensureArray(result.assignment_validation_modes),
|
|
5011
5126
|
(value) => String(value || "").trim().toLowerCase(),
|
|
5012
5127
|
),
|
|
5013
|
-
last_followup_delivery_status: String(result.delivery_status || "").trim().toLowerCase(),
|
|
5014
|
-
last_followup_archive_status: String(result.archive_status || "").trim().toLowerCase(),
|
|
5015
|
-
last_followup_transport_error: String(result.transport_error || "").trim(),
|
|
5016
|
-
last_followup_archive_error: String(result.archive_error || "").trim(),
|
|
5017
|
-
|
|
5018
|
-
|
|
5128
|
+
last_followup_delivery_status: String(result.delivery_status || "").trim().toLowerCase(),
|
|
5129
|
+
last_followup_archive_status: String(result.archive_status || "").trim().toLowerCase(),
|
|
5130
|
+
last_followup_transport_error: String(result.transport_error || "").trim(),
|
|
5131
|
+
last_followup_archive_error: String(result.archive_error || "").trim(),
|
|
5132
|
+
last_followup_source_message_envelope: normalizeRunnerTelegramMessageEnvelope(result.source_message_envelope),
|
|
5133
|
+
last_followup_last_reply_message_envelope: normalizeRunnerTelegramMessageEnvelope(result.last_reply_message_envelope),
|
|
5134
|
+
last_followup_attempted_delivery_envelope: normalizeRunnerTelegramMessageEnvelope(result.attempted_delivery_envelope),
|
|
5135
|
+
});
|
|
5136
|
+
}
|
|
5019
5137
|
|
|
5020
5138
|
function buildRunnerRequestRecoveryPatchFromRouteState(currentStateRaw, requestRaw, routeKeyHint = "") {
|
|
5021
5139
|
const currentState = safeObject(currentStateRaw);
|
|
@@ -5095,11 +5213,29 @@ function buildRunnerRequestRecoveryPatchFromRouteState(currentStateRaw, requestR
|
|
|
5095
5213
|
setFollowupStringPatch("followup_assignment_validation_status", ["last_followup_assignment_validation_status", "last_assignment_validation_status"]);
|
|
5096
5214
|
setFollowupStringPatch("followup_assignment_validation_reason", ["last_followup_assignment_validation_reason", "last_assignment_validation_reason"]);
|
|
5097
5215
|
setFollowupArrayPatch("followup_assignment_validation_modes", ["last_followup_assignment_validation_modes"], (value) => String(value || "").trim().toLowerCase());
|
|
5098
|
-
setFollowupStringPatch("followup_delivery_status", ["last_followup_delivery_status"]);
|
|
5099
|
-
setFollowupStringPatch("followup_archive_status", ["last_followup_archive_status"]);
|
|
5100
|
-
setFollowupStringPatch("followup_transport_error", ["last_followup_transport_error"]);
|
|
5101
|
-
setFollowupStringPatch("followup_archive_error", ["last_followup_archive_error"]);
|
|
5102
|
-
|
|
5216
|
+
setFollowupStringPatch("followup_delivery_status", ["last_followup_delivery_status"]);
|
|
5217
|
+
setFollowupStringPatch("followup_archive_status", ["last_followup_archive_status"]);
|
|
5218
|
+
setFollowupStringPatch("followup_transport_error", ["last_followup_transport_error"]);
|
|
5219
|
+
setFollowupStringPatch("followup_archive_error", ["last_followup_archive_error"]);
|
|
5220
|
+
if (!Object.keys(safeObject(request.source_message_envelope)).length) {
|
|
5221
|
+
const recoveredSourceEnvelope = normalizeRunnerTelegramMessageEnvelope(routeState.last_followup_source_message_envelope);
|
|
5222
|
+
if (Object.keys(recoveredSourceEnvelope).length) {
|
|
5223
|
+
patch.source_message_envelope = recoveredSourceEnvelope;
|
|
5224
|
+
}
|
|
5225
|
+
}
|
|
5226
|
+
if (!Object.keys(safeObject(request.last_reply_message_envelope)).length) {
|
|
5227
|
+
const recoveredReplyEnvelope = normalizeRunnerTelegramMessageEnvelope(routeState.last_followup_last_reply_message_envelope);
|
|
5228
|
+
if (Object.keys(recoveredReplyEnvelope).length) {
|
|
5229
|
+
patch.last_reply_message_envelope = recoveredReplyEnvelope;
|
|
5230
|
+
}
|
|
5231
|
+
}
|
|
5232
|
+
if (!Object.keys(safeObject(request.attempted_delivery_envelope)).length) {
|
|
5233
|
+
const recoveredAttemptEnvelope = normalizeRunnerTelegramMessageEnvelope(routeState.last_followup_attempted_delivery_envelope);
|
|
5234
|
+
if (Object.keys(recoveredAttemptEnvelope).length) {
|
|
5235
|
+
patch.attempted_delivery_envelope = recoveredAttemptEnvelope;
|
|
5236
|
+
}
|
|
5237
|
+
}
|
|
5238
|
+
const requestStatus = normalizeRunnerRequestStatus(request.status);
|
|
5103
5239
|
if (!isFinalRunnerRequestStatus(requestStatus)) {
|
|
5104
5240
|
const routeAction = String(routeState.last_action || "").trim().toLowerCase();
|
|
5105
5241
|
if (routeAction === "replied") {
|
|
@@ -5432,19 +5568,50 @@ function markRunnerRequestLifecycle({
|
|
|
5432
5568
|
const key = String(requestKey || "").trim();
|
|
5433
5569
|
if (!key) return null;
|
|
5434
5570
|
const currentState = loadBotRunnerState();
|
|
5435
|
-
const existing = safeObject(normalizeBotRunnerRequests(currentState.requests)[key]);
|
|
5436
|
-
if (!Object.keys(existing).length) return null;
|
|
5437
|
-
const parsed = safeObject(selectedRecord?.parsedArchive);
|
|
5438
|
-
const
|
|
5439
|
-
const
|
|
5571
|
+
const existing = safeObject(normalizeBotRunnerRequests(currentState.requests)[key]);
|
|
5572
|
+
if (!Object.keys(existing).length) return null;
|
|
5573
|
+
const parsed = safeObject(selectedRecord?.parsedArchive);
|
|
5574
|
+
const parsedKind = String(parsed.kind || "").trim().toLowerCase();
|
|
5575
|
+
const conversationID = String(conversationIDRaw || existing.conversation_id || parsed.conversationID || "").trim();
|
|
5576
|
+
const normalizedCurrentBotSelector = normalizeTelegramMentionUsername(
|
|
5440
5577
|
currentBotSelector
|
|
5441
5578
|
|| safeObject(currentState.routes)[String(routeKey || "").trim()]?.last_speaker_bot_username
|
|
5442
|
-
|| "",
|
|
5443
|
-
);
|
|
5444
|
-
const
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5579
|
+
|| "",
|
|
5580
|
+
);
|
|
5581
|
+
const sourceMessageEnvelope = buildRunnerTelegramMessageEnvelopeFromParsedArchive(parsed);
|
|
5582
|
+
const effectiveReplyToMessageID = intFromRawAllowZero(
|
|
5583
|
+
replyToMessageID,
|
|
5584
|
+
intFromRawAllowZero(existing.last_reply_to_message_id, 0),
|
|
5585
|
+
);
|
|
5586
|
+
const lastReplyMessageEnvelope = buildTelegramBotReplyEnvelope({
|
|
5587
|
+
sourceEnvelope: sourceMessageEnvelope,
|
|
5588
|
+
chatID: existing.chat_id,
|
|
5589
|
+
messageID: lastReplyMessageID,
|
|
5590
|
+
messageThreadID: lastReplyMessageThreadID,
|
|
5591
|
+
replyToMessageID: effectiveReplyToMessageID,
|
|
5592
|
+
senderUsername: normalizedCurrentBotSelector,
|
|
5593
|
+
body: aiReplyPreview,
|
|
5594
|
+
});
|
|
5595
|
+
const attemptedDeliveryEnvelope = buildTelegramBotReplyEnvelope({
|
|
5596
|
+
sourceEnvelope: sourceMessageEnvelope,
|
|
5597
|
+
chatID: existing.chat_id,
|
|
5598
|
+
messageThreadID: lastReplyMessageThreadID,
|
|
5599
|
+
replyToMessageID: effectiveReplyToMessageID,
|
|
5600
|
+
senderUsername: normalizedCurrentBotSelector,
|
|
5601
|
+
body: aiReplyPreview,
|
|
5602
|
+
});
|
|
5603
|
+
const shouldRefreshAttemptedDeliveryEnvelope = (
|
|
5604
|
+
aiReplyGenerated === true
|
|
5605
|
+
|| String(aiReplyPreview || "").trim().length > 0
|
|
5606
|
+
|| String(deliveryStatus || "").trim().length > 0
|
|
5607
|
+
|| String(transportError || "").trim().length > 0
|
|
5608
|
+
|| intFromRawAllowZero(replyToMessageID, 0) > 0
|
|
5609
|
+
|| intFromRawAllowZero(lastReplyMessageThreadID, 0) > 0
|
|
5610
|
+
);
|
|
5611
|
+
const rootEffectiveExecutionContractTargets = uniqueOrderedStrings(
|
|
5612
|
+
[
|
|
5613
|
+
...ensureArray(executionContractTargets),
|
|
5614
|
+
...ensureArray(normalizedExecutionContractTargets),
|
|
5448
5615
|
...ensureArray(responseContractValidationTargets),
|
|
5449
5616
|
],
|
|
5450
5617
|
normalizeTelegramMentionUsername,
|
|
@@ -5779,9 +5946,17 @@ function markRunnerRequestLifecycle({
|
|
|
5779
5946
|
closed_at: (nextStatus === "closed" || nextStatus === "expired" || nextStatus === "loop_closed")
|
|
5780
5947
|
? nowISO
|
|
5781
5948
|
: String(existing.closed_at || "").trim(),
|
|
5782
|
-
closed_reason: (nextStatus === "closed" || nextStatus === "expired" || nextStatus === "loop_closed")
|
|
5783
|
-
? String(closedReason || existing.closed_reason || normalizedOutcome).trim()
|
|
5784
|
-
: String(existing.closed_reason || "").trim(),
|
|
5949
|
+
closed_reason: (nextStatus === "closed" || nextStatus === "expired" || nextStatus === "loop_closed")
|
|
5950
|
+
? String(closedReason || existing.closed_reason || normalizedOutcome).trim()
|
|
5951
|
+
: String(existing.closed_reason || "").trim(),
|
|
5952
|
+
source_message_body: parsedKind === "bot_reply"
|
|
5953
|
+
? String(existing.source_message_body || "").trim()
|
|
5954
|
+
: String(parsed.body || existing.source_message_body || "").trim(),
|
|
5955
|
+
source_message_envelope: parsedKind === "bot_reply"
|
|
5956
|
+
? safeObject(existing.source_message_envelope)
|
|
5957
|
+
: Object.keys(sourceMessageEnvelope).length
|
|
5958
|
+
? sourceMessageEnvelope
|
|
5959
|
+
: safeObject(existing.source_message_envelope),
|
|
5785
5960
|
last_comment_id: String(selectedRecord?.id || existing.last_comment_id || "").trim(),
|
|
5786
5961
|
last_comment_kind: String(parsed.kind || existing.last_comment_kind || "").trim().toLowerCase(),
|
|
5787
5962
|
last_source_message_id: intFromRawAllowZero(parsed.messageID, 0) || existing.last_source_message_id,
|
|
@@ -5789,6 +5964,12 @@ function markRunnerRequestLifecycle({
|
|
|
5789
5964
|
last_reply_message_id: intFromRawAllowZero(lastReplyMessageID, 0) || existing.last_reply_message_id,
|
|
5790
5965
|
last_reply_message_thread_id: intFromRawAllowZero(lastReplyMessageThreadID, 0) || existing.last_reply_message_thread_id,
|
|
5791
5966
|
last_reply_to_message_id: intFromRawAllowZero(replyToMessageID, 0) || existing.last_reply_to_message_id,
|
|
5967
|
+
last_reply_message_envelope: intFromRawAllowZero(lastReplyMessageEnvelope.message_id, 0) > 0
|
|
5968
|
+
? lastReplyMessageEnvelope
|
|
5969
|
+
: safeObject(existing.last_reply_message_envelope),
|
|
5970
|
+
attempted_delivery_envelope: shouldRefreshAttemptedDeliveryEnvelope
|
|
5971
|
+
? attemptedDeliveryEnvelope
|
|
5972
|
+
: safeObject(existing.attempted_delivery_envelope),
|
|
5792
5973
|
last_reply_fallback_used: replyFallbackUsed === true
|
|
5793
5974
|
? true
|
|
5794
5975
|
: existing.last_reply_fallback_used === true,
|
|
@@ -5997,6 +6178,9 @@ function mergeRunnerRequestForServerHydration(localEntryRaw, serverEntryRaw) {
|
|
|
5997
6178
|
}
|
|
5998
6179
|
};
|
|
5999
6180
|
preserveLocalStringWhenServerBlank("source_message_body");
|
|
6181
|
+
preserveLocalObjectWhenServerBlank("source_message_envelope");
|
|
6182
|
+
preserveLocalObjectWhenServerBlank("last_reply_message_envelope");
|
|
6183
|
+
preserveLocalObjectWhenServerBlank("attempted_delivery_envelope");
|
|
6000
6184
|
preserveLocalStringWhenServerBlank("conversation_id");
|
|
6001
6185
|
preserveLocalStringWhenServerBlank("conversation_intent_mode");
|
|
6002
6186
|
preserveLocalStringWhenServerBlank("conversation_lead_bot");
|
|
@@ -8444,22 +8628,25 @@ function summarizeRunnerRequestForStatusLookup(entryRaw) {
|
|
|
8444
8628
|
updated_at: String(entry.updated_at || "").trim(),
|
|
8445
8629
|
source_message_id: intFromRawAllowZero(entry.source_message_id, 0) || undefined,
|
|
8446
8630
|
last_source_message_id: intFromRawAllowZero(entry.last_source_message_id, 0) || undefined,
|
|
8447
|
-
...buildRunnerValidationAndDeliverySummary({
|
|
8448
|
-
aiReplyPreview: runnerRequestPreferredAIReplyPreview(entry),
|
|
8449
|
-
executionContractType: runnerRequestPreferredExecutionContractType(entry),
|
|
8450
|
-
executionContractTargets: runnerRequestPreferredExecutionContractTargets(entry),
|
|
8451
|
-
nextExpectedResponders: runnerRequestPreferredNextExpectedResponders(entry),
|
|
8631
|
+
...buildRunnerValidationAndDeliverySummary({
|
|
8632
|
+
aiReplyPreview: runnerRequestPreferredAIReplyPreview(entry),
|
|
8633
|
+
executionContractType: runnerRequestPreferredExecutionContractType(entry),
|
|
8634
|
+
executionContractTargets: runnerRequestPreferredExecutionContractTargets(entry),
|
|
8635
|
+
nextExpectedResponders: runnerRequestPreferredNextExpectedResponders(entry),
|
|
8452
8636
|
responseContractValidationStatus: runnerRequestPreferredResponseContractValidationStatus(entry),
|
|
8453
8637
|
responseContractValidationReason: runnerRequestPreferredResponseContractValidationReason(entry),
|
|
8454
8638
|
responseContractValidationTargets: runnerRequestPreferredResponseContractValidationTargets(entry),
|
|
8455
8639
|
assignmentValidationStatus: runnerRequestPreferredAssignmentValidationStatus(entry),
|
|
8456
8640
|
assignmentValidationReason: runnerRequestPreferredAssignmentValidationReason(entry),
|
|
8457
8641
|
assignmentValidationModes: runnerRequestPreferredAssignmentValidationModes(entry),
|
|
8458
|
-
deliveryStatus: runnerRequestPreferredDeliveryStatus(entry),
|
|
8459
|
-
archiveStatus: runnerRequestPreferredArchiveStatus(entry),
|
|
8460
|
-
transportError: runnerRequestPreferredTransportError(entry),
|
|
8461
|
-
archiveError: runnerRequestPreferredArchiveError(entry),
|
|
8462
|
-
|
|
8642
|
+
deliveryStatus: runnerRequestPreferredDeliveryStatus(entry),
|
|
8643
|
+
archiveStatus: runnerRequestPreferredArchiveStatus(entry),
|
|
8644
|
+
transportError: runnerRequestPreferredTransportError(entry),
|
|
8645
|
+
archiveError: runnerRequestPreferredArchiveError(entry),
|
|
8646
|
+
sourceMessageEnvelope: entry.source_message_envelope,
|
|
8647
|
+
lastReplyMessageEnvelope: entry.last_reply_message_envelope,
|
|
8648
|
+
attemptedDeliveryEnvelope: entry.attempted_delivery_envelope,
|
|
8649
|
+
}),
|
|
8463
8650
|
selected_bot_usernames: ensureArray(entry.selected_bot_usernames)
|
|
8464
8651
|
.map((value) => normalizeTelegramMentionUsername(value))
|
|
8465
8652
|
.filter(Boolean),
|
|
@@ -8569,10 +8756,10 @@ function resolveRunnerStatusLookupRequests({
|
|
|
8569
8756
|
|
|
8570
8757
|
function buildRunnerShowLastRunPayload(lastRunSummaryRaw) {
|
|
8571
8758
|
const lastRunSummary = safeObject(lastRunSummaryRaw);
|
|
8572
|
-
return {
|
|
8573
|
-
action: lastRunSummary.action || "-",
|
|
8574
|
-
reason: lastRunSummary.reason || "-",
|
|
8575
|
-
intent_type: lastRunSummary.intent_type || "-",
|
|
8759
|
+
return {
|
|
8760
|
+
action: lastRunSummary.action || "-",
|
|
8761
|
+
reason: lastRunSummary.reason || "-",
|
|
8762
|
+
intent_type: lastRunSummary.intent_type || "-",
|
|
8576
8763
|
ai_reply_preview: lastRunSummary.ai_reply_preview || "-",
|
|
8577
8764
|
execution_contract_type: lastRunSummary.execution_contract_type || "-",
|
|
8578
8765
|
execution_contract_targets: ensureArray(lastRunSummary.execution_contract_targets),
|
|
@@ -8585,10 +8772,13 @@ function buildRunnerShowLastRunPayload(lastRunSummaryRaw) {
|
|
|
8585
8772
|
assignment_validation_modes: ensureArray(lastRunSummary.assignment_validation_modes),
|
|
8586
8773
|
delivery_status: lastRunSummary.delivery_status || "-",
|
|
8587
8774
|
archive_status: lastRunSummary.archive_status || "-",
|
|
8588
|
-
transport_error: lastRunSummary.transport_error || "-",
|
|
8589
|
-
archive_error: lastRunSummary.archive_error || "-",
|
|
8590
|
-
|
|
8591
|
-
|
|
8775
|
+
transport_error: lastRunSummary.transport_error || "-",
|
|
8776
|
+
archive_error: lastRunSummary.archive_error || "-",
|
|
8777
|
+
source_message_envelope: safeObject(lastRunSummary.source_message_envelope),
|
|
8778
|
+
last_reply_message_envelope: safeObject(lastRunSummary.last_reply_message_envelope),
|
|
8779
|
+
attempted_delivery_envelope: safeObject(lastRunSummary.attempted_delivery_envelope),
|
|
8780
|
+
workspace_dir: lastRunSummary.workspace_dir || "-",
|
|
8781
|
+
artifact_validation: lastRunSummary.artifact_validation || "-",
|
|
8592
8782
|
artifact_paths: ensureArray(lastRunSummary.artifact_paths),
|
|
8593
8783
|
artifact_errors: ensureArray(lastRunSummary.artifact_errors),
|
|
8594
8784
|
boundary_violations: ensureArray(lastRunSummary.boundary_violations),
|
package/lib/runner-helpers.mjs
CHANGED
|
@@ -31,6 +31,130 @@ function intFromRaw(raw, fallback) {
|
|
|
31
31
|
return parsed > 0 ? parsed : fallback;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
export function normalizeTelegramMessageEnvelope(rawEnvelope) {
|
|
35
|
+
const envelope = safeObject(rawEnvelope);
|
|
36
|
+
const chatID = String(
|
|
37
|
+
envelope.chat_id
|
|
38
|
+
|| envelope.chatID
|
|
39
|
+
|| envelope.chatId
|
|
40
|
+
|| "",
|
|
41
|
+
).trim();
|
|
42
|
+
const messageID = intFromRawAllowZero(envelope.message_id || envelope.messageID, 0);
|
|
43
|
+
const messageThreadID = intFromRawAllowZero(
|
|
44
|
+
envelope.message_thread_id || envelope.messageThreadID,
|
|
45
|
+
0,
|
|
46
|
+
);
|
|
47
|
+
const replyToMessageID = intFromRawAllowZero(
|
|
48
|
+
envelope.reply_to_message_id || envelope.replyToMessageID,
|
|
49
|
+
0,
|
|
50
|
+
);
|
|
51
|
+
const kind = String(envelope.kind || "").trim().toLowerCase();
|
|
52
|
+
const senderUsername = normalizeMentionSelector(
|
|
53
|
+
envelope.sender_username
|
|
54
|
+
|| envelope.senderUsername
|
|
55
|
+
|| envelope.username
|
|
56
|
+
|| envelope.bot_username
|
|
57
|
+
|| envelope.botUsername
|
|
58
|
+
|| "",
|
|
59
|
+
);
|
|
60
|
+
const sender = firstNonEmptyString([
|
|
61
|
+
envelope.sender,
|
|
62
|
+
senderUsername ? `@${senderUsername}` : "",
|
|
63
|
+
]);
|
|
64
|
+
const rawSenderIsBot = envelope.sender_is_bot ?? envelope.senderIsBot;
|
|
65
|
+
const senderIsBot = rawSenderIsBot === true
|
|
66
|
+
|| rawSenderIsBot === "true"
|
|
67
|
+
|| rawSenderIsBot === 1
|
|
68
|
+
|| rawSenderIsBot === "1"
|
|
69
|
+
|| kind === "bot_reply";
|
|
70
|
+
const body = String(envelope.body || envelope.text || "").trim();
|
|
71
|
+
if (
|
|
72
|
+
!chatID
|
|
73
|
+
&& !(messageID > 0)
|
|
74
|
+
&& !(messageThreadID > 0)
|
|
75
|
+
&& !(replyToMessageID > 0)
|
|
76
|
+
&& !kind
|
|
77
|
+
&& !sender
|
|
78
|
+
&& !senderUsername
|
|
79
|
+
&& !body
|
|
80
|
+
) {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
...(chatID ? { chat_id: chatID } : {}),
|
|
85
|
+
...(messageID > 0 ? { message_id: messageID } : {}),
|
|
86
|
+
...(messageThreadID > 0 ? { message_thread_id: messageThreadID } : {}),
|
|
87
|
+
...(replyToMessageID > 0 ? { reply_to_message_id: replyToMessageID } : {}),
|
|
88
|
+
...(kind ? { kind } : {}),
|
|
89
|
+
...(sender ? { sender } : {}),
|
|
90
|
+
...(senderUsername ? { sender_username: senderUsername } : {}),
|
|
91
|
+
sender_is_bot: senderIsBot === true,
|
|
92
|
+
...(body ? { body } : {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function buildTelegramMessageEnvelopeFromParsedArchive(parsedArchiveRaw, overrides = {}) {
|
|
97
|
+
const parsedArchive = safeObject(parsedArchiveRaw);
|
|
98
|
+
return normalizeTelegramMessageEnvelope({
|
|
99
|
+
chat_id: firstNonEmptyString([
|
|
100
|
+
overrides.chat_id,
|
|
101
|
+
parsedArchive.chatID,
|
|
102
|
+
parsedArchive.chatId,
|
|
103
|
+
]),
|
|
104
|
+
message_id: overrides.message_id ?? parsedArchive.messageID,
|
|
105
|
+
message_thread_id: overrides.message_thread_id ?? parsedArchive.messageThreadID,
|
|
106
|
+
reply_to_message_id: overrides.reply_to_message_id ?? parsedArchive.replyToMessageID,
|
|
107
|
+
kind: firstNonEmptyString([overrides.kind, parsedArchive.kind]),
|
|
108
|
+
sender: firstNonEmptyString([
|
|
109
|
+
overrides.sender,
|
|
110
|
+
parsedArchive.sender,
|
|
111
|
+
parsedArchive.botName,
|
|
112
|
+
parsedArchive.replyToSender,
|
|
113
|
+
]),
|
|
114
|
+
sender_username: firstNonEmptyString([
|
|
115
|
+
overrides.sender_username,
|
|
116
|
+
parsedArchive.botUsername,
|
|
117
|
+
parsedArchive.username,
|
|
118
|
+
parsedArchive.replyToUsername,
|
|
119
|
+
]),
|
|
120
|
+
sender_is_bot: overrides.sender_is_bot ?? parsedArchive.senderIsBot,
|
|
121
|
+
body: firstNonEmptyString([overrides.body, parsedArchive.body]),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function buildTelegramBotReplyEnvelope({
|
|
126
|
+
sourceEnvelope: sourceEnvelopeRaw = {},
|
|
127
|
+
chatID = "",
|
|
128
|
+
messageID = 0,
|
|
129
|
+
messageThreadID = 0,
|
|
130
|
+
replyToMessageID = 0,
|
|
131
|
+
sender = "",
|
|
132
|
+
senderUsername = "",
|
|
133
|
+
body = "",
|
|
134
|
+
} = {}) {
|
|
135
|
+
const sourceEnvelope = normalizeTelegramMessageEnvelope(sourceEnvelopeRaw);
|
|
136
|
+
const normalizedSenderUsername = normalizeMentionSelector(senderUsername);
|
|
137
|
+
const senderLabel = firstNonEmptyString([
|
|
138
|
+
sender,
|
|
139
|
+
normalizedSenderUsername ? `@${normalizedSenderUsername}` : "",
|
|
140
|
+
"bot",
|
|
141
|
+
]);
|
|
142
|
+
return normalizeTelegramMessageEnvelope({
|
|
143
|
+
chat_id: firstNonEmptyString([
|
|
144
|
+
chatID,
|
|
145
|
+
sourceEnvelope.chat_id,
|
|
146
|
+
]),
|
|
147
|
+
message_id: intFromRawAllowZero(messageID, 0) || undefined,
|
|
148
|
+
message_thread_id: intFromRawAllowZero(messageThreadID, 0) || undefined,
|
|
149
|
+
reply_to_message_id: intFromRawAllowZero(replyToMessageID, 0) || undefined,
|
|
150
|
+
kind: "bot_reply",
|
|
151
|
+
sender: senderLabel,
|
|
152
|
+
sender_username: normalizedSenderUsername,
|
|
153
|
+
sender_is_bot: true,
|
|
154
|
+
body: String(body || "").trim(),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
34
158
|
function normalizePendingSelectionOptions(rawOptions) {
|
|
35
159
|
const options = safeObject(rawOptions);
|
|
36
160
|
const maxPendingAgeMs = intFromRawAllowZero(options.maxPendingAgeMs, 0);
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import {
|
|
4
|
+
buildTelegramBotReplyEnvelope,
|
|
5
|
+
buildTelegramMessageEnvelopeFromParsedArchive,
|
|
4
6
|
buildRunnerContextWindow,
|
|
5
7
|
buildRunnerRouteStateFromComment,
|
|
6
8
|
compareArchiveCommentRecords,
|
|
7
9
|
dedupeProcessableArchiveComments,
|
|
8
10
|
isInboundArchiveKind,
|
|
11
|
+
normalizeTelegramMessageEnvelope,
|
|
9
12
|
selectPendingArchiveComments,
|
|
10
13
|
} from "./runner-helpers.mjs";
|
|
11
14
|
import {
|
|
@@ -4717,16 +4720,10 @@ export async function processRunnerSelectedRecord({
|
|
|
4717
4720
|
safeObject(persistedHumanIntentRequest).reply_chain_context
|
|
4718
4721
|
|| safeObject(persistedHumanIntentRequest).replyChainContext,
|
|
4719
4722
|
);
|
|
4720
|
-
const
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|| safeObject(authorityReplyChainContext.latest_prior_bot_reply).message_thread_id
|
|
4725
|
-
|| safeObject(persistedHumanIntentRequest).last_source_message_thread_id
|
|
4726
|
-
|| safeObject(persistedHumanIntentRequest).source_message_thread_id
|
|
4727
|
-
|| safeObject(persistedHumanIntentRequest).last_reply_message_thread_id,
|
|
4728
|
-
0,
|
|
4729
|
-
);
|
|
4723
|
+
const sourceMessageEnvelope = buildTelegramMessageEnvelopeFromParsedArchive(selectedRecord?.parsedArchive);
|
|
4724
|
+
const replyMessageThreadID = intFromRawAllowZero(sourceMessageEnvelope.message_thread_id, 0);
|
|
4725
|
+
const replyToMessageID = intFromRawAllowZero(sourceMessageEnvelope.message_id, 0);
|
|
4726
|
+
const replyAnchorSource = replyToMessageID > 0 ? "source_message_envelope" : "";
|
|
4730
4727
|
const normalizedPrecomputedHumanIntentContext = safeObject(precomputedHumanIntentContext);
|
|
4731
4728
|
const validateWorkspaceArtifacts = typeof executionDeps.validateWorkspaceArtifacts === "function"
|
|
4732
4729
|
? executionDeps.validateWorkspaceArtifacts
|
|
@@ -5136,7 +5133,7 @@ export async function processRunnerSelectedRecord({
|
|
|
5136
5133
|
text: replyText,
|
|
5137
5134
|
disableWebPagePreview: true,
|
|
5138
5135
|
messageThreadID: replyMessageThreadID,
|
|
5139
|
-
replyToMessageID
|
|
5136
|
+
replyToMessageID,
|
|
5140
5137
|
archiveReplies: normalizedRoute.archivePolicy.mirrorReplies,
|
|
5141
5138
|
archiveDedupeOutbound: normalizedRoute.archivePolicy.dedupeOutbound,
|
|
5142
5139
|
archiveThreadID: archiveThread.threadID,
|
|
@@ -5488,9 +5485,6 @@ export async function processRunnerSelectedRecord({
|
|
|
5488
5485
|
},
|
|
5489
5486
|
};
|
|
5490
5487
|
}
|
|
5491
|
-
const replyToMessageID = aiResult.replyToMessageID > 0
|
|
5492
|
-
? aiResult.replyToMessageID
|
|
5493
|
-
: intFromRawAllowZero(selectedRecord.parsedArchive?.messageID, 0);
|
|
5494
5488
|
const sanitizedReplyText = sanitizeForcedDirectReplyText({
|
|
5495
5489
|
replyText: aiResult.reply,
|
|
5496
5490
|
bot,
|
|
@@ -5498,6 +5492,14 @@ export async function processRunnerSelectedRecord({
|
|
|
5498
5492
|
triggerDecision: effectiveTriggerDecision,
|
|
5499
5493
|
conversationContext: effectiveConversationContext,
|
|
5500
5494
|
});
|
|
5495
|
+
const attemptedDeliveryEnvelope = buildTelegramBotReplyEnvelope({
|
|
5496
|
+
sourceEnvelope: sourceMessageEnvelope,
|
|
5497
|
+
messageThreadID: replyMessageThreadID,
|
|
5498
|
+
replyToMessageID,
|
|
5499
|
+
sender: bot?.username ? `@${String(bot.username || "").trim().replace(/^@+/, "")}` : String(bot?.name || "bot").trim(),
|
|
5500
|
+
senderUsername: normalizeMentionSelector(bot?.username || bot?.name),
|
|
5501
|
+
body: sanitizedReplyText,
|
|
5502
|
+
});
|
|
5501
5503
|
const normalizedExecutionTargets = ensureArray(executionContract?.assignments)
|
|
5502
5504
|
.map((item) => normalizeMentionSelector(item?.targetBot))
|
|
5503
5505
|
.filter(Boolean);
|
|
@@ -5667,6 +5669,10 @@ export async function processRunnerSelectedRecord({
|
|
|
5667
5669
|
ai_reply_generated: true,
|
|
5668
5670
|
ai_reply_generated_at: aiReplyGeneratedAt,
|
|
5669
5671
|
ai_reply_preview: aiReplyPreview,
|
|
5672
|
+
source_message_envelope: sourceMessageEnvelope,
|
|
5673
|
+
attempted_delivery_envelope: attemptedDeliveryEnvelope,
|
|
5674
|
+
reply_to_message_id: replyToMessageID,
|
|
5675
|
+
reply_message_thread_id: replyMessageThreadID,
|
|
5670
5676
|
delivery_status: "failed_transport",
|
|
5671
5677
|
archive_status: "not_attempted",
|
|
5672
5678
|
transport_error: transportError,
|
|
@@ -5765,6 +5771,7 @@ export async function processRunnerSelectedRecord({
|
|
|
5765
5771
|
0,
|
|
5766
5772
|
),
|
|
5767
5773
|
last_reply_message_thread_id: intFromRawAllowZero(deliveryResult.delivery.effectiveMessageThreadID, replyMessageThreadID),
|
|
5774
|
+
last_reply_anchor_source: replyAnchorSource,
|
|
5768
5775
|
last_contract_validation_status: String(responseContractValidation.status || "").trim(),
|
|
5769
5776
|
last_contract_validation_reason: String(responseContractValidation.reason || "").trim(),
|
|
5770
5777
|
last_contract_validation_targets: ensureArray(responseContractValidation.targets),
|
|
@@ -5873,12 +5880,27 @@ export async function processRunnerSelectedRecord({
|
|
|
5873
5880
|
ai_reply_generated: true,
|
|
5874
5881
|
ai_reply_generated_at: aiReplyGeneratedAt,
|
|
5875
5882
|
ai_reply_preview: aiReplyPreview,
|
|
5883
|
+
source_message_envelope: sourceMessageEnvelope,
|
|
5884
|
+
attempted_delivery_envelope: attemptedDeliveryEnvelope,
|
|
5876
5885
|
last_reply_message_id: intFromRawAllowZero(
|
|
5877
5886
|
safeObject(deliveryResult.delivery.body).result?.message_id ?? safeObject(deliveryResult.delivery.body).message_id,
|
|
5878
5887
|
0,
|
|
5879
5888
|
),
|
|
5880
5889
|
last_reply_message_thread_id: intFromRawAllowZero(deliveryResult.delivery.effectiveMessageThreadID, replyMessageThreadID),
|
|
5881
5890
|
reply_to_message_id: intFromRawAllowZero(deliveryResult.delivery.effectiveReplyToMessageID, replyToMessageID),
|
|
5891
|
+
last_reply_message_envelope: buildTelegramBotReplyEnvelope({
|
|
5892
|
+
sourceEnvelope: sourceMessageEnvelope,
|
|
5893
|
+
messageID: intFromRawAllowZero(
|
|
5894
|
+
safeObject(deliveryResult.delivery.body).result?.message_id ?? safeObject(deliveryResult.delivery.body).message_id,
|
|
5895
|
+
0,
|
|
5896
|
+
),
|
|
5897
|
+
messageThreadID: intFromRawAllowZero(deliveryResult.delivery.effectiveMessageThreadID, replyMessageThreadID),
|
|
5898
|
+
replyToMessageID: intFromRawAllowZero(deliveryResult.delivery.effectiveReplyToMessageID, replyToMessageID),
|
|
5899
|
+
sender: bot?.username ? `@${String(bot.username || "").trim().replace(/^@+/, "")}` : String(bot?.name || "bot").trim(),
|
|
5900
|
+
senderUsername: normalizeMentionSelector(bot?.username || bot?.name),
|
|
5901
|
+
body: sanitizedReplyText,
|
|
5902
|
+
}),
|
|
5903
|
+
reply_anchor_source: replyAnchorSource,
|
|
5882
5904
|
reply_fallback_used: deliveryResult.delivery.replyFallbackUsed === true,
|
|
5883
5905
|
response_contract_validation_status: String(responseContractValidation.status || "").trim(),
|
|
5884
5906
|
response_contract_validation_reason: String(responseContractValidation.reason || "").trim(),
|