metheus-governance-mcp-cli 0.2.269 → 0.2.271
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.
|
@@ -212,6 +212,67 @@ function readOutputFile(filePath) {
|
|
|
212
212
|
return fs.readFileSync(filePath, "utf8");
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
export function looksLikeCodexCliSessionTranscript(rawText = "") {
|
|
216
|
+
const text = String(rawText || "").trim();
|
|
217
|
+
if (!text) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return /OpenAI Codex v|session id:|^workdir:|^model:|^provider:|^approval:|^sandbox:|^reasoning effort:|^--------|^user$|^codex$|mcp:.*\b(starting|ready)\b/i.test(text);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function summarizeCodexCliFailure({
|
|
224
|
+
status = 0,
|
|
225
|
+
stdoutText = "",
|
|
226
|
+
stderrText = "",
|
|
227
|
+
spawnError = null,
|
|
228
|
+
}) {
|
|
229
|
+
const genericMessage = status
|
|
230
|
+
? `Codex CLI exited before returning a final reply (status ${status})`
|
|
231
|
+
: "Codex CLI exited before returning a final reply";
|
|
232
|
+
if (spawnError) {
|
|
233
|
+
const spawnMessage = String(spawnError?.message || spawnError || "").trim();
|
|
234
|
+
return spawnMessage
|
|
235
|
+
? `${genericMessage}: ${spawnMessage}`
|
|
236
|
+
: genericMessage;
|
|
237
|
+
}
|
|
238
|
+
const candidateLines = `${String(stderrText || "")}\n${String(stdoutText || "")}`
|
|
239
|
+
.split(/\r?\n/)
|
|
240
|
+
.map((line) => String(line || "").trim())
|
|
241
|
+
.filter(Boolean)
|
|
242
|
+
.filter((line) => !looksLikeCodexCliSessionTranscript(line))
|
|
243
|
+
.filter((line) => /(error|failed|timeout|timed out|denied|missing|unavailable|not found|capacity)/i.test(line))
|
|
244
|
+
.slice(0, 2);
|
|
245
|
+
return candidateLines.length
|
|
246
|
+
? `${genericMessage}: ${candidateLines.join(" | ")}`
|
|
247
|
+
: genericMessage;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function resolveCodexRawTextProcessResult({
|
|
251
|
+
outputText = "",
|
|
252
|
+
stdoutText = "",
|
|
253
|
+
stderrText = "",
|
|
254
|
+
status = 0,
|
|
255
|
+
spawnError = null,
|
|
256
|
+
}) {
|
|
257
|
+
const normalizedOutputText = String(outputText || "").trim();
|
|
258
|
+
if (normalizedOutputText && !looksLikeCodexCliSessionTranscript(normalizedOutputText)) {
|
|
259
|
+
return normalizedOutputText;
|
|
260
|
+
}
|
|
261
|
+
const normalizedStdoutText = String(stdoutText || "").trim();
|
|
262
|
+
if (normalizedStdoutText && !looksLikeCodexCliSessionTranscript(normalizedStdoutText)) {
|
|
263
|
+
return normalizedStdoutText;
|
|
264
|
+
}
|
|
265
|
+
if (spawnError || status !== 0) {
|
|
266
|
+
throw new Error(summarizeCodexCliFailure({
|
|
267
|
+
status,
|
|
268
|
+
stdoutText: normalizedStdoutText,
|
|
269
|
+
stderrText,
|
|
270
|
+
spawnError,
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
throw new Error("Codex CLI did not return a usable final reply");
|
|
274
|
+
}
|
|
275
|
+
|
|
215
276
|
function tryParseEmbeddedJsonObject(text) {
|
|
216
277
|
const raw = String(text || "").trim();
|
|
217
278
|
if (!raw) return null;
|
|
@@ -686,13 +747,13 @@ function runCodexRawText({ promptText, workspaceDir, model, permissionMode, reas
|
|
|
686
747
|
maxBuffer: 8 * 1024 * 1024,
|
|
687
748
|
},
|
|
688
749
|
);
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
750
|
+
return resolveCodexRawTextProcessResult({
|
|
751
|
+
outputText: readOutputFile(outputPath),
|
|
752
|
+
stdoutText: String(result.stdout || ""),
|
|
753
|
+
stderrText: String(result.stderr || ""),
|
|
754
|
+
status: Number.isInteger(result.status) ? result.status : 0,
|
|
755
|
+
spawnError: result.error || null,
|
|
756
|
+
});
|
|
696
757
|
} finally {
|
|
697
758
|
if (fs.existsSync(outputPath)) {
|
|
698
759
|
fs.rmSync(outputPath, { force: true });
|
package/lib/runner-helpers.mjs
CHANGED
|
@@ -254,12 +254,24 @@ function normalizePendingSelectionOptions(rawOptions) {
|
|
|
254
254
|
};
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
+
function resolveArchiveRecordEventTime(record) {
|
|
258
|
+
const normalizedRecord = safeObject(record);
|
|
259
|
+
const parsedArchive = safeObject(normalizedRecord.parsedArchive);
|
|
260
|
+
return firstNonEmptyString([
|
|
261
|
+
normalizedRecord.sourceOccurredAt,
|
|
262
|
+
parsedArchive.occurredAt,
|
|
263
|
+
parsedArchive.occurred_at,
|
|
264
|
+
normalizedRecord.createdAt,
|
|
265
|
+
normalizedRecord.updatedAt,
|
|
266
|
+
]);
|
|
267
|
+
}
|
|
268
|
+
|
|
257
269
|
function isArchiveRecordWithinPendingAgeLimit(record, rawOptions) {
|
|
258
270
|
const options = normalizePendingSelectionOptions(rawOptions);
|
|
259
271
|
if (!(options.maxPendingAgeMs > 0)) {
|
|
260
272
|
return true;
|
|
261
273
|
}
|
|
262
|
-
const recordTime = Date.parse(
|
|
274
|
+
const recordTime = Date.parse(resolveArchiveRecordEventTime(record));
|
|
263
275
|
if (!Number.isFinite(recordTime)) {
|
|
264
276
|
return true;
|
|
265
277
|
}
|
|
@@ -411,8 +423,8 @@ function contextRelatednessScore(record, selectedRecord, rawOptions) {
|
|
|
411
423
|
}
|
|
412
424
|
|
|
413
425
|
export function compareArchiveCommentRecords(left, right) {
|
|
414
|
-
const leftTime =
|
|
415
|
-
const rightTime =
|
|
426
|
+
const leftTime = resolveArchiveRecordEventTime(left);
|
|
427
|
+
const rightTime = resolveArchiveRecordEventTime(right);
|
|
416
428
|
if (leftTime && rightTime && leftTime !== rightTime) {
|
|
417
429
|
return leftTime < rightTime ? -1 : 1;
|
|
418
430
|
}
|
|
@@ -521,13 +533,18 @@ export function buildRunnerRouteStateFromComment(record, patch = {}) {
|
|
|
521
533
|
export function normalizeArchiveCommentRecord(rawComment, parseArchivedChatComment) {
|
|
522
534
|
const comment = safeObject(rawComment);
|
|
523
535
|
const body = String(comment.body || "").trim();
|
|
536
|
+
const parsedArchive = typeof parseArchivedChatComment === "function" ? parseArchivedChatComment(body) : null;
|
|
524
537
|
return {
|
|
525
538
|
id: String(comment.id || "").trim(),
|
|
526
539
|
body,
|
|
527
540
|
createdAt: firstNonEmptyString([comment.created_at, comment.createdAt, comment.updated_at, comment.updatedAt]),
|
|
528
541
|
updatedAt: firstNonEmptyString([comment.updated_at, comment.updatedAt]),
|
|
529
542
|
authorUserID: firstNonEmptyString([comment.author_user_id, comment.authorUserId, comment.created_by]),
|
|
530
|
-
|
|
543
|
+
sourceOccurredAt: firstNonEmptyString([
|
|
544
|
+
safeObject(parsedArchive).occurredAt,
|
|
545
|
+
safeObject(parsedArchive).occurred_at,
|
|
546
|
+
]),
|
|
547
|
+
parsedArchive,
|
|
531
548
|
};
|
|
532
549
|
}
|
|
533
550
|
|
|
@@ -51,6 +51,48 @@ function detectDirectedManagedReplyTarget({
|
|
|
51
51
|
return "";
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
const DIRECTED_MANAGED_REPLY_ENGLISH_ACTION_PATTERN = "\\b(?:say|tell|greet|reply|answer|introduce|mention)\\b";
|
|
55
|
+
const DIRECTED_MANAGED_REPLY_KOREAN_ACTION_PATTERN = "(?:\\uC778\\uC0AC|\\uB9D0|\\uC804\\uB2EC|\\uB2F5|\\uC18C\\uAC1C|\\uC5B8\\uAE09)";
|
|
56
|
+
const DIRECTED_MANAGED_REPLY_ACTION_PATTERN = `(?:${DIRECTED_MANAGED_REPLY_ENGLISH_ACTION_PATTERN}|${DIRECTED_MANAGED_REPLY_KOREAN_ACTION_PATTERN})`;
|
|
57
|
+
const DIRECTED_MANAGED_REPLY_POSTPOSITION_PATTERN = "(?:\\uC5D0\\uAC8C|\\uD55C\\uD14C|\\uAED8|\\uBCF4\\uACE0)";
|
|
58
|
+
|
|
59
|
+
function detectDirectedManagedReplyTargetV2({
|
|
60
|
+
text,
|
|
61
|
+
currentBotSelector = "",
|
|
62
|
+
managedMentions = [],
|
|
63
|
+
}) {
|
|
64
|
+
const normalizedText = String(text || "").trim();
|
|
65
|
+
const currentSelector = String(currentBotSelector || "").trim().toLowerCase();
|
|
66
|
+
if (!normalizedText || !currentSelector) {
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
const instructionPattern = new RegExp(DIRECTED_MANAGED_REPLY_ACTION_PATTERN, "iu");
|
|
70
|
+
if (!instructionPattern.test(normalizedText)) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
const candidates = ensureArray(managedMentions)
|
|
74
|
+
.map((item) => String(item || "").trim().toLowerCase())
|
|
75
|
+
.filter((item) => item && item !== currentSelector);
|
|
76
|
+
for (const selector of candidates) {
|
|
77
|
+
const escapedSelector = escapeRegexText(String(selector || "").replace(/^@+/, ""));
|
|
78
|
+
const explicitTargetPattern = new RegExp(
|
|
79
|
+
`(?:@${escapedSelector}\\s*(?:${DIRECTED_MANAGED_REPLY_POSTPOSITION_PATTERN})?|(?:to|for)\\s+@${escapedSelector}\\b)`,
|
|
80
|
+
"iu",
|
|
81
|
+
);
|
|
82
|
+
if (explicitTargetPattern.test(normalizedText)) {
|
|
83
|
+
return selector;
|
|
84
|
+
}
|
|
85
|
+
const instructionWindowPattern = new RegExp(
|
|
86
|
+
`@${escapedSelector}(?:\\s*(?:${DIRECTED_MANAGED_REPLY_POSTPOSITION_PATTERN}))?(?:[^@\\n]{0,32}?)${DIRECTED_MANAGED_REPLY_ACTION_PATTERN}`,
|
|
87
|
+
"iu",
|
|
88
|
+
);
|
|
89
|
+
if (instructionWindowPattern.test(normalizedText)) {
|
|
90
|
+
return selector;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return "";
|
|
94
|
+
}
|
|
95
|
+
|
|
54
96
|
export async function resolveHumanIntentContext({
|
|
55
97
|
selectedRecord,
|
|
56
98
|
normalizedRoute,
|
|
@@ -118,7 +160,7 @@ export async function resolveHumanIntentContext({
|
|
|
118
160
|
runnerHumanIntentPromises.set(cacheKey, promise);
|
|
119
161
|
}
|
|
120
162
|
let humanIntent = await runnerHumanIntentPromises.get(cacheKey);
|
|
121
|
-
const directedReplyTargetSelector =
|
|
163
|
+
const directedReplyTargetSelector = detectDirectedManagedReplyTargetV2({
|
|
122
164
|
text: parsed.body,
|
|
123
165
|
currentBotSelector,
|
|
124
166
|
managedMentions,
|
|
@@ -85,6 +85,9 @@ import {
|
|
|
85
85
|
import {
|
|
86
86
|
finalizeRunnerRequestRootReferenceRecorderState,
|
|
87
87
|
} from "./runner-recorder-request-root-reference-finalization-handoff.mjs";
|
|
88
|
+
import {
|
|
89
|
+
resolveCodexRawTextProcessResult,
|
|
90
|
+
} from "./local-ai-adapters.mjs";
|
|
88
91
|
import {
|
|
89
92
|
buildRunnerInheritedRootReferenceRecorderResult,
|
|
90
93
|
buildRunnerRootThreadRecorderFailure,
|
|
@@ -737,11 +740,11 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
737
740
|
);
|
|
738
741
|
}
|
|
739
742
|
|
|
740
|
-
try {
|
|
741
|
-
const pendingSelection = selectPendingArchiveComments(
|
|
742
|
-
[
|
|
743
|
-
{
|
|
744
|
-
id: "dup-comment-1",
|
|
743
|
+
try {
|
|
744
|
+
const pendingSelection = selectPendingArchiveComments(
|
|
745
|
+
[
|
|
746
|
+
{
|
|
747
|
+
id: "dup-comment-1",
|
|
745
748
|
createdAt: "2026-03-18T00:00:01.000Z",
|
|
746
749
|
updatedAt: "2026-03-18T00:00:01.000Z",
|
|
747
750
|
parsedArchive: { kind: "telegram_message", chatID: "-1001", messageID: 353, body: "@RyoAI_bot first copy" },
|
|
@@ -767,14 +770,83 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
767
770
|
} catch (err) {
|
|
768
771
|
push(
|
|
769
772
|
"runner_pending_selection_ignores_duplicate_archived_inbound_message_ids",
|
|
770
|
-
false,
|
|
771
|
-
String(err?.message || err),
|
|
772
|
-
);
|
|
773
|
-
}
|
|
774
|
-
|
|
773
|
+
false,
|
|
774
|
+
String(err?.message || err),
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
try {
|
|
779
|
+
const nowMs = Date.parse("2026-03-31T12:00:00.000Z");
|
|
780
|
+
const pendingSelection = selectPendingArchiveComments(
|
|
781
|
+
[
|
|
782
|
+
{
|
|
783
|
+
id: "cursor-comment",
|
|
784
|
+
createdAt: "2026-03-31T11:55:00.000Z",
|
|
785
|
+
updatedAt: "2026-03-31T11:55:00.000Z",
|
|
786
|
+
sourceOccurredAt: "2026-03-31T09:55:00.000Z",
|
|
787
|
+
parsedArchive: {
|
|
788
|
+
kind: "telegram_message",
|
|
789
|
+
chatID: "-1001",
|
|
790
|
+
messageID: 1145,
|
|
791
|
+
occurredAt: "2026-03-31T09:55:00.000Z",
|
|
792
|
+
body: "@RyoAI_bot 기준 댓글",
|
|
793
|
+
},
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
id: "stale-source-comment",
|
|
797
|
+
createdAt: "2026-03-31T11:59:58.000Z",
|
|
798
|
+
updatedAt: "2026-03-31T11:59:58.000Z",
|
|
799
|
+
sourceOccurredAt: "2026-03-31T10:00:00.000Z",
|
|
800
|
+
parsedArchive: {
|
|
801
|
+
kind: "telegram_message",
|
|
802
|
+
chatID: "-1001",
|
|
803
|
+
messageID: 325,
|
|
804
|
+
occurredAt: "2026-03-31T10:00:00.000Z",
|
|
805
|
+
body: "@RyoAI_bot 오래된 하이",
|
|
806
|
+
},
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
id: "fresh-source-comment",
|
|
810
|
+
createdAt: "2026-03-31T11:59:59.000Z",
|
|
811
|
+
updatedAt: "2026-03-31T11:59:59.000Z",
|
|
812
|
+
sourceOccurredAt: "2026-03-31T11:57:00.000Z",
|
|
813
|
+
parsedArchive: {
|
|
814
|
+
kind: "telegram_message",
|
|
815
|
+
chatID: "-1001",
|
|
816
|
+
messageID: 1146,
|
|
817
|
+
occurredAt: "2026-03-31T11:57:00.000Z",
|
|
818
|
+
body: "@RyoAI_bot 최신 하이",
|
|
819
|
+
},
|
|
820
|
+
},
|
|
821
|
+
],
|
|
822
|
+
{
|
|
823
|
+
last_processed_comment_id: "cursor-comment",
|
|
824
|
+
},
|
|
825
|
+
"start",
|
|
826
|
+
(record) => record,
|
|
827
|
+
{
|
|
828
|
+
maxPendingAgeMs: 15 * 60 * 1000,
|
|
829
|
+
nowMs,
|
|
830
|
+
},
|
|
831
|
+
);
|
|
832
|
+
push(
|
|
833
|
+
"runner_pending_selection_uses_source_occurrence_time_for_stale_filtering",
|
|
834
|
+
pendingSelection.pending.length === 1
|
|
835
|
+
&& String(pendingSelection.pending[0]?.id || "") === "fresh-source-comment"
|
|
836
|
+
&& ensureArray(pendingSelection.staleSkipped).some((record) => String(record?.id || "") === "stale-source-comment"),
|
|
837
|
+
`pending=${pendingSelection.pending.map((item) => item.id).join(",") || "(none)"} stale=${ensureArray(pendingSelection.staleSkipped).map((item) => item.id).join(",") || "(none)"}`,
|
|
838
|
+
);
|
|
839
|
+
} catch (err) {
|
|
840
|
+
push(
|
|
841
|
+
"runner_pending_selection_uses_source_occurrence_time_for_stale_filtering",
|
|
842
|
+
false,
|
|
843
|
+
String(err?.message || err),
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
|
|
775
847
|
try {
|
|
776
848
|
const duplicateComments = [
|
|
777
|
-
{
|
|
849
|
+
{
|
|
778
850
|
id: "dup-comment-earliest",
|
|
779
851
|
createdAt: "2026-03-18T00:00:01.000Z",
|
|
780
852
|
updatedAt: "2026-03-18T00:00:01.000Z",
|
|
@@ -3222,15 +3294,76 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
3222
3294
|
&& aliasHumanIntentContext?.reusedPersistedContract === true,
|
|
3223
3295
|
`managedMentions=${JSON.stringify(ensureArray(aliasHumanIntentContext?.managedMentions))} reused=${String(aliasHumanIntentContext?.reusedPersistedContract)}`,
|
|
3224
3296
|
);
|
|
3225
|
-
} catch (err) {
|
|
3226
|
-
push(
|
|
3227
|
-
"runner_human_intent_context_ignores_raw_alias_selector_for_managed_mentions",
|
|
3228
|
-
false,
|
|
3229
|
-
String(err?.message || err),
|
|
3230
|
-
);
|
|
3231
|
-
}
|
|
3232
|
-
|
|
3233
|
-
|
|
3297
|
+
} catch (err) {
|
|
3298
|
+
push(
|
|
3299
|
+
"runner_human_intent_context_ignores_raw_alias_selector_for_managed_mentions",
|
|
3300
|
+
false,
|
|
3301
|
+
String(err?.message || err),
|
|
3302
|
+
);
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
try {
|
|
3306
|
+
const replyTargetIntentContext = await resolveHumanIntentContext({
|
|
3307
|
+
selectedRecord: {
|
|
3308
|
+
id: "comment-directed-reply-target-korean",
|
|
3309
|
+
parsedArchive: {
|
|
3310
|
+
kind: "telegram_message",
|
|
3311
|
+
body: "@RyoAI_bot 너가 @SangHoon01_bot 인사 시켜봐",
|
|
3312
|
+
senderIsBot: false,
|
|
3313
|
+
},
|
|
3314
|
+
},
|
|
3315
|
+
normalizedRoute: {
|
|
3316
|
+
name: "telegram-monitor-ryoai-bot-2",
|
|
3317
|
+
},
|
|
3318
|
+
bot: {
|
|
3319
|
+
username: "ryoai_bot",
|
|
3320
|
+
name: "RyoAI_bot",
|
|
3321
|
+
},
|
|
3322
|
+
executionPlan: {},
|
|
3323
|
+
deps: {
|
|
3324
|
+
resolveConversationPeerBots: () => [
|
|
3325
|
+
{ id: "bot-self-1", name: "RyoAI_bot" },
|
|
3326
|
+
{ id: "bot-peer-1", name: "SangHoon01_bot" },
|
|
3327
|
+
],
|
|
3328
|
+
},
|
|
3329
|
+
intentDeps: {
|
|
3330
|
+
normalizeMentionSelector: normalizeSelftestMentionSelector,
|
|
3331
|
+
buildConversationPeerMap: (_bot, _route, runtimeDeps) => new Map(
|
|
3332
|
+
ensureArray(runtimeDeps?.resolveConversationPeerBots?.() || []).map((item) => {
|
|
3333
|
+
const selector = normalizeSelftestMentionSelector(item?.name || item?.username);
|
|
3334
|
+
return [selector, item];
|
|
3335
|
+
}).filter(([selector]) => selector),
|
|
3336
|
+
),
|
|
3337
|
+
extractOrderedMentionSelectors: (text) => Array.from(String(text || "").matchAll(/@([A-Za-z0-9_]+)/g)).map((match) => normalizeSelftestMentionSelector(match[1] || "")),
|
|
3338
|
+
uniqueOrdered: normalizeSelftestConversationSelectorList,
|
|
3339
|
+
buildHumanIntentFromPersistedRunnerRequest: () => null,
|
|
3340
|
+
buildRunnerHumanIntentCacheKey: () => "directed-reply-target-korean",
|
|
3341
|
+
runnerHumanIntentPromises: new Map(),
|
|
3342
|
+
analyzeHumanConversationIntentWithContractResolver: async () => ({
|
|
3343
|
+
intentMode: "single_bot",
|
|
3344
|
+
replyExpectation: "actionable",
|
|
3345
|
+
intentType: "actionable_request",
|
|
3346
|
+
}),
|
|
3347
|
+
scheduleRunnerHumanIntentCacheCleanup: () => {},
|
|
3348
|
+
isCompleteHumanIntentContract: () => true,
|
|
3349
|
+
normalizeHumanIntentType: (value, fallback = "") => String(value || "").trim() || fallback,
|
|
3350
|
+
},
|
|
3351
|
+
});
|
|
3352
|
+
push(
|
|
3353
|
+
"runner_human_intent_context_detects_korean_directed_reply_target",
|
|
3354
|
+
String(replyTargetIntentContext?.humanIntent?.replyTargetBotSelector || "") === "sanghoon01_bot"
|
|
3355
|
+
&& JSON.stringify(ensureArray(replyTargetIntentContext?.managedMentions || [])) === JSON.stringify(["ryoai_bot", "sanghoon01_bot"]),
|
|
3356
|
+
`reply_target=${String(replyTargetIntentContext?.humanIntent?.replyTargetBotSelector || "(none)")} managed=${JSON.stringify(ensureArray(replyTargetIntentContext?.managedMentions || []))}`,
|
|
3357
|
+
);
|
|
3358
|
+
} catch (err) {
|
|
3359
|
+
push(
|
|
3360
|
+
"runner_human_intent_context_detects_korean_directed_reply_target",
|
|
3361
|
+
false,
|
|
3362
|
+
String(err?.message || err),
|
|
3363
|
+
);
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
const mentionOverridesReplyForUnmentionedBot = evaluateTelegramRunnerTrigger(
|
|
3234
3367
|
{
|
|
3235
3368
|
id: "comment-2b",
|
|
3236
3369
|
parsedArchive: {
|
|
@@ -18701,6 +18834,48 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
18701
18834
|
push("runner_selected_record_terminal_outcome_stays_within_module_4_boundary", false, String(err?.message || err));
|
|
18702
18835
|
}
|
|
18703
18836
|
|
|
18837
|
+
try {
|
|
18838
|
+
const replyText = resolveCodexRawTextProcessResult({
|
|
18839
|
+
outputText: "{\"reply\":\"하이\"}",
|
|
18840
|
+
stdoutText: "",
|
|
18841
|
+
stderrText: "OpenAI Codex v0.114.0\nsession id: test-session\nmcp: metheus ready",
|
|
18842
|
+
status: 1,
|
|
18843
|
+
spawnError: null,
|
|
18844
|
+
});
|
|
18845
|
+
push(
|
|
18846
|
+
"codex_nonzero_exit_uses_final_output_file_when_available",
|
|
18847
|
+
String(replyText || "").trim() === "{\"reply\":\"하이\"}",
|
|
18848
|
+
`reply=${String(replyText || "(none)")}`,
|
|
18849
|
+
);
|
|
18850
|
+
} catch (err) {
|
|
18851
|
+
push("codex_nonzero_exit_uses_final_output_file_when_available", false, String(err?.message || err));
|
|
18852
|
+
}
|
|
18853
|
+
|
|
18854
|
+
try {
|
|
18855
|
+
let errorMessage = "";
|
|
18856
|
+
try {
|
|
18857
|
+
resolveCodexRawTextProcessResult({
|
|
18858
|
+
outputText: "",
|
|
18859
|
+
stdoutText: "",
|
|
18860
|
+
stderrText: "OpenAI Codex v0.114.0\nworkdir: C:\\LUSH KOREA CLI\nsession id: test-session\nmcp: metheus starting\nmcp: metheus ready",
|
|
18861
|
+
status: 1,
|
|
18862
|
+
spawnError: null,
|
|
18863
|
+
});
|
|
18864
|
+
} catch (err) {
|
|
18865
|
+
errorMessage = String(err?.message || err);
|
|
18866
|
+
}
|
|
18867
|
+
push(
|
|
18868
|
+
"codex_failure_summary_does_not_leak_session_transcript",
|
|
18869
|
+
/Codex CLI exited before returning a final reply/i.test(errorMessage)
|
|
18870
|
+
&& !/OpenAI Codex v/i.test(errorMessage)
|
|
18871
|
+
&& !/session id:/i.test(errorMessage)
|
|
18872
|
+
&& !/mcp:/i.test(errorMessage),
|
|
18873
|
+
errorMessage || "(no error message)",
|
|
18874
|
+
);
|
|
18875
|
+
} catch (err) {
|
|
18876
|
+
push("codex_failure_summary_does_not_leak_session_transcript", false, String(err?.message || err));
|
|
18877
|
+
}
|
|
18878
|
+
|
|
18704
18879
|
try {
|
|
18705
18880
|
const prepared = await prepareRunnerSelectedRecordContractContext({
|
|
18706
18881
|
selectedRecord: {
|