omnius 1.0.157 → 1.0.158
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/dist/index.js +629 -54
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -572826,6 +572826,7 @@ function newDocument(scope) {
|
|
|
572826
572826
|
updatedAt: now,
|
|
572827
572827
|
messageCount: 0,
|
|
572828
572828
|
participants: {},
|
|
572829
|
+
preferences: {},
|
|
572829
572830
|
dominantTone: [],
|
|
572830
572831
|
responseStyle: [
|
|
572831
572832
|
"Prefer concise, direct answers unless the user asks for depth.",
|
|
@@ -572859,6 +572860,7 @@ function normalizeDocument(scope, parsed) {
|
|
|
572859
572860
|
label: scope.label || parsed.scope?.label || fresh.scope.label
|
|
572860
572861
|
},
|
|
572861
572862
|
participants: parsed.participants && typeof parsed.participants === "object" ? parsed.participants : {},
|
|
572863
|
+
preferences: parsed.preferences && typeof parsed.preferences === "object" ? parsed.preferences : {},
|
|
572862
572864
|
dominantTone: Array.isArray(parsed.dominantTone) ? parsed.dominantTone : [],
|
|
572863
572865
|
responseStyle: Array.isArray(parsed.responseStyle) && parsed.responseStyle.length > 0 ? parsed.responseStyle : fresh.responseStyle,
|
|
572864
572866
|
relationshipModel: Array.isArray(parsed.relationshipModel) && parsed.relationshipModel.length > 0 ? parsed.relationshipModel : fresh.relationshipModel,
|
|
@@ -572878,6 +572880,41 @@ function normalizeDocument(scope, parsed) {
|
|
|
572878
572880
|
}
|
|
572879
572881
|
return doc;
|
|
572880
572882
|
}
|
|
572883
|
+
function updateScopedPersonalityReplyPreference(scope, preference) {
|
|
572884
|
+
const doc = loadScopedPersonality(scope);
|
|
572885
|
+
const now = new Date(preference.ts ?? Date.now()).toISOString();
|
|
572886
|
+
const existing = doc.preferences?.replyMode;
|
|
572887
|
+
const evidence = preference.evidenceMessageId === void 0 ? existing?.evidenceMessageIds ?? [] : [.../* @__PURE__ */ new Set([...existing?.evidenceMessageIds ?? [], preference.evidenceMessageId])].slice(-12);
|
|
572888
|
+
doc.preferences = {
|
|
572889
|
+
...doc.preferences ?? {},
|
|
572890
|
+
replyMode: {
|
|
572891
|
+
mode: preference.mode,
|
|
572892
|
+
scope: preference.preferenceScope,
|
|
572893
|
+
updatedAt: now,
|
|
572894
|
+
confidence: Math.max(existing?.confidence ?? 0, Math.max(0, Math.min(1, preference.confidence ?? 0.84))),
|
|
572895
|
+
evidenceMessageIds: evidence,
|
|
572896
|
+
note: preference.note ? compactLine(preference.note, 220) : existing?.note,
|
|
572897
|
+
source: preference.source ? compactLine(preference.source, 80) : existing?.source
|
|
572898
|
+
}
|
|
572899
|
+
};
|
|
572900
|
+
doc.updatedAt = now;
|
|
572901
|
+
const line = `${now} preference/reply_mode: ${preference.mode} (${preference.preferenceScope})${preference.note ? ` - ${compactLine(preference.note, 160)}` : ""}`;
|
|
572902
|
+
if (!doc.durableObservations.includes(line)) doc.durableObservations.push(line);
|
|
572903
|
+
doc.durableObservations = doc.durableObservations.slice(-MAX_PROFILE_DURABLE_OBSERVATIONS);
|
|
572904
|
+
appendScopedPersonalityEvent(scope, {
|
|
572905
|
+
ts: preference.ts ?? Date.now(),
|
|
572906
|
+
iso: now,
|
|
572907
|
+
role: "system",
|
|
572908
|
+
mode: "reply-preference",
|
|
572909
|
+
replyMode: preference.mode,
|
|
572910
|
+
preferenceScope: preference.preferenceScope,
|
|
572911
|
+
evidenceMessageId: preference.evidenceMessageId,
|
|
572912
|
+
note: preference.note,
|
|
572913
|
+
source: preference.source
|
|
572914
|
+
});
|
|
572915
|
+
saveScopedPersonality(scope, doc);
|
|
572916
|
+
return doc;
|
|
572917
|
+
}
|
|
572881
572918
|
function loadScopedPersonality(scope) {
|
|
572882
572919
|
const paths = scopedPersonalityPaths(scope);
|
|
572883
572920
|
if (!existsSync88(paths.json)) return newDocument(scope);
|
|
@@ -573001,6 +573038,7 @@ ${samples}` : ""}`;
|
|
|
573001
573038
|
const topTopics = Object.entries(doc.topicCounts ?? {}).sort((a2, b) => b[1] - a2[1]).slice(0, 18).map(([topic, count]) => `- ${topic}: ${count}`);
|
|
573002
573039
|
const durable = doc.durableObservations.slice(-18).map((line) => `- ${line}`);
|
|
573003
573040
|
const relationships = doc.relationshipEvents.slice(-10).map((line) => `- ${line}`);
|
|
573041
|
+
const replyMode = doc.preferences?.replyMode;
|
|
573004
573042
|
return [
|
|
573005
573043
|
`# Scoped Personality Profile`,
|
|
573006
573044
|
``,
|
|
@@ -573014,6 +573052,9 @@ ${samples}` : ""}`;
|
|
|
573014
573052
|
`## Response Style`,
|
|
573015
573053
|
doc.responseStyle.map((line) => `- ${line}`).join("\n"),
|
|
573016
573054
|
``,
|
|
573055
|
+
`## Stored Preferences`,
|
|
573056
|
+
replyMode ? `- reply_mode: ${replyMode.mode}; scope=${replyMode.scope}; confidence=${replyMode.confidence.toFixed(2)}; updated=${replyMode.updatedAt}${replyMode.note ? `; note=${replyMode.note}` : ""}` : "- none",
|
|
573057
|
+
``,
|
|
573017
573058
|
`## Relationship Model`,
|
|
573018
573059
|
doc.relationshipModel.map((line) => `- ${line}`).join("\n"),
|
|
573019
573060
|
``,
|
|
@@ -620429,10 +620470,10 @@ function formatSystemObservations(sessionKey) {
|
|
|
620429
620470
|
if (recent.length > 0) {
|
|
620430
620471
|
const sends = recent.filter((e2) => e2.kind.startsWith("telegram.send."));
|
|
620431
620472
|
const reactions = recent.filter((e2) => e2.kind.startsWith("emoji."));
|
|
620432
|
-
const
|
|
620433
|
-
|
|
620434
|
-
|
|
620435
|
-
|
|
620473
|
+
const failures = sends.filter((e2) => e2.kind === "telegram.send.failed");
|
|
620474
|
+
if (failures.length > 0) {
|
|
620475
|
+
lines.push(`This chat has ${failures.length} recent raw Telegram send failure(s). Latest raw failure: ${failures[failures.length - 1]?.reason ?? "unknown"}.`);
|
|
620476
|
+
}
|
|
620436
620477
|
if (reactions.length > 0) {
|
|
620437
620478
|
const reactSummary = reactions.filter((e2) => e2.kind === "emoji.reaction.received").map((e2) => e2.emoji).join("");
|
|
620438
620479
|
if (reactSummary) lines.push(`Recent inbound reactions in this chat: ${reactSummary}`);
|
|
@@ -621879,6 +621920,15 @@ function telegramSocialActorKind(actor) {
|
|
|
621879
621920
|
function telegramSocialThreadKey(input) {
|
|
621880
621921
|
return input.messageThreadId !== void 0 ? `chat:${String(input.chatId)}:thread:${input.messageThreadId}` : `chat:${String(input.chatId)}`;
|
|
621881
621922
|
}
|
|
621923
|
+
function telegramSocialChatPreferenceKey(chatId) {
|
|
621924
|
+
return `chat:${String(chatId)}`;
|
|
621925
|
+
}
|
|
621926
|
+
function telegramSocialUserInChatPreferenceKey(chatId, actorKey) {
|
|
621927
|
+
return `${telegramSocialChatPreferenceKey(chatId)}:${actorKey}`;
|
|
621928
|
+
}
|
|
621929
|
+
function telegramTextDeliveryCapabilityKey(input) {
|
|
621930
|
+
return input.messageThreadId !== void 0 ? `${telegramSocialChatPreferenceKey(input.chatId)}:thread:${input.messageThreadId}:text` : `${telegramSocialChatPreferenceKey(input.chatId)}:text`;
|
|
621931
|
+
}
|
|
621882
621932
|
function appendUnique(items, value2, max) {
|
|
621883
621933
|
if (value2 === void 0 || value2 === null) return items.slice(-max);
|
|
621884
621934
|
const next = items.filter((item) => item !== value2);
|
|
@@ -621951,14 +622001,29 @@ function formatTelegramSocialStateContext(state, input) {
|
|
|
621951
622001
|
const salience = state.salience.filter((item) => item.senderKey === senderKey3 || item.chatId === String(input.chatId)).sort((a2, b) => b.ts - a2.ts).slice(0, limit);
|
|
621952
622002
|
const daydreams = Object.values(state.daydreamOpportunities).filter((item) => item.lifecycle !== "retired").sort((a2, b) => b.updatedAt - a2.updatedAt).slice(0, Math.min(5, limit));
|
|
621953
622003
|
const preferences = preferenceLines(state.preferences[senderKey3]);
|
|
622004
|
+
const chatPreferenceKey = telegramSocialChatPreferenceKey(input.chatId);
|
|
622005
|
+
const userChatPreferenceKey = telegramSocialUserInChatPreferenceKey(input.chatId, senderKey3);
|
|
622006
|
+
const scopedPreferences = [
|
|
622007
|
+
...preferenceLines(state.preferences[userChatPreferenceKey], "user-in-chat"),
|
|
622008
|
+
...preferenceLines(state.preferences[chatPreferenceKey], "chat")
|
|
622009
|
+
];
|
|
622010
|
+
const resolvedReplyMode = resolveReplyModePreferenceForContext(state, input.chatId, senderKey3);
|
|
622011
|
+
const delivery = state.deliveryCapabilities[telegramTextDeliveryCapabilityKey({
|
|
622012
|
+
chatId: input.chatId,
|
|
622013
|
+
messageThreadId: input.messageThreadId
|
|
622014
|
+
})] ?? state.deliveryCapabilities[telegramTextDeliveryCapabilityKey({ chatId: input.chatId })];
|
|
621954
622015
|
return [
|
|
621955
622016
|
"### Telegram Structured Social State",
|
|
621956
622017
|
selfKey ? `Agent self node: ${selfKey}` : "Agent self node: unknown",
|
|
621957
622018
|
`Identity boundary: the agent is the self node only. Current actor ${senderKey3} is ${senderIdentity}; reply target ${replyKey ?? "none"} is ${replyIdentity}. Participant first-person claims belong to their actor node, not the agent, unless that actor is the self node.`,
|
|
621958
622019
|
`Current actor node: ${senderKey3} [${participant?.actorKind || telegramSocialActorKind(input)}] messages=${participant?.messageCount ?? 0}${participant?.lastText ? ` last=${jsonLine(participant.lastText, 140)}` : ""}`,
|
|
621959
622020
|
thread ? `Active channel/thread: ${thread.key}; messages=${thread.messageCount}; participants=${thread.participantKeys.slice(-8).join(", ") || "none"}; last_outcomes=${thread.lastOutcomeIds.slice(-5).join(", ") || "none"}` : "",
|
|
622021
|
+
delivery ? `Telegram text delivery raw warning stream: ${delivery.status}; key=${telegramTextDeliveryCapabilityKey({ chatId: input.chatId, messageThreadId: input.messageThreadId })}${delivery.reason ? `; raw=${jsonLine(delivery.reason, 180)}` : ""}` : "Telegram text delivery raw warning stream: none recorded",
|
|
622022
|
+
resolvedReplyMode ? `Resolved reply mode: ${resolvedReplyMode.item.mode} from ${resolvedReplyMode.item.scope} (${resolvedReplyMode.key}); confidence=${resolvedReplyMode.item.confidence.toFixed(2)}${resolvedReplyMode.item.note ? ` note=${jsonLine(resolvedReplyMode.item.note, 120)}` : ""}` : "Resolved reply mode: notes_then_reply (system default)",
|
|
621960
622023
|
preferences.length ? `Relevant preference vector for ${senderKey3}:
|
|
621961
622024
|
${preferences.join("\n")}` : `Relevant preference vector for ${senderKey3}: no durable preferences yet`,
|
|
622025
|
+
scopedPreferences.length ? `Scoped reply preferences:
|
|
622026
|
+
${scopedPreferences.join("\n")}` : "",
|
|
621962
622027
|
salience.length ? `Recent salience observations:
|
|
621963
622028
|
${salience.map((item) => `- ${iso(item.ts)} ${item.senderKey}: ${item.signals.join(", ") || "none"}; text=${jsonLine(item.textPreview, 120)}`).join("\n")}` : "",
|
|
621964
622029
|
edges.length ? `Relevant relationship edges:
|
|
@@ -621969,11 +622034,26 @@ ${outcomes.map(formatOutcome).join("\n")}` : "Prior response outcomes: none yet"
|
|
|
621969
622034
|
${daydreams.map((item) => `- ${item.id} [${item.lifecycle}] confidence=${item.confidence.toFixed(2)} trigger=${jsonLine(item.trigger, 140)}`).join("\n")}` : ""
|
|
621970
622035
|
].filter(Boolean).join("\n");
|
|
621971
622036
|
}
|
|
621972
|
-
function
|
|
622037
|
+
function resolveReplyModePreferenceForContext(state, chatId, senderKey3) {
|
|
622038
|
+
for (const key of [
|
|
622039
|
+
telegramSocialUserInChatPreferenceKey(chatId, senderKey3),
|
|
622040
|
+
senderKey3,
|
|
622041
|
+
telegramSocialChatPreferenceKey(chatId)
|
|
622042
|
+
]) {
|
|
622043
|
+
const item = state.preferences[key]?.replyMode;
|
|
622044
|
+
if (item) return { key, item };
|
|
622045
|
+
}
|
|
622046
|
+
return void 0;
|
|
622047
|
+
}
|
|
622048
|
+
function preferenceLines(vector, prefix) {
|
|
621973
622049
|
if (!vector) return [];
|
|
621974
622050
|
return Object.entries(vector).map(([key, evidence]) => {
|
|
622051
|
+
if (key === "replyMode") {
|
|
622052
|
+
const item2 = evidence;
|
|
622053
|
+
return `- ${prefix ? `${prefix}.` : ""}${key}: mode=${item2.mode} scope=${item2.scope} confidence=${item2.confidence.toFixed(2)} evidence=${item2.evidenceMessageIds.join(",") || "none"}${item2.note ? ` note=${jsonLine(item2.note, 120)}` : ""}`;
|
|
622054
|
+
}
|
|
621975
622055
|
const item = evidence;
|
|
621976
|
-
return `- ${key}: value=${item.value.toFixed(2)} confidence=${item.confidence.toFixed(2)} evidence=${item.evidenceMessageIds.join(",") || "none"}${item.note ? ` note=${jsonLine(item.note, 120)}` : ""}`;
|
|
622056
|
+
return `- ${prefix ? `${prefix}.` : ""}${key}: value=${item.value.toFixed(2)} confidence=${item.confidence.toFixed(2)} evidence=${item.evidenceMessageIds.join(",") || "none"}${item.note ? ` note=${jsonLine(item.note, 120)}` : ""}`;
|
|
621977
622057
|
});
|
|
621978
622058
|
}
|
|
621979
622059
|
function formatEdge(edge) {
|
|
@@ -622003,6 +622083,7 @@ function createTelegramSocialState(now = Date.now()) {
|
|
|
622003
622083
|
participants: {},
|
|
622004
622084
|
relationships: [],
|
|
622005
622085
|
preferences: {},
|
|
622086
|
+
deliveryCapabilities: {},
|
|
622006
622087
|
threads: {},
|
|
622007
622088
|
salience: [],
|
|
622008
622089
|
outcomes: [],
|
|
@@ -622019,6 +622100,7 @@ function normalizeTelegramSocialState(raw) {
|
|
|
622019
622100
|
state.participants = normalizeRecord(value2.participants, normalizeParticipant);
|
|
622020
622101
|
state.relationships = Array.isArray(value2.relationships) ? value2.relationships.map(normalizeRelationship).filter(Boolean).slice(-TELEGRAM_SOCIAL_LIMITS.relationships) : [];
|
|
622021
622102
|
state.preferences = normalizePreferences(value2.preferences);
|
|
622103
|
+
state.deliveryCapabilities = normalizeRecord(value2.deliveryCapabilities, normalizeDeliveryCapability);
|
|
622022
622104
|
state.threads = normalizeRecord(value2.threads, normalizeThread);
|
|
622023
622105
|
state.salience = Array.isArray(value2.salience) ? value2.salience.map(normalizeSalience).filter(Boolean).slice(-TELEGRAM_SOCIAL_LIMITS.salience) : [];
|
|
622024
622106
|
state.outcomes = Array.isArray(value2.outcomes) ? value2.outcomes.map(normalizeOutcome).filter(Boolean).slice(-TELEGRAM_SOCIAL_LIMITS.outcomes) : [];
|
|
@@ -622088,9 +622170,55 @@ function normalizePreferences(raw) {
|
|
|
622088
622170
|
note: compactOptional(evidence.note, 220)
|
|
622089
622171
|
};
|
|
622090
622172
|
}
|
|
622173
|
+
const replyMode = vector["replyMode"];
|
|
622174
|
+
if (replyMode && typeof replyMode === "object" && !Array.isArray(replyMode)) {
|
|
622175
|
+
const record = replyMode;
|
|
622176
|
+
const mode = normalizeReplyMode(record["mode"]);
|
|
622177
|
+
if (mode) {
|
|
622178
|
+
out[actorKey].replyMode = {
|
|
622179
|
+
mode,
|
|
622180
|
+
scope: normalizeReplyPreferenceScope(record["scope"]),
|
|
622181
|
+
confidence: clamp0110(numberOr(record["confidence"], 0.8)),
|
|
622182
|
+
updatedAt: numberOr(record["updatedAt"], Date.now()),
|
|
622183
|
+
evidenceMessageIds: Array.isArray(record["evidenceMessageIds"]) ? record["evidenceMessageIds"].filter(isNumber).slice(-12) : [],
|
|
622184
|
+
note: compactOptional(record["note"], 220),
|
|
622185
|
+
source: compactOptional(record["source"], 80)
|
|
622186
|
+
};
|
|
622187
|
+
}
|
|
622188
|
+
}
|
|
622091
622189
|
}
|
|
622092
622190
|
return out;
|
|
622093
622191
|
}
|
|
622192
|
+
function normalizeReplyMode(raw) {
|
|
622193
|
+
return raw === "reply_then_notes" || raw === "notes_then_reply" || raw === "reply_only" ? raw : void 0;
|
|
622194
|
+
}
|
|
622195
|
+
function normalizeReplyPreferenceScope(raw) {
|
|
622196
|
+
return raw === "chat" || raw === "user_in_chat" || raw === "user" ? raw : "user_in_chat";
|
|
622197
|
+
}
|
|
622198
|
+
function normalizeDeliveryCapability(raw) {
|
|
622199
|
+
if (!raw || typeof raw !== "object") return null;
|
|
622200
|
+
const value2 = raw;
|
|
622201
|
+
const key = compact2(value2.key || "", 180);
|
|
622202
|
+
const chatId = compact2(value2.chatId || "", 120);
|
|
622203
|
+
if (!key || !chatId) return null;
|
|
622204
|
+
const status = normalizeDeliveryStatus(value2.status);
|
|
622205
|
+
return {
|
|
622206
|
+
key,
|
|
622207
|
+
chatId,
|
|
622208
|
+
messageThreadId: typeof value2.messageThreadId === "number" ? value2.messageThreadId : void 0,
|
|
622209
|
+
status,
|
|
622210
|
+
canSendText: typeof value2.canSendText === "boolean" ? value2.canSendText : status === "allowed" ? true : void 0,
|
|
622211
|
+
checkedAt: numberOr(value2.checkedAt, Date.now()),
|
|
622212
|
+
lastSuccessAt: typeof value2.lastSuccessAt === "number" ? value2.lastSuccessAt : void 0,
|
|
622213
|
+
lastFailureAt: typeof value2.lastFailureAt === "number" ? value2.lastFailureAt : void 0,
|
|
622214
|
+
reason: compactOptional(value2.reason, 320),
|
|
622215
|
+
retryAfterSec: typeof value2.retryAfterSec === "number" ? Math.max(0, Math.floor(value2.retryAfterSec)) : void 0,
|
|
622216
|
+
source: compactOptional(value2.source, 80)
|
|
622217
|
+
};
|
|
622218
|
+
}
|
|
622219
|
+
function normalizeDeliveryStatus(raw) {
|
|
622220
|
+
return raw === "allowed" || raw === "failed" ? raw : "unknown";
|
|
622221
|
+
}
|
|
622094
622222
|
function normalizeThread(raw) {
|
|
622095
622223
|
if (!raw || typeof raw !== "object") return null;
|
|
622096
622224
|
const value2 = raw;
|
|
@@ -622291,6 +622419,73 @@ function markTelegramDaydreamOpportunitiesConsidered(state, opportunities, messa
|
|
|
622291
622419
|
}
|
|
622292
622420
|
return registered;
|
|
622293
622421
|
}
|
|
622422
|
+
function setTelegramReplyModePreference(state, input) {
|
|
622423
|
+
const now = input.ts ?? Date.now();
|
|
622424
|
+
const actorKey = input.actor ? telegramSocialActorKey(input.actor) : void 0;
|
|
622425
|
+
const key = input.scope === "chat" ? telegramSocialChatPreferenceKey(input.chatId) : input.scope === "user_in_chat" && actorKey ? telegramSocialUserInChatPreferenceKey(input.chatId, actorKey) : actorKey ?? telegramSocialChatPreferenceKey(input.chatId);
|
|
622426
|
+
const vector = state.preferences[key] ?? {};
|
|
622427
|
+
const existing = vector.replyMode;
|
|
622428
|
+
const next = {
|
|
622429
|
+
mode: input.mode,
|
|
622430
|
+
scope: input.scope,
|
|
622431
|
+
confidence: Math.max(existing?.confidence ?? 0, clamp0110(input.confidence ?? 0.84)),
|
|
622432
|
+
updatedAt: now,
|
|
622433
|
+
evidenceMessageIds: appendUnique(existing?.evidenceMessageIds ?? [], input.messageId, 12),
|
|
622434
|
+
note: compactOptional(input.note, 220),
|
|
622435
|
+
source: compactOptional(input.source, 80)
|
|
622436
|
+
};
|
|
622437
|
+
vector.replyMode = next;
|
|
622438
|
+
state.preferences[key] = vector;
|
|
622439
|
+
state.updatedAt = now;
|
|
622440
|
+
return next;
|
|
622441
|
+
}
|
|
622442
|
+
function resolveTelegramReplyModePreference(state, input) {
|
|
622443
|
+
const actorKey = input.actor ? telegramSocialActorKey(input.actor) : void 0;
|
|
622444
|
+
const keys = [
|
|
622445
|
+
actorKey ? telegramSocialUserInChatPreferenceKey(input.chatId, actorKey) : "",
|
|
622446
|
+
actorKey ?? "",
|
|
622447
|
+
telegramSocialChatPreferenceKey(input.chatId)
|
|
622448
|
+
].filter(Boolean);
|
|
622449
|
+
for (const key of keys) {
|
|
622450
|
+
const pref = state.preferences[key]?.replyMode;
|
|
622451
|
+
if (!pref) continue;
|
|
622452
|
+
return {
|
|
622453
|
+
key,
|
|
622454
|
+
mode: pref.mode,
|
|
622455
|
+
scope: pref.scope,
|
|
622456
|
+
confidence: pref.confidence,
|
|
622457
|
+
updatedAt: pref.updatedAt,
|
|
622458
|
+
note: pref.note,
|
|
622459
|
+
source: pref.source
|
|
622460
|
+
};
|
|
622461
|
+
}
|
|
622462
|
+
return void 0;
|
|
622463
|
+
}
|
|
622464
|
+
function setTelegramTextDeliveryCapability(state, input) {
|
|
622465
|
+
const now = input.ts ?? Date.now();
|
|
622466
|
+
const key = telegramTextDeliveryCapabilityKey(input);
|
|
622467
|
+
const existing = state.deliveryCapabilities[key];
|
|
622468
|
+
const canSendText = input.status === "allowed" ? true : input.status === "failed" ? void 0 : input.canSendText ?? existing?.canSendText;
|
|
622469
|
+
const next = {
|
|
622470
|
+
key,
|
|
622471
|
+
chatId: String(input.chatId),
|
|
622472
|
+
messageThreadId: input.messageThreadId,
|
|
622473
|
+
status: input.status,
|
|
622474
|
+
canSendText,
|
|
622475
|
+
checkedAt: now,
|
|
622476
|
+
lastSuccessAt: input.status === "allowed" ? now : existing?.lastSuccessAt,
|
|
622477
|
+
lastFailureAt: input.status === "failed" ? now : existing?.lastFailureAt,
|
|
622478
|
+
reason: compactOptional(input.reason, 320) || existing?.reason,
|
|
622479
|
+
retryAfterSec: input.retryAfterSec,
|
|
622480
|
+
source: compactOptional(input.source, 80)
|
|
622481
|
+
};
|
|
622482
|
+
state.deliveryCapabilities[key] = next;
|
|
622483
|
+
state.updatedAt = now;
|
|
622484
|
+
return next;
|
|
622485
|
+
}
|
|
622486
|
+
function telegramTextDeliveryCapabilityFor(state, input) {
|
|
622487
|
+
return state.deliveryCapabilities[telegramTextDeliveryCapabilityKey(input)] ?? state.deliveryCapabilities[telegramTextDeliveryCapabilityKey({ chatId: input.chatId })];
|
|
622488
|
+
}
|
|
622294
622489
|
function commitDecisionEdges(state, input, senderKey3, selfKey, now) {
|
|
622295
622490
|
if (!selfKey) return;
|
|
622296
622491
|
if (input.shouldReply) {
|
|
@@ -622706,6 +622901,28 @@ function telegramDecisionNumber(parsed, keys, nestedKeys = ["internal_notes", "i
|
|
|
622706
622901
|
}
|
|
622707
622902
|
return void 0;
|
|
622708
622903
|
}
|
|
622904
|
+
function parseTelegramReplyMode(raw) {
|
|
622905
|
+
return raw === "reply_then_notes" || raw === "notes_then_reply" || raw === "reply_only" ? raw : void 0;
|
|
622906
|
+
}
|
|
622907
|
+
function parseTelegramReplyPreferenceToolScope(raw) {
|
|
622908
|
+
return raw === "current_user_in_chat" || raw === "current_user_global" || raw === "current_group" ? raw : void 0;
|
|
622909
|
+
}
|
|
622910
|
+
function parseTelegramReplyPreferenceUpdate(parsed) {
|
|
622911
|
+
const raw = parsed["reply_mode_preference"] ?? parsed["replyModePreference"] ?? parsed["preference_update"] ?? parsed["preferenceUpdate"];
|
|
622912
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
622913
|
+
const record = raw;
|
|
622914
|
+
const replyMode = parseTelegramReplyMode(record["reply_mode"] ?? record["replyMode"] ?? record["mode"]);
|
|
622915
|
+
const scope = parseTelegramReplyPreferenceToolScope(record["scope"]);
|
|
622916
|
+
if (!replyMode || !scope) return void 0;
|
|
622917
|
+
const confidence2 = Number(record["confidence"]);
|
|
622918
|
+
return {
|
|
622919
|
+
scope,
|
|
622920
|
+
replyMode,
|
|
622921
|
+
confidence: Number.isFinite(confidence2) ? Math.max(0, Math.min(1, confidence2)) : void 0,
|
|
622922
|
+
note: cleanTelegramDecisionNote(record["note"] ?? record["reason"] ?? record["rationale"]),
|
|
622923
|
+
source: cleanTelegramDecisionNote(record["source"])
|
|
622924
|
+
};
|
|
622925
|
+
}
|
|
622709
622926
|
function uniqueTelegramJsonCandidates(candidates) {
|
|
622710
622927
|
const seen = /* @__PURE__ */ new Set();
|
|
622711
622928
|
const unique = [];
|
|
@@ -623048,7 +623265,8 @@ function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
|
|
|
623048
623265
|
scenarioLabel: telegramDecisionNote(parsed, ["scenario_label", "scenarioLabel", "label"], ["scenario", "classification"]),
|
|
623049
623266
|
scenarioConfidence: telegramDecisionNumber(parsed, ["scenario_confidence", "scenarioConfidence", "confidence"], ["scenario", "classification"]),
|
|
623050
623267
|
scenarioObjective: telegramDecisionNote(parsed, ["scenario_objective", "scenarioObjective", "objective"], ["scenario", "classification"]),
|
|
623051
|
-
scenarioStateLoop: telegramDecisionNote(parsed, ["scenario_state_loop", "scenarioStateLoop", "state_loop", "stateLoop"], ["scenario", "classification"])
|
|
623268
|
+
scenarioStateLoop: telegramDecisionNote(parsed, ["scenario_state_loop", "scenarioStateLoop", "state_loop", "stateLoop"], ["scenario", "classification"]),
|
|
623269
|
+
replyPreferenceUpdate: parseTelegramReplyPreferenceUpdate(parsed)
|
|
623052
623270
|
};
|
|
623053
623271
|
} catch {
|
|
623054
623272
|
continue;
|
|
@@ -625273,6 +625491,7 @@ External acquisition contract:
|
|
|
625273
625491
|
decision2.voiceNote ? `voice note: ${decision2.voiceNote}` : "",
|
|
625274
625492
|
decision2.scenarioNote ? `scenario note: ${decision2.scenarioNote}` : "",
|
|
625275
625493
|
decision2.scenarioId ? `scenario classification: ${decision2.scenarioId}${decision2.scenarioLabel ? ` (${decision2.scenarioLabel})` : ""}` : "",
|
|
625494
|
+
decision2.replyPreferenceUpdate ? `reply preference update: ${decision2.replyPreferenceUpdate.replyMode} (${this.telegramReplyPreferenceScopeLabel(decision2.replyPreferenceUpdate.scope)})` : "",
|
|
625276
625495
|
cadence ? `next attention sample: ${cadence}` : ""
|
|
625277
625496
|
].filter(Boolean);
|
|
625278
625497
|
if (viewId && this.subAgentViewCallbacks) {
|
|
@@ -625293,7 +625512,8 @@ External acquisition contract:
|
|
|
625293
625512
|
decision2.procedureNote ? `procedure note: ${decision2.procedureNote}` : "",
|
|
625294
625513
|
decision2.voiceNote ? `voice note: ${decision2.voiceNote}` : "",
|
|
625295
625514
|
decision2.scenarioNote ? `scenario note: ${decision2.scenarioNote}` : "",
|
|
625296
|
-
decision2.scenarioId ? `scenario classification: ${decision2.scenarioId}${decision2.scenarioLabel ? ` (${decision2.scenarioLabel})` : ""}` : ""
|
|
625515
|
+
decision2.scenarioId ? `scenario classification: ${decision2.scenarioId}${decision2.scenarioLabel ? ` (${decision2.scenarioLabel})` : ""}` : "",
|
|
625516
|
+
decision2.replyPreferenceUpdate ? `reply preference update: ${decision2.replyPreferenceUpdate.replyMode} (${this.telegramReplyPreferenceScopeLabel(decision2.replyPreferenceUpdate.scope)})` : ""
|
|
625297
625517
|
].filter(Boolean);
|
|
625298
625518
|
this.tuiWrite(() => {
|
|
625299
625519
|
renderTelegramSubAgentEvent(msg.username, primary);
|
|
@@ -625710,6 +625930,7 @@ ${message2}`)
|
|
|
625710
625930
|
decision2.voiceNote ? `voice_note: ${decision2.voiceNote}` : "",
|
|
625711
625931
|
decision2.memoryNote ? `memory_note: ${decision2.memoryNote}` : "",
|
|
625712
625932
|
decision2.relationshipNote ? `relationship_note: ${decision2.relationshipNote}` : "",
|
|
625933
|
+
decision2.replyPreferenceUpdate ? `reply_preference_update: ${decision2.replyPreferenceUpdate.replyMode} (${this.telegramReplyPreferenceScopeLabel(decision2.replyPreferenceUpdate.scope)})` : "",
|
|
625713
625934
|
"Use this as classifier output from the prior attention stage, not as a new instruction to spawn or route again."
|
|
625714
625935
|
].filter(Boolean).join("\n");
|
|
625715
625936
|
}
|
|
@@ -626515,6 +626736,158 @@ ${mediaContext}` : ""
|
|
|
626515
626736
|
repoRoot: this.repoRoot || "."
|
|
626516
626737
|
};
|
|
626517
626738
|
}
|
|
626739
|
+
telegramUserPersonalityScope(msg) {
|
|
626740
|
+
const id = msg.fromUserId ? `telegram-user:${msg.fromUserId}` : `telegram-user:${msg.username || msg.firstName || "unknown"}`;
|
|
626741
|
+
const label = `user-${msg.username || msg.firstName || msg.fromUserId || "unknown"}`;
|
|
626742
|
+
return {
|
|
626743
|
+
kind: "telegram-user",
|
|
626744
|
+
id,
|
|
626745
|
+
label,
|
|
626746
|
+
repoRoot: this.repoRoot || "."
|
|
626747
|
+
};
|
|
626748
|
+
}
|
|
626749
|
+
telegramUserInChatPersonalityScope(sessionKey, msg) {
|
|
626750
|
+
const user = msg.fromUserId ? `user:${msg.fromUserId}` : `user:${msg.username || msg.firstName || "unknown"}`;
|
|
626751
|
+
const chat = msg.chatTitle || msg.chatType || String(msg.chatId);
|
|
626752
|
+
return {
|
|
626753
|
+
kind: "telegram-user-in-chat",
|
|
626754
|
+
id: `${sessionKey}:${user}`,
|
|
626755
|
+
label: `${chat}-${msg.username || msg.firstName || msg.fromUserId || "unknown"}`,
|
|
626756
|
+
repoRoot: this.repoRoot || "."
|
|
626757
|
+
};
|
|
626758
|
+
}
|
|
626759
|
+
telegramSocialPreferenceScope(scope) {
|
|
626760
|
+
if (scope === "current_group") return "chat";
|
|
626761
|
+
if (scope === "current_user_global") return "user";
|
|
626762
|
+
return "user_in_chat";
|
|
626763
|
+
}
|
|
626764
|
+
telegramReplyPreferenceScopeLabel(scope) {
|
|
626765
|
+
if (scope === "current_group") return "current group";
|
|
626766
|
+
if (scope === "current_user_global") return "current user globally";
|
|
626767
|
+
return "current user in this group/chat";
|
|
626768
|
+
}
|
|
626769
|
+
scopedPersonalityForReplyPreference(sessionKey, msg, scope) {
|
|
626770
|
+
if (scope === "current_group") return this.telegramPersonalityScope(sessionKey, msg);
|
|
626771
|
+
if (scope === "current_user_global") return this.telegramUserPersonalityScope(msg);
|
|
626772
|
+
return this.telegramUserInChatPersonalityScope(sessionKey, msg);
|
|
626773
|
+
}
|
|
626774
|
+
applyTelegramReplyPreferenceUpdate(sessionKey, msg, update2, source) {
|
|
626775
|
+
if (!update2) return void 0;
|
|
626776
|
+
const preferenceScope = this.telegramSocialPreferenceScope(update2.scope);
|
|
626777
|
+
const evidence = setTelegramReplyModePreference(this.telegramSocialStateForSession(sessionKey), {
|
|
626778
|
+
chatId: msg.chatId,
|
|
626779
|
+
actor: this.telegramMessageSocialActorInput(msg),
|
|
626780
|
+
scope: preferenceScope,
|
|
626781
|
+
mode: update2.replyMode,
|
|
626782
|
+
confidence: update2.confidence,
|
|
626783
|
+
messageId: msg.messageId,
|
|
626784
|
+
note: update2.note,
|
|
626785
|
+
source: update2.source || source
|
|
626786
|
+
});
|
|
626787
|
+
try {
|
|
626788
|
+
updateScopedPersonalityReplyPreference(
|
|
626789
|
+
this.scopedPersonalityForReplyPreference(sessionKey, msg, update2.scope),
|
|
626790
|
+
{
|
|
626791
|
+
mode: update2.replyMode,
|
|
626792
|
+
preferenceScope,
|
|
626793
|
+
confidence: evidence.confidence,
|
|
626794
|
+
evidenceMessageId: msg.messageId,
|
|
626795
|
+
note: update2.note,
|
|
626796
|
+
source: update2.source || source
|
|
626797
|
+
}
|
|
626798
|
+
);
|
|
626799
|
+
} catch {
|
|
626800
|
+
}
|
|
626801
|
+
this.saveTelegramConversationState(sessionKey);
|
|
626802
|
+
return `stored reply_mode=${update2.replyMode} for ${this.telegramReplyPreferenceScopeLabel(update2.scope)}`;
|
|
626803
|
+
}
|
|
626804
|
+
hydrateTelegramReplyPreferencesFromPersona(sessionKey, msg) {
|
|
626805
|
+
for (const [scope, personalityScope] of [
|
|
626806
|
+
["current_group", this.telegramPersonalityScope(sessionKey, msg)],
|
|
626807
|
+
["current_user_global", this.telegramUserPersonalityScope(msg)],
|
|
626808
|
+
["current_user_in_chat", this.telegramUserInChatPersonalityScope(sessionKey, msg)]
|
|
626809
|
+
]) {
|
|
626810
|
+
try {
|
|
626811
|
+
const pref = loadScopedPersonality(personalityScope).preferences?.replyMode;
|
|
626812
|
+
if (!pref) continue;
|
|
626813
|
+
setTelegramReplyModePreference(this.telegramSocialStateForSession(sessionKey), {
|
|
626814
|
+
chatId: msg.chatId,
|
|
626815
|
+
actor: this.telegramMessageSocialActorInput(msg),
|
|
626816
|
+
scope: pref.scope,
|
|
626817
|
+
mode: pref.mode,
|
|
626818
|
+
confidence: pref.confidence,
|
|
626819
|
+
note: pref.note,
|
|
626820
|
+
source: pref.source || `persona:${scope}`,
|
|
626821
|
+
ts: Number.isFinite(Date.parse(pref.updatedAt)) ? Date.parse(pref.updatedAt) : Date.now()
|
|
626822
|
+
});
|
|
626823
|
+
} catch {
|
|
626824
|
+
}
|
|
626825
|
+
}
|
|
626826
|
+
}
|
|
626827
|
+
resolvedTelegramReplyMode(sessionKey, msg) {
|
|
626828
|
+
try {
|
|
626829
|
+
this.hydrateTelegramReplyPreferencesFromPersona(sessionKey, msg);
|
|
626830
|
+
return resolveTelegramReplyModePreference(this.telegramSocialStateForSession(sessionKey), {
|
|
626831
|
+
chatId: msg.chatId,
|
|
626832
|
+
actor: this.telegramMessageSocialActorInput(msg)
|
|
626833
|
+
})?.mode ?? "notes_then_reply";
|
|
626834
|
+
} catch {
|
|
626835
|
+
return "notes_then_reply";
|
|
626836
|
+
}
|
|
626837
|
+
}
|
|
626838
|
+
stripTelegramDecisionNotes(decision2) {
|
|
626839
|
+
return {
|
|
626840
|
+
...decision2,
|
|
626841
|
+
silentDisposition: void 0,
|
|
626842
|
+
mentalNote: void 0,
|
|
626843
|
+
memoryNote: void 0,
|
|
626844
|
+
relationshipNote: void 0,
|
|
626845
|
+
procedureNote: void 0,
|
|
626846
|
+
voiceNote: void 0,
|
|
626847
|
+
scenarioNote: void 0,
|
|
626848
|
+
scenarioId: void 0,
|
|
626849
|
+
scenarioLabel: void 0,
|
|
626850
|
+
scenarioConfidence: void 0,
|
|
626851
|
+
scenarioObjective: void 0,
|
|
626852
|
+
scenarioStateLoop: void 0
|
|
626853
|
+
};
|
|
626854
|
+
}
|
|
626855
|
+
telegramTextDeliveryCapability(sessionKey, chatId, messageThreadId) {
|
|
626856
|
+
try {
|
|
626857
|
+
return telegramTextDeliveryCapabilityFor(this.telegramSocialStateForSession(sessionKey), {
|
|
626858
|
+
chatId,
|
|
626859
|
+
messageThreadId
|
|
626860
|
+
});
|
|
626861
|
+
} catch {
|
|
626862
|
+
return void 0;
|
|
626863
|
+
}
|
|
626864
|
+
}
|
|
626865
|
+
updateTelegramTextDeliveryCapability(chatId, input) {
|
|
626866
|
+
const sessionKey = `chat:${String(chatId)}`;
|
|
626867
|
+
try {
|
|
626868
|
+
const capability = setTelegramTextDeliveryCapability(this.telegramSocialStateForSession(sessionKey), {
|
|
626869
|
+
chatId,
|
|
626870
|
+
messageThreadId: input.messageThreadId,
|
|
626871
|
+
status: input.status,
|
|
626872
|
+
canSendText: input.canSendText,
|
|
626873
|
+
reason: input.reason,
|
|
626874
|
+
retryAfterSec: input.retryAfterSec,
|
|
626875
|
+
source: input.source
|
|
626876
|
+
});
|
|
626877
|
+
this.saveTelegramConversationState(sessionKey);
|
|
626878
|
+
return capability;
|
|
626879
|
+
} catch {
|
|
626880
|
+
return void 0;
|
|
626881
|
+
}
|
|
626882
|
+
}
|
|
626883
|
+
formatTelegramDeliveryCapabilityContext(sessionKey, msg) {
|
|
626884
|
+
const capability = this.telegramTextDeliveryCapability(sessionKey, msg.chatId, msg.messageThreadId);
|
|
626885
|
+
if (!capability) return "Telegram text delivery raw warning stream for this chat: none recorded.";
|
|
626886
|
+
return [
|
|
626887
|
+
`Telegram text delivery raw warning stream for this chat: ${capability.status}.`,
|
|
626888
|
+
capability.reason ? `Latest raw Telegram warning/error text: ${capability.reason}` : ""
|
|
626889
|
+
].filter(Boolean).join(" ");
|
|
626890
|
+
}
|
|
626518
626891
|
ensureTelegramConversationLoaded(sessionKey) {
|
|
626519
626892
|
if (this.loadedConversationState.has(sessionKey)) return;
|
|
626520
626893
|
this.loadedConversationState.add(sessionKey);
|
|
@@ -627024,7 +627397,7 @@ ${mediaContext}` : ""
|
|
|
627024
627397
|
convertMarkdownToTelegramHTML(decision2.text),
|
|
627025
627398
|
replyTo
|
|
627026
627399
|
);
|
|
627027
|
-
this.recordTelegramAssistantMessage({
|
|
627400
|
+
if (sentMessageId !== null) this.recordTelegramAssistantMessage({
|
|
627028
627401
|
chatId,
|
|
627029
627402
|
chatType: artifact.chatType,
|
|
627030
627403
|
chatTitle: artifact.chatTitle,
|
|
@@ -627037,6 +627410,7 @@ ${mediaContext}` : ""
|
|
|
627037
627410
|
messageId: sentMessageId,
|
|
627038
627411
|
replyToMessageId: replyTo
|
|
627039
627412
|
});
|
|
627413
|
+
if (sentMessageId === null) return { sent: false, reason: "Telegram returned no delivered message id" };
|
|
627040
627414
|
state.lastFollowupAt = now;
|
|
627041
627415
|
this.saveTelegramConversationState(sessionKey);
|
|
627042
627416
|
this.tuiWrite(() => renderTelegramSubAgentEvent("reflection", `sent scoped Telegram follow-up (${decision2.confidence.toFixed(2)}): ${decision2.reason}`));
|
|
@@ -627127,6 +627501,7 @@ ${mediaContext}` : ""
|
|
|
627127
627501
|
buildTelegramSocialStateContext(sessionKey, msg, salienceSignals = []) {
|
|
627128
627502
|
try {
|
|
627129
627503
|
this.registerLatestTelegramDaydreamOpportunities(sessionKey);
|
|
627504
|
+
this.hydrateTelegramReplyPreferencesFromPersona(sessionKey, msg);
|
|
627130
627505
|
return formatTelegramSocialStateContext(this.telegramSocialStateForSession(sessionKey), {
|
|
627131
627506
|
sessionKey,
|
|
627132
627507
|
chatId: msg.chatId,
|
|
@@ -627255,6 +627630,28 @@ ${mediaContext}` : ""
|
|
|
627255
627630
|
msg.chatType !== "private" ? `Group participant ${telegramSpeakerLabel(msg)} in ${msg.chatTitle || "unknown group"}` : `Private Telegram chat with ${telegramSpeakerLabel(msg)}`
|
|
627256
627631
|
]
|
|
627257
627632
|
});
|
|
627633
|
+
updateScopedPersonality(this.telegramUserPersonalityScope(msg), {
|
|
627634
|
+
speaker: telegramSpeakerLabel(msg),
|
|
627635
|
+
text,
|
|
627636
|
+
role: "user",
|
|
627637
|
+
mode,
|
|
627638
|
+
ts: entry.ts,
|
|
627639
|
+
toneTags: inferTelegramToneTags(text),
|
|
627640
|
+
relationshipHints: [
|
|
627641
|
+
`Telegram user identity ${telegramSpeakerLabel(msg)} observed in ${msg.chatType}`
|
|
627642
|
+
]
|
|
627643
|
+
});
|
|
627644
|
+
updateScopedPersonality(this.telegramUserInChatPersonalityScope(sessionKey, msg), {
|
|
627645
|
+
speaker: telegramSpeakerLabel(msg),
|
|
627646
|
+
text,
|
|
627647
|
+
role: "user",
|
|
627648
|
+
mode,
|
|
627649
|
+
ts: entry.ts,
|
|
627650
|
+
toneTags: inferTelegramToneTags(text),
|
|
627651
|
+
relationshipHints: [
|
|
627652
|
+
msg.chatType !== "private" ? `Participant-specific preference/memory scope for ${telegramSpeakerLabel(msg)} in ${msg.chatTitle || "unknown group"}` : `Participant-specific preference/memory scope for private chat with ${telegramSpeakerLabel(msg)}`
|
|
627653
|
+
]
|
|
627654
|
+
});
|
|
627258
627655
|
} catch {
|
|
627259
627656
|
}
|
|
627260
627657
|
this.saveTelegramConversationState(sessionKey);
|
|
@@ -628986,7 +629383,7 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`,
|
|
|
628986
629383
|
routeInstruction,
|
|
628987
629384
|
``,
|
|
628988
629385
|
`Return JSON only with this schema:`,
|
|
628989
|
-
`{"recoverable":true|false,"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note","procedure_note":"short tree/procedure note","voice_note":"short final-voice note","scenario_note":"short scenario/transition note","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition"}`,
|
|
629386
|
+
`{"recoverable":true|false,"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note","procedure_note":"short tree/procedure note","voice_note":"short final-voice note","scenario_note":"short scenario/transition note","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition","reply_mode_preference":null|{"scope":"current_user_in_chat"|"current_user_global"|"current_group","reply_mode":"reply_then_notes"|"notes_then_reply"|"reply_only","confidence":0.0-1.0,"note":"why this durable preference was explicitly expressed"}}`,
|
|
628990
629387
|
``,
|
|
628991
629388
|
`Original router output:`,
|
|
628992
629389
|
rawPreview,
|
|
@@ -629050,7 +629447,7 @@ ${userPrompt.slice(-4e3)}` : userPrompt;
|
|
|
629050
629447
|
`Return exactly one JSON object and no prose. No <think> tags. No commentary.`,
|
|
629051
629448
|
routeInstruction,
|
|
629052
629449
|
``,
|
|
629053
|
-
`Required schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note","procedure_note":"short tree/procedure note","voice_note":"short final-voice note","scenario_note":"short scenario/transition note","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition"}`,
|
|
629450
|
+
`Required schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note","procedure_note":"short tree/procedure note","voice_note":"short final-voice note","scenario_note":"short scenario/transition note","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition","reply_mode_preference":null|{"scope":"current_user_in_chat"|"current_user_global"|"current_group","reply_mode":"reply_then_notes"|"notes_then_reply"|"reply_only","confidence":0.0-1.0,"note":"why this durable preference was explicitly expressed"}}`,
|
|
629054
629451
|
``,
|
|
629055
629452
|
`Invalid previous output, for diagnostics only:`,
|
|
629056
629453
|
invalidPreview,
|
|
@@ -629350,6 +629747,7 @@ ${retryText}`,
|
|
|
629350
629747
|
`Platform salience signals (context only, not triggers): ${identitySalienceSignals.length ? identitySalienceSignals.join(", ") : "none"}`,
|
|
629351
629748
|
`Current chat type: ${msg.chatType}`,
|
|
629352
629749
|
`Current sender: ${telegramSpeakerLabel(msg)} [${telegramActorKindLabel(msg)}]`,
|
|
629750
|
+
this.formatTelegramDeliveryCapabilityContext(sessionKey, msg),
|
|
629353
629751
|
msg.replyToMessageId ? `Current message replies to message_id ${msg.replyToMessageId}` : "",
|
|
629354
629752
|
msg.replyToUsername ? `Current message replies to @${msg.replyToUsername}${msg.replyToBot ? " [bot]" : " [human/unknown]"}` : "",
|
|
629355
629753
|
currentReplyContext,
|
|
@@ -629414,7 +629812,7 @@ ${stimulationProbe.context}`,
|
|
|
629414
629812
|
`Use the persona docs below as binding behavioral guidance for whether speaking is appropriate and how to avoid over-eager or adversarially bad interventions.`,
|
|
629415
629813
|
`Return JSON only, with no markdown and no explanation outside JSON.`,
|
|
629416
629814
|
``,
|
|
629417
|
-
`Schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note","procedure_note":"short tree/procedure note","voice_note":"short final-voice note","scenario_note":"short scenario/transition note","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition"}`,
|
|
629815
|
+
`Schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note","procedure_note":"short tree/procedure note","voice_note":"short final-voice note","scenario_note":"short scenario/transition note","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition","reply_mode_preference":null|{"scope":"current_user_in_chat"|"current_user_global"|"current_group","reply_mode":"reply_then_notes"|"notes_then_reply"|"reply_only","confidence":0.0-1.0,"note":"why this durable preference was explicitly expressed"}}`,
|
|
629418
629816
|
``,
|
|
629419
629817
|
`Route meanings:`,
|
|
629420
629818
|
`- chat: a short conversational answer can be produced without tools.`,
|
|
@@ -629426,6 +629824,8 @@ ${stimulationProbe.context}`,
|
|
|
629426
629824
|
`High-salience evidence: private DMs, exact @username matches, display-name self references, and replies to this bot are notification-like signals. They should usually move attention toward deeper processing and a likely response unless the surrounding context makes silence more natural.`,
|
|
629427
629825
|
`No keyword routing: do not use static keyword rules. Infer whether identity references are actually aimed at this bot from syntax, tone, recent turns, and relationships.`,
|
|
629428
629826
|
`Observation notes: always fill silent_disposition, mental_note, memory_note, relationship_note, procedure_note, voice_note, scenario_note, scenario_id, scenario_label, scenario_confidence, scenario_objective, and scenario_state_loop with concise outcome-level notes for the TUI. Do not expose hidden chain-of-thought; summarize what the bot did with the heard message.`,
|
|
629827
|
+
`Reply-mode preference capture: if and only if the current sender explicitly expresses a durable preference for reply cadence/order, populate reply_mode_preference as a typed update. Do not infer this from style, keywords, tone, or one-off task shape. Use null otherwise.`,
|
|
629828
|
+
`Reply-mode meanings: reply_then_notes means visible reply first and internal notes afterward; notes_then_reply means internal notes before visible reply; reply_only means one user-facing reply with tools/context and no extra internal notes stage.`,
|
|
629429
629829
|
`Bot-to-bot discipline: sender labels include [bot] or [human]. Treat peer bots as autonomous actors, not human users. Avoid bot loops by replying only when the exchange context makes a response socially useful.`,
|
|
629430
629830
|
`Ingress discipline: this Telegram message has already been retained as chat context. should_reply controls only whether to emit a visible reply.`,
|
|
629431
629831
|
`Memory discipline: use durable associative user memory, relationships, prior actions, and recent context to infer whether this speaker is continuing a bot-related thread. A mention is not required when the semantic target is clearly the bot or an ongoing bot-mediated discussion.`,
|
|
@@ -630233,6 +630633,11 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
630233
630633
|
if (replyParameters) body["reply_parameters"] = replyParameters;
|
|
630234
630634
|
const result = await this.apiCall("sendMessage", body);
|
|
630235
630635
|
this.state.messagesSent++;
|
|
630636
|
+
this.updateTelegramTextDeliveryCapability(chatId, {
|
|
630637
|
+
status: "allowed",
|
|
630638
|
+
canSendText: true,
|
|
630639
|
+
source: "sendLiveMessage"
|
|
630640
|
+
});
|
|
630236
630641
|
return result.result?.message_id ?? null;
|
|
630237
630642
|
} catch {
|
|
630238
630643
|
try {
|
|
@@ -630244,8 +630649,26 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
630244
630649
|
if (replyParameters) body["reply_parameters"] = replyParameters;
|
|
630245
630650
|
const result = await this.apiCall("sendMessage", body);
|
|
630246
630651
|
this.state.messagesSent++;
|
|
630652
|
+
this.updateTelegramTextDeliveryCapability(chatId, {
|
|
630653
|
+
status: "allowed",
|
|
630654
|
+
canSendText: true,
|
|
630655
|
+
source: "sendLiveMessage.plain_fallback"
|
|
630656
|
+
});
|
|
630247
630657
|
return result.result?.message_id ?? null;
|
|
630248
|
-
} catch {
|
|
630658
|
+
} catch (err) {
|
|
630659
|
+
const errStr = err instanceof Error ? err.message : String(err);
|
|
630660
|
+
this.tuiWrite(() => renderWarning(`Failed to send Telegram live message: ${errStr}`));
|
|
630661
|
+
this.updateTelegramTextDeliveryCapability(chatId, {
|
|
630662
|
+
status: "failed",
|
|
630663
|
+
reason: errStr,
|
|
630664
|
+
source: "sendLiveMessage"
|
|
630665
|
+
});
|
|
630666
|
+
getSoulObservationStream().emit({
|
|
630667
|
+
kind: "telegram.send.failed",
|
|
630668
|
+
sessionKey: String(chatId),
|
|
630669
|
+
reason: errStr,
|
|
630670
|
+
ts: Date.now()
|
|
630671
|
+
});
|
|
630249
630672
|
return null;
|
|
630250
630673
|
}
|
|
630251
630674
|
}
|
|
@@ -630480,14 +630903,29 @@ Join: ${newUrl}`);
|
|
|
630480
630903
|
} catch (err) {
|
|
630481
630904
|
decision2 = this.fallbackTelegramRouterDecision(msg, toolContext, err);
|
|
630482
630905
|
}
|
|
630483
|
-
this.
|
|
630906
|
+
const storedPreference = this.applyTelegramReplyPreferenceUpdate(
|
|
630484
630907
|
sessionKey,
|
|
630485
630908
|
msg,
|
|
630486
|
-
|
|
630487
|
-
|
|
630488
|
-
this.telegramMessageIdentitySalienceSignals(msg),
|
|
630489
|
-
this.markLatestTelegramDaydreamOpportunitiesConsidered(sessionKey, msg)
|
|
630909
|
+
decision2.replyPreferenceUpdate,
|
|
630910
|
+
"telegram-router"
|
|
630490
630911
|
);
|
|
630912
|
+
if (storedPreference) this.subAgentViewCallbacks?.onWrite(attentionViewId || this.viewIdForMessage(msg), `preference: ${storedPreference}`);
|
|
630913
|
+
const replyMode = this.resolvedTelegramReplyMode(sessionKey, msg);
|
|
630914
|
+
const deliveredDecision = replyMode === "reply_only" ? this.stripTelegramDecisionNotes(decision2) : decision2;
|
|
630915
|
+
const daydreamOpportunities = this.markLatestTelegramDaydreamOpportunitiesConsidered(sessionKey, msg);
|
|
630916
|
+
const shouldDeferNotes = replyMode === "reply_then_notes" && decision2.shouldReply;
|
|
630917
|
+
if (!shouldDeferNotes) {
|
|
630918
|
+
this.deliverTelegramAttentionDecision(
|
|
630919
|
+
sessionKey,
|
|
630920
|
+
msg,
|
|
630921
|
+
attentionViewId,
|
|
630922
|
+
deliveredDecision,
|
|
630923
|
+
this.telegramMessageIdentitySalienceSignals(msg),
|
|
630924
|
+
daydreamOpportunities
|
|
630925
|
+
);
|
|
630926
|
+
} else if (attentionViewId && this.subAgentViewCallbacks) {
|
|
630927
|
+
this.subAgentViewCallbacks.onWrite(attentionViewId, `reply mode: reply_then_notes; internal notes will be committed after visible reply attempt`);
|
|
630928
|
+
}
|
|
630491
630929
|
this.markLastTelegramUserMessageMode(msg, decision2.shouldReply ? decision2.route : "ambient");
|
|
630492
630930
|
this.subAgentViewCallbacks?.onWrite(
|
|
630493
630931
|
this.viewIdForMessage(msg),
|
|
@@ -630497,7 +630935,7 @@ Join: ${newUrl}`);
|
|
|
630497
630935
|
this.maybeLogTelegramGroupSkip(msg, `live inference: no reply — ${decision2.reason}`);
|
|
630498
630936
|
return;
|
|
630499
630937
|
}
|
|
630500
|
-
const decisionContext = this.formatTelegramAttentionDecisionContext(
|
|
630938
|
+
const decisionContext = this.formatTelegramAttentionDecisionContext(deliveredDecision);
|
|
630501
630939
|
const existingAfterDecision = this.subAgents.get(sessionKey);
|
|
630502
630940
|
if (existingAfterDecision && !existingAfterDecision.aborted) {
|
|
630503
630941
|
this.subAgentViewCallbacks?.onWrite(
|
|
@@ -630506,11 +630944,31 @@ Join: ${newUrl}`);
|
|
|
630506
630944
|
);
|
|
630507
630945
|
this.enqueueTelegramSubAgentContext(sessionKey, existingAfterDecision, decisionContext, msg.username);
|
|
630508
630946
|
await this.enqueueTelegramQueuedSessionWorkForExistingSubAgent(work, existingAfterDecision);
|
|
630947
|
+
if (shouldDeferNotes) {
|
|
630948
|
+
this.deliverTelegramAttentionDecision(
|
|
630949
|
+
sessionKey,
|
|
630950
|
+
msg,
|
|
630951
|
+
attentionViewId,
|
|
630952
|
+
deliveredDecision,
|
|
630953
|
+
this.telegramMessageIdentitySalienceSignals(msg),
|
|
630954
|
+
daydreamOpportunities
|
|
630955
|
+
);
|
|
630956
|
+
}
|
|
630509
630957
|
return;
|
|
630510
630958
|
}
|
|
630511
630959
|
const subAgentProfile = decision2.route === "chat" ? "chat" : "action";
|
|
630512
630960
|
if (decision2.route === "chat" && msg.chatType === "private") {
|
|
630513
630961
|
await this.handleTelegramChatCompletion(msg, toolContext, [decisionContext, rapidContext].filter(Boolean).join("\n\n"));
|
|
630962
|
+
if (shouldDeferNotes) {
|
|
630963
|
+
this.deliverTelegramAttentionDecision(
|
|
630964
|
+
sessionKey,
|
|
630965
|
+
msg,
|
|
630966
|
+
attentionViewId,
|
|
630967
|
+
deliveredDecision,
|
|
630968
|
+
this.telegramMessageIdentitySalienceSignals(msg),
|
|
630969
|
+
daydreamOpportunities
|
|
630970
|
+
);
|
|
630971
|
+
}
|
|
630514
630972
|
return;
|
|
630515
630973
|
}
|
|
630516
630974
|
const subAgent = {
|
|
@@ -630595,6 +631053,16 @@ Join: ${newUrl}`);
|
|
|
630595
631053
|
await this.deleteLiveMessage(msg.chatId, subAgent.liveMessageId).catch(() => {
|
|
630596
631054
|
});
|
|
630597
631055
|
}
|
|
631056
|
+
if (shouldDeferNotes) {
|
|
631057
|
+
this.deliverTelegramAttentionDecision(
|
|
631058
|
+
sessionKey,
|
|
631059
|
+
msg,
|
|
631060
|
+
attentionViewId,
|
|
631061
|
+
deliveredDecision,
|
|
631062
|
+
this.telegramMessageIdentitySalienceSignals(msg),
|
|
631063
|
+
daydreamOpportunities
|
|
631064
|
+
);
|
|
631065
|
+
}
|
|
630598
631066
|
return;
|
|
630599
631067
|
}
|
|
630600
631068
|
if (subAgent.liveMessagePromise) {
|
|
@@ -630603,16 +631071,30 @@ Join: ${newUrl}`);
|
|
|
630603
631071
|
}
|
|
630604
631072
|
const finalHtml = convertMarkdownToTelegramHTML(finalText);
|
|
630605
631073
|
const sentMessageId = await this.sendOrEditFinalTelegramHTML(msg, finalHtml, subAgent.liveMessageId);
|
|
630606
|
-
|
|
630607
|
-
|
|
630608
|
-
|
|
630609
|
-
|
|
631074
|
+
if (sentMessageId !== null || msg.guestQueryId) {
|
|
631075
|
+
this.recordTelegramAssistantMessage(msg, finalText, subAgentProfile, {
|
|
631076
|
+
messageId: sentMessageId,
|
|
631077
|
+
replyToMessageId: msg.chatType !== "private" ? msg.messageId : void 0
|
|
631078
|
+
});
|
|
631079
|
+
} else {
|
|
631080
|
+
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, "Telegram text send returned no delivered message id");
|
|
631081
|
+
}
|
|
630610
631082
|
await this.sendGeneratedArtifactsFromSubAgent(
|
|
630611
631083
|
msg,
|
|
630612
631084
|
subAgent,
|
|
630613
631085
|
finalText,
|
|
630614
631086
|
Boolean(subAgent.liveMessageId && !msg.guestQueryId)
|
|
630615
631087
|
);
|
|
631088
|
+
if (shouldDeferNotes) {
|
|
631089
|
+
this.deliverTelegramAttentionDecision(
|
|
631090
|
+
sessionKey,
|
|
631091
|
+
msg,
|
|
631092
|
+
attentionViewId,
|
|
631093
|
+
deliveredDecision,
|
|
631094
|
+
this.telegramMessageIdentitySalienceSignals(msg),
|
|
631095
|
+
daydreamOpportunities
|
|
631096
|
+
);
|
|
631097
|
+
}
|
|
630616
631098
|
this.tuiWrite(() => renderTelegramSubAgentComplete(msg.username, finalText));
|
|
630617
631099
|
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, `completed: ${finalText}`);
|
|
630618
631100
|
this.subAgentViewCallbacks?.onStatus(subAgent.viewId, "completed");
|
|
@@ -630633,6 +631115,16 @@ Join: ${newUrl}`);
|
|
|
630633
631115
|
await this.deleteLiveMessage(msg.chatId, subAgent.liveMessageId).catch(() => {
|
|
630634
631116
|
});
|
|
630635
631117
|
}
|
|
631118
|
+
if (shouldDeferNotes) {
|
|
631119
|
+
this.deliverTelegramAttentionDecision(
|
|
631120
|
+
sessionKey,
|
|
631121
|
+
msg,
|
|
631122
|
+
attentionViewId,
|
|
631123
|
+
deliveredDecision,
|
|
631124
|
+
this.telegramMessageIdentitySalienceSignals(msg),
|
|
631125
|
+
daydreamOpportunities
|
|
631126
|
+
);
|
|
631127
|
+
}
|
|
630636
631128
|
} finally {
|
|
630637
631129
|
this.clearTelegramSubAgentContextBuffer(sessionKey);
|
|
630638
631130
|
this.subAgents.delete(sessionKey);
|
|
@@ -630716,10 +631208,14 @@ Join: ${newUrl}`);
|
|
|
630716
631208
|
}
|
|
630717
631209
|
const finalHtml = convertMarkdownToTelegramHTML(finalText);
|
|
630718
631210
|
const sentMessageId = await this.sendOrEditFinalTelegramHTML(msg, finalHtml, subAgent.liveMessageId);
|
|
630719
|
-
|
|
630720
|
-
|
|
630721
|
-
|
|
630722
|
-
|
|
631211
|
+
if (sentMessageId !== null || msg.guestQueryId) {
|
|
631212
|
+
this.recordTelegramAssistantMessage(msg, finalText, "chat", {
|
|
631213
|
+
messageId: sentMessageId,
|
|
631214
|
+
replyToMessageId: msg.chatType !== "private" ? msg.messageId : void 0
|
|
631215
|
+
});
|
|
631216
|
+
} else {
|
|
631217
|
+
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, "Telegram text send returned no delivered message id");
|
|
631218
|
+
}
|
|
630723
631219
|
await this.sendGeneratedArtifactsFromSubAgent(
|
|
630724
631220
|
msg,
|
|
630725
631221
|
subAgent,
|
|
@@ -630845,10 +631341,14 @@ Join: ${newUrl}`);
|
|
|
630845
631341
|
}
|
|
630846
631342
|
const finalHtml = convertMarkdownToTelegramHTML(cleaned);
|
|
630847
631343
|
const sentMessageId = await this.sendOrEditFinalTelegramHTML(msg, finalHtml, liveMessageId);
|
|
630848
|
-
|
|
630849
|
-
|
|
630850
|
-
|
|
630851
|
-
|
|
631344
|
+
if (sentMessageId !== null || msg.guestQueryId) {
|
|
631345
|
+
this.recordTelegramAssistantMessage(msg, cleaned, "chat", {
|
|
631346
|
+
messageId: sentMessageId,
|
|
631347
|
+
replyToMessageId: msg.chatType !== "private" ? msg.messageId : void 0
|
|
631348
|
+
});
|
|
631349
|
+
} else {
|
|
631350
|
+
this.subAgentViewCallbacks?.onWrite(viewId, "Telegram text send returned no delivered message id");
|
|
631351
|
+
}
|
|
630852
631352
|
this.subAgentViewCallbacks?.onWrite(viewId, `completed: ${cleaned}`);
|
|
630853
631353
|
this.subAgentViewCallbacks?.onStatus(viewId, "completed");
|
|
630854
631354
|
} catch (err) {
|
|
@@ -631244,6 +631744,7 @@ ${currentTelegramPrompt}`;
|
|
|
631244
631744
|
"You have access to isolated per-chat memory (memory_write, memory_read, memory_search) scoped to this conversation.",
|
|
631245
631745
|
"memory_search may use scope=group/current_chat for this group or scope=user with user_id/username for a participant in this same group. Other groups, admin chats, and private DMs are not accessible here.",
|
|
631246
631746
|
"You can remember facts about users and retrieve them later. Durable associative memory in the prompt includes participant profiles, relationships, scoped facts, and prior actions retained across days, sessions, and Omnius updates. You also have web_search and web_fetch to look up information.",
|
|
631747
|
+
"If a user explicitly states a durable preference for reply cadence/order, call telegram_preference_set. Do not infer or classify reply-mode preferences from keywords, style, tone, or task type.",
|
|
631247
631748
|
"You have the full scoped Telegram media-analysis stack by default: telegram_media_recent, image_read, ocr, ocr_image_advanced, vision, pdf_to_text, ocr_pdf, transcribe_file, video_understand, audio_analyze, and identity_memory. For complex textual imagery, screenshots, forms, scans, or dense labels, prefer ocr_image_advanced after resolving media with path='reply' or path='latest'.",
|
|
631248
631749
|
formatIdentityMemoryContext(chatLabel || "Telegram private chat"),
|
|
631249
631750
|
reminderToolContract,
|
|
@@ -631996,6 +632497,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
631996
632497
|
new SkillListTool(repoRoot),
|
|
631997
632498
|
sharedSkillExtractTool,
|
|
631998
632499
|
this.buildTelegramMediaRecentTool(chatId, msg),
|
|
632500
|
+
this.buildTelegramReplyPreferenceTool(context2, chatId, msg),
|
|
631999
632501
|
this.buildTelegramTool(context2, repoRoot, chatId, msg),
|
|
632000
632502
|
...this.buildTelegramReminderTools(context2, repoRoot, chatId, msg)
|
|
632001
632503
|
];
|
|
@@ -632061,6 +632563,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
632061
632563
|
new SkillListTool(repoRoot),
|
|
632062
632564
|
new SkillExecuteTool(repoRoot),
|
|
632063
632565
|
adminSkillExtractTool,
|
|
632566
|
+
this.buildTelegramReplyPreferenceTool(context2, chatId, msg),
|
|
632064
632567
|
this.buildTelegramTool(context2, repoRoot, chatId, msg),
|
|
632065
632568
|
...this.buildTelegramReminderTools(context2, repoRoot, chatId, msg),
|
|
632066
632569
|
fullSubAgentTool,
|
|
@@ -632318,8 +632821,9 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
632318
632821
|
const text = String(args["text"] || "").trim();
|
|
632319
632822
|
if (!text) throw new Error("text is required for send_message.");
|
|
632320
632823
|
if (dryRun) return this.telegramDryRun(action, targetChatId, { text });
|
|
632321
|
-
const sent = await this.
|
|
632322
|
-
|
|
632824
|
+
const sent = await this.sendMessageDetailed(targetChatId, text);
|
|
632825
|
+
if (!sent.ok) throw new Error(sent.reason || `Telegram send_message ${sent.status}`);
|
|
632826
|
+
return { action, telegram_method: "sendMessage", ok: true, chat_id: targetChatId, message_id: sent.messageId ?? null };
|
|
632323
632827
|
}
|
|
632324
632828
|
case "edit_message_text": {
|
|
632325
632829
|
if (targetChatId === void 0 || messageId === void 0) throw new Error("target/chat_id and message_id are required for edit_message_text.");
|
|
@@ -633233,6 +633737,64 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
633233
633737
|
resolveMedia: (ref, args) => this.resolveTelegramIdentityMedia(chatId, currentMsg, ref, args)
|
|
633234
633738
|
});
|
|
633235
633739
|
}
|
|
633740
|
+
buildTelegramReplyPreferenceTool(_context, _chatId, currentMsg) {
|
|
633741
|
+
const bridge = this;
|
|
633742
|
+
return {
|
|
633743
|
+
name: "telegram_preference_set",
|
|
633744
|
+
description: [
|
|
633745
|
+
"Store an explicitly stated Telegram reply-mode preference for the current user or group.",
|
|
633746
|
+
"Use only when the user directly expresses a durable preference; do not infer from style, tone, keywords, or task type.",
|
|
633747
|
+
"This stores internal behavior preferences only and does not send a Telegram message."
|
|
633748
|
+
].join(" "),
|
|
633749
|
+
parameters: {
|
|
633750
|
+
type: "object",
|
|
633751
|
+
properties: {
|
|
633752
|
+
scope: {
|
|
633753
|
+
type: "string",
|
|
633754
|
+
enum: ["current_user_in_chat", "current_user_global", "current_group"],
|
|
633755
|
+
description: "Where to store the preference. Default current_user_in_chat for public/group contexts."
|
|
633756
|
+
},
|
|
633757
|
+
reply_mode: {
|
|
633758
|
+
type: "string",
|
|
633759
|
+
enum: ["reply_then_notes", "notes_then_reply", "reply_only"],
|
|
633760
|
+
description: "reply_then_notes = visible reply first, then internal notes; notes_then_reply = internal notes first; reply_only = one reply with tools/context and no extra internal notes stage."
|
|
633761
|
+
},
|
|
633762
|
+
confidence: { type: "number", description: "Confidence that the user explicitly expressed this durable preference, 0.0-1.0." },
|
|
633763
|
+
note: { type: "string", description: "Short evidence/rationale from the user's message." }
|
|
633764
|
+
},
|
|
633765
|
+
required: ["reply_mode"]
|
|
633766
|
+
},
|
|
633767
|
+
async execute(args) {
|
|
633768
|
+
const start2 = performance.now();
|
|
633769
|
+
if (!currentMsg) {
|
|
633770
|
+
return { success: false, output: "", error: "No current Telegram message is available for preference scope.", durationMs: performance.now() - start2 };
|
|
633771
|
+
}
|
|
633772
|
+
const replyMode = parseTelegramReplyMode(args["reply_mode"] ?? args["replyMode"] ?? args["mode"]);
|
|
633773
|
+
if (!replyMode) {
|
|
633774
|
+
return { success: false, output: "", error: "reply_mode must be reply_then_notes, notes_then_reply, or reply_only.", durationMs: performance.now() - start2 };
|
|
633775
|
+
}
|
|
633776
|
+
const scope = parseTelegramReplyPreferenceToolScope(args["scope"]) ?? "current_user_in_chat";
|
|
633777
|
+
const confidenceRaw = Number(args["confidence"]);
|
|
633778
|
+
const update2 = {
|
|
633779
|
+
scope,
|
|
633780
|
+
replyMode,
|
|
633781
|
+
confidence: Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : void 0,
|
|
633782
|
+
note: typeof args["note"] === "string" ? args["note"].trim().slice(0, 220) : void 0,
|
|
633783
|
+
source: "telegram_preference_set"
|
|
633784
|
+
};
|
|
633785
|
+
const sessionKey = bridge.sessionKeyForMessage(currentMsg);
|
|
633786
|
+
const stored = bridge.applyTelegramReplyPreferenceUpdate(sessionKey, currentMsg, update2, "telegram_preference_set");
|
|
633787
|
+
return {
|
|
633788
|
+
success: true,
|
|
633789
|
+
output: stored || `stored reply_mode=${replyMode}`,
|
|
633790
|
+
llmContent: stored || `Stored Telegram reply preference ${replyMode}.`,
|
|
633791
|
+
durationMs: performance.now() - start2,
|
|
633792
|
+
mutated: true,
|
|
633793
|
+
mutatedFiles: []
|
|
633794
|
+
};
|
|
633795
|
+
}
|
|
633796
|
+
};
|
|
633797
|
+
}
|
|
633236
633798
|
buildTelegramMediaRecentTool(chatId, currentMsg) {
|
|
633237
633799
|
const bridge = this;
|
|
633238
633800
|
return {
|
|
@@ -633743,17 +634305,25 @@ ${text}`.trim());
|
|
|
633743
634305
|
// ── Message sending ───────────────────────────────────────────────────
|
|
633744
634306
|
/** Send a response back to a Telegram chat (Markdown → HTML conversion) */
|
|
633745
634307
|
async sendMessage(chatId, text, replyToMessageId, options2 = {}) {
|
|
634308
|
+
const result = await this.sendMessageDetailed(chatId, text, replyToMessageId, options2);
|
|
634309
|
+
return result.messageId ?? null;
|
|
634310
|
+
}
|
|
634311
|
+
async sendMessageDetailed(chatId, text, replyToMessageId, options2 = {}) {
|
|
633746
634312
|
const extracted = extractMediaReferences(text);
|
|
633747
634313
|
const mediaRefs = this.filterTelegramMediaReferences(extracted.media, options2);
|
|
633748
634314
|
const html = convertMarkdownToTelegramHTML(extracted.text);
|
|
633749
|
-
const
|
|
634315
|
+
const textResult = extracted.text.trim() ? await this.sendMessageHTMLDetailed(chatId, html, replyToMessageId, options2) : { ok: true, status: "sent", chatId, messageId: null };
|
|
633750
634316
|
for (const media of mediaRefs) {
|
|
633751
634317
|
await this.sendMediaReference(chatId, media, { replyToMessageId }).catch(() => null);
|
|
633752
634318
|
}
|
|
633753
|
-
return
|
|
634319
|
+
return textResult;
|
|
633754
634320
|
}
|
|
633755
634321
|
/** Send an HTML-formatted message to a Telegram chat */
|
|
633756
634322
|
async sendMessageHTML(chatId, html, replyToMessageId, options2 = {}) {
|
|
634323
|
+
const result = await this.sendMessageHTMLDetailed(chatId, html, replyToMessageId, options2);
|
|
634324
|
+
return result.messageId ?? null;
|
|
634325
|
+
}
|
|
634326
|
+
async sendMessageHTMLDetailed(chatId, html, replyToMessageId, options2 = {}) {
|
|
633757
634327
|
const extracted = extractMediaReferences(html);
|
|
633758
634328
|
const mediaRefs = this.filterTelegramMediaReferences(extracted.media, options2);
|
|
633759
634329
|
const sendHtml = extracted.text || (extracted.media.length > 0 ? "" : html);
|
|
@@ -633768,7 +634338,7 @@ ${text}`.trim());
|
|
|
633768
634338
|
).catch(() => null);
|
|
633769
634339
|
if (sentId === null) sentId = mediaId;
|
|
633770
634340
|
}
|
|
633771
|
-
return sentId;
|
|
634341
|
+
return { ok: sentId !== null || mediaRefs.length === 0, status: "sent", chatId, messageId: sentId };
|
|
633772
634342
|
}
|
|
633773
634343
|
const chunks = splitTelegramMessageText(sendHtml, 3900);
|
|
633774
634344
|
for (let idx = 0; idx < chunks.length; idx++) {
|
|
@@ -633786,6 +634356,11 @@ ${text}`.trim());
|
|
|
633786
634356
|
if (result.ok === false) throw new Error(String(result.description || "Telegram sendMessage failed"));
|
|
633787
634357
|
this.state.messagesSent++;
|
|
633788
634358
|
if (sentId === null) sentId = result.result?.message_id ?? null;
|
|
634359
|
+
this.updateTelegramTextDeliveryCapability(chatId, {
|
|
634360
|
+
status: "allowed",
|
|
634361
|
+
canSendText: true,
|
|
634362
|
+
source: "sendMessage"
|
|
634363
|
+
});
|
|
633789
634364
|
getSoulObservationStream().emit({
|
|
633790
634365
|
kind: "telegram.send.success",
|
|
633791
634366
|
sessionKey: sessionKeyForObs,
|
|
@@ -633801,6 +634376,11 @@ ${text}`.trim());
|
|
|
633801
634376
|
if (result.ok === false) throw new Error(String(result.description || "Telegram sendMessage failed"));
|
|
633802
634377
|
this.state.messagesSent++;
|
|
633803
634378
|
if (sentId === null) sentId = result.result?.message_id ?? null;
|
|
634379
|
+
this.updateTelegramTextDeliveryCapability(chatId, {
|
|
634380
|
+
status: "allowed",
|
|
634381
|
+
canSendText: true,
|
|
634382
|
+
source: "sendMessage.plain_fallback"
|
|
634383
|
+
});
|
|
633804
634384
|
getSoulObservationStream().emit({
|
|
633805
634385
|
kind: "telegram.send.success",
|
|
633806
634386
|
sessionKey: sessionKeyForObs,
|
|
@@ -633810,30 +634390,25 @@ ${text}`.trim());
|
|
|
633810
634390
|
} catch (err) {
|
|
633811
634391
|
this.tuiWrite(() => renderWarning(`Failed to send Telegram message: ${err instanceof Error ? err.message : String(err)}`));
|
|
633812
634392
|
const errStr = err instanceof Error ? err.message : String(err);
|
|
633813
|
-
|
|
633814
|
-
|
|
633815
|
-
|
|
633816
|
-
|
|
633817
|
-
|
|
633818
|
-
|
|
633819
|
-
|
|
633820
|
-
|
|
633821
|
-
|
|
633822
|
-
|
|
633823
|
-
|
|
633824
|
-
|
|
633825
|
-
sessionKey: sessionKeyForObs,
|
|
633826
|
-
retryAfterSec: m2 ? parseInt(m2[1], 10) : void 0,
|
|
633827
|
-
ts: Date.now()
|
|
633828
|
-
});
|
|
633829
|
-
}
|
|
634393
|
+
this.updateTelegramTextDeliveryCapability(chatId, {
|
|
634394
|
+
status: "failed",
|
|
634395
|
+
reason: errStr,
|
|
634396
|
+
source: "sendMessage"
|
|
634397
|
+
});
|
|
634398
|
+
getSoulObservationStream().emit({
|
|
634399
|
+
kind: "telegram.send.failed",
|
|
634400
|
+
sessionKey: sessionKeyForObs,
|
|
634401
|
+
reason: errStr,
|
|
634402
|
+
ts: Date.now()
|
|
634403
|
+
});
|
|
634404
|
+
return { ok: false, status: "failed", chatId, messageId: sentId, reason: errStr };
|
|
633830
634405
|
}
|
|
633831
634406
|
}
|
|
633832
634407
|
}
|
|
633833
634408
|
for (const media of mediaRefs) {
|
|
633834
634409
|
await this.sendMediaReference(chatId, media).catch(() => null);
|
|
633835
634410
|
}
|
|
633836
|
-
return sentId;
|
|
634411
|
+
return { ok: sentId !== null, status: "sent", chatId, messageId: sentId };
|
|
633837
634412
|
}
|
|
633838
634413
|
filterTelegramMediaReferences(media, options2) {
|
|
633839
634414
|
const suppress = options2.suppressMedia;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.158",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.158",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED