omnius 1.0.60 → 1.0.61
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 +208 -24
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12159,17 +12159,26 @@ process.on('unhandledRejection', (reason) => {
|
|
|
12159
12159
|
|
|
12160
12160
|
dlog('COHERE response: ' + _cData.queryId + ' model=' + _cModel + ' tier=' + ['trivial','moderate','complex','expert'][_cTier] + ' ' + _cLatency + 'ms' + (_cReviewed ? ' (reviewed)' : ''));
|
|
12161
12161
|
// IK-01: Update identity on query success
|
|
12162
|
+
// Store full query + response content; downstream renderers (narrative summary, prompts)
|
|
12163
|
+
// are responsible for compaction. Truncating at write time destroys identity history.
|
|
12164
|
+
// NOTE: '\\n' is double-escaped because this whole block runs inside the
|
|
12165
|
+
// outer DAEMON_SCRIPT template literal — see comment near line 440.
|
|
12162
12166
|
_updateIdentity({ type: 'query_served', outcome: 1.0, details: {
|
|
12163
12167
|
latencyMs: _cLatency, toolsUsed: _cToolsUsed, model: _cModel,
|
|
12164
|
-
|
|
12168
|
+
query: _cData.query || '',
|
|
12169
|
+
response: _cFinalContent || '',
|
|
12170
|
+
summary: (_cData.query || '') + (_cFinalContent ? '\\n→ ' + _cFinalContent : '')
|
|
12165
12171
|
}});
|
|
12166
12172
|
} catch (_cErr) {
|
|
12167
12173
|
dlog('COHERE inference error: ' + (_cErr.message || _cErr));
|
|
12168
12174
|
_cohereStats.queriesErrors++;
|
|
12169
12175
|
_saveStats();
|
|
12170
12176
|
// IK-01: Update identity on query failure
|
|
12177
|
+
// Preserve the full error so post-hoc diagnosis is possible.
|
|
12171
12178
|
_updateIdentity({ type: 'query_failed', outcome: 0, details: {
|
|
12172
|
-
error: (_cErr.message || String(_cErr)
|
|
12179
|
+
error: (_cErr && _cErr.message) || String(_cErr),
|
|
12180
|
+
query: _cData.query || '',
|
|
12181
|
+
summary: 'inference error: ' + ((_cErr && _cErr.message) || String(_cErr))
|
|
12173
12182
|
}});
|
|
12174
12183
|
}
|
|
12175
12184
|
} catch (_cParseErr) {
|
|
@@ -593168,12 +593177,16 @@ sleep 1
|
|
|
593168
593177
|
return "handled";
|
|
593169
593178
|
}
|
|
593170
593179
|
if (requested !== "auto" && requested !== "chat" && requested !== "action") {
|
|
593171
|
-
renderWarning("Usage: /telegram mode auto|chat|action [--
|
|
593180
|
+
renderWarning("Usage: /telegram mode auto|chat|action [--global]");
|
|
593172
593181
|
return "handled";
|
|
593173
593182
|
}
|
|
593174
|
-
|
|
593183
|
+
const hasGlobalFlagMode = parts.includes("--global");
|
|
593184
|
+
const projectRootMode = ctx3.repoRoot || process.cwd();
|
|
593185
|
+
const projectHasOmniusMode = existsSync100(join114(projectRootMode, ".omnius"));
|
|
593186
|
+
const wantsLocalMode = hasGlobalFlagMode ? false : isLocal || projectHasOmniusMode;
|
|
593187
|
+
ctx3.saveTelegramSettings?.({ mode: requested, local: wantsLocalMode });
|
|
593175
593188
|
ctx3.telegramSetInteractionMode?.(requested);
|
|
593176
|
-
renderInfo(`Telegram interaction mode set to ${c3.bold(requested)}${
|
|
593189
|
+
renderInfo(`Telegram interaction mode set to ${c3.bold(requested)}${wantsLocalMode ? " (project)" : " (global)"}.`);
|
|
593177
593190
|
return "handled";
|
|
593178
593191
|
}
|
|
593179
593192
|
if (parts[0] === "auth" || parts[0] === "authenticate") {
|
|
@@ -593420,18 +593433,23 @@ sleep 1
|
|
|
593420
593433
|
}
|
|
593421
593434
|
const keyIdx = parts.indexOf("--key");
|
|
593422
593435
|
const adminIdx = parts.indexOf("--admin");
|
|
593436
|
+
const hasGlobalFlag = parts.includes("--global");
|
|
593437
|
+
const projectRoot = ctx3.repoRoot || process.cwd();
|
|
593438
|
+
const projectHasOmnius = existsSync100(join114(projectRoot, ".omnius"));
|
|
593439
|
+
const wantsLocal = hasGlobalFlag ? false : isLocal || projectHasOmnius;
|
|
593423
593440
|
if (keyIdx !== -1 || adminIdx !== -1) {
|
|
593424
593441
|
const settings = {
|
|
593425
|
-
local:
|
|
593442
|
+
local: wantsLocal
|
|
593426
593443
|
};
|
|
593427
|
-
const scope =
|
|
593444
|
+
const scope = wantsLocal ? "project" : "global";
|
|
593428
593445
|
if (keyIdx !== -1) {
|
|
593429
593446
|
const token = parts[keyIdx + 1];
|
|
593430
593447
|
if (!token || token.startsWith("--")) {
|
|
593431
593448
|
renderWarning(
|
|
593432
|
-
"Usage: /telegram --key <bot-token> [--admin <id>] [--
|
|
593449
|
+
"Usage: /telegram --key <bot-token> [--admin <id>] [--global]"
|
|
593433
593450
|
);
|
|
593434
593451
|
renderInfo("Get a bot token from @BotFather on Telegram.");
|
|
593452
|
+
renderInfo("Default scope: project-local when .omnius/ exists; use --global to override.");
|
|
593435
593453
|
return "handled";
|
|
593436
593454
|
}
|
|
593437
593455
|
settings.key = token;
|
|
@@ -593440,7 +593458,7 @@ sleep 1
|
|
|
593440
593458
|
const userId = parts[adminIdx + 1];
|
|
593441
593459
|
if (!userId || userId.startsWith("--")) {
|
|
593442
593460
|
renderWarning(
|
|
593443
|
-
"Usage: /telegram --admin <user-id-or-username> [--key <token>] [--
|
|
593461
|
+
"Usage: /telegram --admin <user-id-or-username> [--key <token>] [--global]"
|
|
593444
593462
|
);
|
|
593445
593463
|
return "handled";
|
|
593446
593464
|
}
|
|
@@ -593455,6 +593473,11 @@ sleep 1
|
|
|
593455
593473
|
renderInfo(
|
|
593456
593474
|
`Telegram admin set to ${c3.bold(settings.admin)} (${scope}).`
|
|
593457
593475
|
);
|
|
593476
|
+
if (wantsLocal && !projectHasOmnius) {
|
|
593477
|
+
renderWarning(
|
|
593478
|
+
"No .omnius/ in the current directory; this 'local' setting was written to ./.omnius/settings.json and only applies when omnius is invoked from this folder."
|
|
593479
|
+
);
|
|
593480
|
+
}
|
|
593458
593481
|
if (!ctx3.isTelegramActive?.() && settings.key)
|
|
593459
593482
|
renderInfo("Use /telegram to start.");
|
|
593460
593483
|
return "handled";
|
|
@@ -593468,9 +593491,30 @@ sleep 1
|
|
|
593468
593491
|
if (!settings.key) {
|
|
593469
593492
|
renderWarning("No Telegram bot token configured.");
|
|
593470
593493
|
renderInfo("Set one first: /telegram --key <bot-token>");
|
|
593471
|
-
renderInfo("Get a token from @BotFather on Telegram.");
|
|
593494
|
+
renderInfo("Get a token from @BotFather on Telegram. The token saves project-locally by default when .omnius/ exists.");
|
|
593472
593495
|
return "handled";
|
|
593473
593496
|
}
|
|
593497
|
+
try {
|
|
593498
|
+
const startProjectRoot = ctx3.repoRoot || process.cwd();
|
|
593499
|
+
if (existsSync100(join114(startProjectRoot, ".omnius"))) {
|
|
593500
|
+
const projectSettingsPath = join114(startProjectRoot, ".omnius", "settings.json");
|
|
593501
|
+
let projectHasKey = false;
|
|
593502
|
+
if (existsSync100(projectSettingsPath)) {
|
|
593503
|
+
try {
|
|
593504
|
+
const projectJson = JSON.parse(readFileSync81(projectSettingsPath, "utf8"));
|
|
593505
|
+
projectHasKey = typeof projectJson?.telegramKey === "string" && projectJson.telegramKey.length > 0;
|
|
593506
|
+
} catch {
|
|
593507
|
+
}
|
|
593508
|
+
}
|
|
593509
|
+
if (!projectHasKey) {
|
|
593510
|
+
renderWarning(
|
|
593511
|
+
"Using GLOBAL Telegram token in a project that has no local key. Another omnius instance running with the same token will steal getUpdates and you'll see 409 conflicts."
|
|
593512
|
+
);
|
|
593513
|
+
renderInfo("Scope it locally: /telegram --key <token> (writes to ./.omnius/settings.json)");
|
|
593514
|
+
}
|
|
593515
|
+
}
|
|
593516
|
+
} catch {
|
|
593517
|
+
}
|
|
593474
593518
|
try {
|
|
593475
593519
|
await ctx3.telegramStart?.(settings.key, settings.admin);
|
|
593476
593520
|
} catch (err) {
|
|
@@ -593482,8 +593526,8 @@ sleep 1
|
|
|
593482
593526
|
}
|
|
593483
593527
|
renderWarning(`Unknown argument: "${arg}"`);
|
|
593484
593528
|
renderInfo("Usage:");
|
|
593485
|
-
renderInfo(" /telegram --key <token> Save bot token (
|
|
593486
|
-
renderInfo(" /telegram --admin <id> Set admin filter (
|
|
593529
|
+
renderInfo(" /telegram --key <token> Save bot token (project-local when .omnius/ exists)");
|
|
593530
|
+
renderInfo(" /telegram --admin <id> Set admin filter (project-local by default)");
|
|
593487
593531
|
renderInfo(" /telegram Toggle on/off");
|
|
593488
593532
|
renderInfo(" /telegram stop Stop bridge");
|
|
593489
593533
|
renderInfo(" /telegram status Show status");
|
|
@@ -593502,7 +593546,7 @@ sleep 1
|
|
|
593502
593546
|
renderInfo(" /telegram delete-messages <chat> <msg,msg> [reason] Delete multiple messages");
|
|
593503
593547
|
renderInfo(" /telegram delete-reaction <chat> <msg> --user <id> Delete a reaction");
|
|
593504
593548
|
renderInfo(" /telegram delete-reactions <chat> --user <id> Delete recent reactions");
|
|
593505
|
-
renderInfo(" Add --
|
|
593549
|
+
renderInfo(" Add --global to write to ~/.omnius/ (shared across all omnius instances)");
|
|
593506
593550
|
return "handled";
|
|
593507
593551
|
}
|
|
593508
593552
|
case "platforms":
|
|
@@ -610944,6 +610988,12 @@ External acquisition contract:
|
|
|
610944
610988
|
/** Durable SQLite mirror for raw Telegram messages and metadata. */
|
|
610945
610989
|
telegramSqlitePath;
|
|
610946
610990
|
telegramSqliteDb = null;
|
|
610991
|
+
/**
|
|
610992
|
+
* Per-bot ownership lockfile under .omnius/telegram-runner-state/.
|
|
610993
|
+
* Prevents two omnius instances from polling the same bot token concurrently
|
|
610994
|
+
* (which would cause silent 409 conflicts on getUpdates). Released in stop().
|
|
610995
|
+
*/
|
|
610996
|
+
telegramOwnerLockFile = null;
|
|
610947
610997
|
/** Session keys loaded from persistent conversation memory */
|
|
610948
610998
|
loadedConversationState = /* @__PURE__ */ new Set();
|
|
610949
610999
|
/** True once persisted Telegram conversation scopes have been bulk-loaded. */
|
|
@@ -611775,10 +611825,19 @@ ${mediaContext}` : ""
|
|
|
611775
611825
|
}
|
|
611776
611826
|
this.chatParticipants.set(sessionKey, participants);
|
|
611777
611827
|
}
|
|
611778
|
-
|
|
611828
|
+
const cardsLookTruncated = Array.isArray(parsed.memoryCards) && parsed.memoryCards.some((card) => Array.isArray(card.notes) && card.notes.some((note) => typeof note === "string" && note.endsWith("...")));
|
|
611829
|
+
if (Array.isArray(parsed.memoryCards) && !cardsLookTruncated) {
|
|
611779
611830
|
this.chatMemoryCards.set(sessionKey, parsed.memoryCards.slice(0, TELEGRAM_MEMORY_CARD_LIMIT));
|
|
611831
|
+
} else if (loadedHistory.length > 0) {
|
|
611832
|
+
this.chatMemoryCards.set(sessionKey, []);
|
|
611833
|
+
for (const entry of loadedHistory) {
|
|
611834
|
+
this.updateTelegramMemoryCards(sessionKey, entry);
|
|
611835
|
+
}
|
|
611780
611836
|
}
|
|
611781
|
-
|
|
611837
|
+
const associativeLooksTruncated = parsed.associativeMemory && Array.isArray(parsed.associativeMemory.facts) && parsed.associativeMemory.facts.some(
|
|
611838
|
+
(fact) => typeof fact?.text === "string" && fact.text.endsWith("...")
|
|
611839
|
+
);
|
|
611840
|
+
if (parsed.associativeMemory && !associativeLooksTruncated) {
|
|
611782
611841
|
this.chatAssociativeMemory.set(
|
|
611783
611842
|
sessionKey,
|
|
611784
611843
|
this.normalizeTelegramAssociativeMemory(parsed.associativeMemory)
|
|
@@ -612488,14 +612547,14 @@ ${mediaContext}` : ""
|
|
|
612488
612547
|
profile.fromUserId = msg.fromUserId || profile.fromUserId;
|
|
612489
612548
|
profile.messageCount += 1;
|
|
612490
612549
|
profile.lastSeenTs = Date.now();
|
|
612491
|
-
profile.lastMessage =
|
|
612550
|
+
profile.lastMessage = stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
|
|
612492
612551
|
if (msg.replyToMessageId) profile.replyCount += 1;
|
|
612493
612552
|
if (this.state.botUsername && text.toLowerCase().includes(`@${this.state.botUsername.toLowerCase()}`)) {
|
|
612494
612553
|
profile.directAddressCount += 1;
|
|
612495
612554
|
}
|
|
612496
612555
|
for (const tag of inferTelegramToneTags(text)) profile.toneTags.add(tag);
|
|
612497
612556
|
if (text.trim()) {
|
|
612498
|
-
profile.samples.push(
|
|
612557
|
+
profile.samples.push(stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim());
|
|
612499
612558
|
if (profile.samples.length > TELEGRAM_CONTEXT_SAMPLE_LIMIT) {
|
|
612500
612559
|
profile.samples.splice(0, profile.samples.length - TELEGRAM_CONTEXT_SAMPLE_LIMIT);
|
|
612501
612560
|
}
|
|
@@ -612516,7 +612575,7 @@ ${mediaContext}` : ""
|
|
|
612516
612575
|
role: entry.role,
|
|
612517
612576
|
speaker,
|
|
612518
612577
|
mode: entry.mode,
|
|
612519
|
-
text:
|
|
612578
|
+
text: stripTelegramHiddenThinking(entry.text || "").replace(/\s+/g, " ").trim(),
|
|
612520
612579
|
messageId: entry.messageId,
|
|
612521
612580
|
replyToMessageId: entry.replyToMessageId,
|
|
612522
612581
|
userId: entry.fromUserId,
|
|
@@ -612566,7 +612625,7 @@ ${mediaContext}` : ""
|
|
|
612566
612625
|
if (!userMemory.toneTags.includes(tag)) userMemory.toneTags.push(tag);
|
|
612567
612626
|
}
|
|
612568
612627
|
userMemory.toneTags = userMemory.toneTags.slice(0, 20);
|
|
612569
|
-
const compact2 =
|
|
612628
|
+
const compact2 = stripTelegramHiddenThinking(entry.text || "").replace(/\s+/g, " ").trim();
|
|
612570
612629
|
if (compact2) {
|
|
612571
612630
|
userMemory.lastMessages.push(compact2);
|
|
612572
612631
|
userMemory.lastMessages = userMemory.lastMessages.slice(-40);
|
|
@@ -612582,7 +612641,7 @@ ${mediaContext}` : ""
|
|
|
612582
612641
|
}
|
|
612583
612642
|
if (entry.replyContext?.sender || entry.replyToMessageId) {
|
|
612584
612643
|
const target = entry.replyContext?.sender ? telegramReplySenderLabel(entry.replyContext.sender) : `message ${entry.replyToMessageId}`;
|
|
612585
|
-
const hint = `${speaker} replied to ${target}: ${
|
|
612644
|
+
const hint = `${speaker} replied to ${target}: ${stripTelegramHiddenThinking(entry.text || "").replace(/\s+/g, " ").trim()}`;
|
|
612586
612645
|
if (!userMemory.relationshipHints.includes(hint)) {
|
|
612587
612646
|
userMemory.relationshipHints.push(hint);
|
|
612588
612647
|
userMemory.relationshipHints = userMemory.relationshipHints.slice(-80);
|
|
@@ -612600,7 +612659,7 @@ ${mediaContext}` : ""
|
|
|
612600
612659
|
}
|
|
612601
612660
|
extractTelegramAssociativeFacts(entry, speaker) {
|
|
612602
612661
|
if (entry.role !== "user") return [];
|
|
612603
|
-
const text =
|
|
612662
|
+
const text = stripTelegramHiddenThinking(entry.text || "").replace(/\s+/g, " ").trim();
|
|
612604
612663
|
const facts = /* @__PURE__ */ new Set();
|
|
612605
612664
|
const patterns = [
|
|
612606
612665
|
/\b(?:remember|note|keep in mind|for future reference)\s+(?:that\s+)?(.{4,260})/i,
|
|
@@ -612621,7 +612680,7 @@ ${mediaContext}` : ""
|
|
|
612621
612680
|
return [...facts].slice(0, 8);
|
|
612622
612681
|
}
|
|
612623
612682
|
upsertTelegramAssociativeFact(facts, text, entry, speaker, weight = 1) {
|
|
612624
|
-
const clean5 =
|
|
612683
|
+
const clean5 = stripTelegramHiddenThinking(text || "").replace(/\s+/g, " ").trim();
|
|
612625
612684
|
const key = clean5.toLowerCase();
|
|
612626
612685
|
const now = entry.ts ?? Date.now();
|
|
612627
612686
|
let fact = facts.find((item) => item.text.toLowerCase() === key);
|
|
@@ -612658,7 +612717,7 @@ ${mediaContext}` : ""
|
|
|
612658
612717
|
return fact;
|
|
612659
612718
|
}
|
|
612660
612719
|
updateTelegramMemoryCards(sessionKey, entry) {
|
|
612661
|
-
const text =
|
|
612720
|
+
const text = stripTelegramHiddenThinking(entry.text || "").replace(/\s+/g, " ").trim();
|
|
612662
612721
|
if (!text || text.length < 3) return;
|
|
612663
612722
|
const speaker = telegramHistorySpeaker(entry);
|
|
612664
612723
|
const tags = telegramMemoryTags(text, entry.mediaSummary);
|
|
@@ -612867,6 +612926,61 @@ ${lines.join("\n")}`);
|
|
|
612867
612926
|
lines.join("\n")
|
|
612868
612927
|
].join("\n");
|
|
612869
612928
|
}
|
|
612929
|
+
/**
|
|
612930
|
+
* Always-on episodic memory recall for the active Telegram session.
|
|
612931
|
+
* Pulls scored episodes from .omnius/episodes.db where session_id = sessionKey,
|
|
612932
|
+
* including social / tool_result / reflection modalities. This surfaces day-old
|
|
612933
|
+
* context the rolling 36-turn window has already shed.
|
|
612934
|
+
*/
|
|
612935
|
+
relevantTelegramEpisodicMemoryContext(sessionKey, msg, limit = 8) {
|
|
612936
|
+
if (!this.repoRoot) return "";
|
|
612937
|
+
const paths = omniusMemoryDbPaths(this.repoRoot);
|
|
612938
|
+
if (!existsSync112(paths.episodes)) return "";
|
|
612939
|
+
let episodes = [];
|
|
612940
|
+
const graph = new TemporalGraph(paths.knowledge);
|
|
612941
|
+
const store2 = new EpisodeStore(paths.episodes, graph);
|
|
612942
|
+
try {
|
|
612943
|
+
const recent = store2.search({ sessionId: sessionKey, limit: Math.max(limit * 3, 24) }) ?? [];
|
|
612944
|
+
const queryText = (msg.text || "").toLowerCase().trim();
|
|
612945
|
+
if (queryText.length > 3) {
|
|
612946
|
+
const qTokens = queryText.split(/\s+/).filter((t2) => t2.length >= 4);
|
|
612947
|
+
const scored = recent.map((ep) => {
|
|
612948
|
+
const content = String(ep.content || "").toLowerCase();
|
|
612949
|
+
const hits = qTokens.filter((t2) => content.includes(t2)).length;
|
|
612950
|
+
return { ep, score: hits };
|
|
612951
|
+
}).sort((a2, b) => b.score - a2.score || b.ep.timestamp - a2.ep.timestamp);
|
|
612952
|
+
episodes = scored.slice(0, limit).map((s2) => s2.ep);
|
|
612953
|
+
} else {
|
|
612954
|
+
episodes = recent.slice(0, limit);
|
|
612955
|
+
}
|
|
612956
|
+
} catch {
|
|
612957
|
+
return "";
|
|
612958
|
+
} finally {
|
|
612959
|
+
try {
|
|
612960
|
+
store2.close();
|
|
612961
|
+
} catch {
|
|
612962
|
+
}
|
|
612963
|
+
try {
|
|
612964
|
+
graph.close();
|
|
612965
|
+
} catch {
|
|
612966
|
+
}
|
|
612967
|
+
}
|
|
612968
|
+
if (episodes.length === 0) return "";
|
|
612969
|
+
const lines = episodes.map((ep) => {
|
|
612970
|
+
const when = ep.timestamp ? new Date(ep.timestamp).toISOString() : "";
|
|
612971
|
+
const meta = ep.metadata || {};
|
|
612972
|
+
const tg = meta.telegram && typeof meta.telegram === "object" ? meta.telegram : {};
|
|
612973
|
+
const speaker = tg.speaker || tg.username || (ep.modality === "tool_result" ? `tool:${ep.toolName || "?"}` : "agent");
|
|
612974
|
+
const mode = tg.mode ? `/${tg.mode}` : "";
|
|
612975
|
+
const text = ep.gist || ep.content;
|
|
612976
|
+
return `- ${when} ${speaker}${mode} [${ep.modality}]: ${telegramContextJsonString(String(text || ""), 260)}`;
|
|
612977
|
+
});
|
|
612978
|
+
return [
|
|
612979
|
+
"### Episodic Memory Recall (durable, day+ scope)",
|
|
612980
|
+
"Scored episodes for this Telegram session from episodes.db. These are PERSISTENT across restarts and survive the rolling-context window. Treat as canonical for older facts.",
|
|
612981
|
+
lines.join("\n")
|
|
612982
|
+
].join("\n");
|
|
612983
|
+
}
|
|
612870
612984
|
telegramSqliteHistoryForSession(sessionKey, limit = 1e3) {
|
|
612871
612985
|
const db = this.telegramDb();
|
|
612872
612986
|
if (!db) return [];
|
|
@@ -613047,6 +613161,17 @@ ${participantLines.join("\n")}`);
|
|
|
613047
613161
|
if (sqliteMirrorContext) {
|
|
613048
613162
|
sections.push(sqliteMirrorContext);
|
|
613049
613163
|
}
|
|
613164
|
+
try {
|
|
613165
|
+
const episodicContext = this.relevantTelegramEpisodicMemoryContext(
|
|
613166
|
+
sessionKey,
|
|
613167
|
+
msg,
|
|
613168
|
+
isGroup ? 10 : 6
|
|
613169
|
+
);
|
|
613170
|
+
if (episodicContext) {
|
|
613171
|
+
sections.push(episodicContext);
|
|
613172
|
+
}
|
|
613173
|
+
} catch {
|
|
613174
|
+
}
|
|
613050
613175
|
const memoryCards = this.relevantTelegramMemoryCards(sessionKey, msg, isGroup ? 10 : 6);
|
|
613051
613176
|
if (memoryCards.length > 0) {
|
|
613052
613177
|
const cardLines = memoryCards.map(({ card, score }) => {
|
|
@@ -613613,6 +613738,40 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
613613
613738
|
if (!me?.ok) {
|
|
613614
613739
|
throw new Error(`Invalid Telegram bot token: ${me?.description || "unknown error"}`);
|
|
613615
613740
|
}
|
|
613741
|
+
if (this.repoRoot && me.result?.id) {
|
|
613742
|
+
try {
|
|
613743
|
+
const lockDir = resolve43(this.repoRoot, ".omnius", "telegram-runner-state");
|
|
613744
|
+
mkdirSync65(lockDir, { recursive: true });
|
|
613745
|
+
const lockFile = join127(lockDir, `bot-${me.result.id}.owner.lock`);
|
|
613746
|
+
if (existsSync112(lockFile)) {
|
|
613747
|
+
try {
|
|
613748
|
+
const prior = JSON.parse(readFileSync92(lockFile, "utf8"));
|
|
613749
|
+
const priorAlive = typeof prior.pid === "number" && prior.pid !== process.pid ? this.processIsAlive(prior.pid) : false;
|
|
613750
|
+
if (priorAlive) {
|
|
613751
|
+
throw new Error(
|
|
613752
|
+
`Telegram bot @${prior.botUsername || me.result.username || "unknown"} is already being polled by pid ${prior.pid} (cwd ${prior.cwd || "?"}). Stop that instance or use a different bot token in this project.`
|
|
613753
|
+
);
|
|
613754
|
+
}
|
|
613755
|
+
} catch (e2) {
|
|
613756
|
+
if (e2 instanceof Error && e2.message.startsWith("Telegram bot @")) throw e2;
|
|
613757
|
+
}
|
|
613758
|
+
}
|
|
613759
|
+
writeFileSync59(
|
|
613760
|
+
lockFile,
|
|
613761
|
+
JSON.stringify({
|
|
613762
|
+
pid: process.pid,
|
|
613763
|
+
cwd: this.repoRoot,
|
|
613764
|
+
botUsername: me.result.username,
|
|
613765
|
+
botUserId: me.result.id,
|
|
613766
|
+
ts: Date.now()
|
|
613767
|
+
}, null, 2),
|
|
613768
|
+
{ encoding: "utf-8", mode: 384 }
|
|
613769
|
+
);
|
|
613770
|
+
this.telegramOwnerLockFile = lockFile;
|
|
613771
|
+
} catch (e2) {
|
|
613772
|
+
if (e2 instanceof Error && e2.message.startsWith("Telegram bot @")) throw e2;
|
|
613773
|
+
}
|
|
613774
|
+
}
|
|
613616
613775
|
this.state = {
|
|
613617
613776
|
active: true,
|
|
613618
613777
|
botUsername: me.result?.username ?? "unknown",
|
|
@@ -613663,10 +613822,33 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
613663
613822
|
}
|
|
613664
613823
|
this.telegramSqliteDb = null;
|
|
613665
613824
|
}
|
|
613825
|
+
if (this.telegramOwnerLockFile) {
|
|
613826
|
+
try {
|
|
613827
|
+
if (existsSync112(this.telegramOwnerLockFile)) {
|
|
613828
|
+
unlinkSync22(this.telegramOwnerLockFile);
|
|
613829
|
+
}
|
|
613830
|
+
} catch {
|
|
613831
|
+
}
|
|
613832
|
+
this.telegramOwnerLockFile = null;
|
|
613833
|
+
}
|
|
613666
613834
|
this.subAgents.clear();
|
|
613667
613835
|
this.activeChatViews.clear();
|
|
613668
613836
|
this.refreshActiveTelegramInteractionCount();
|
|
613669
613837
|
}
|
|
613838
|
+
/**
|
|
613839
|
+
* Cheap liveness probe: kill(pid, 0) throws ESRCH when the process is dead
|
|
613840
|
+
* and EPERM when it exists but we can't signal it (still alive from our POV).
|
|
613841
|
+
*/
|
|
613842
|
+
processIsAlive(pid) {
|
|
613843
|
+
if (!pid || !Number.isFinite(pid)) return false;
|
|
613844
|
+
try {
|
|
613845
|
+
process.kill(pid, 0);
|
|
613846
|
+
return true;
|
|
613847
|
+
} catch (e2) {
|
|
613848
|
+
if (e2 && e2.code === "EPERM") return true;
|
|
613849
|
+
return false;
|
|
613850
|
+
}
|
|
613851
|
+
}
|
|
613670
613852
|
// ── Typing indicator ──────────────────────────────────────────────────
|
|
613671
613853
|
/** Start sending "typing" indicator every 4 seconds */
|
|
613672
613854
|
startTypingIndicator(chatId) {
|
|
@@ -648230,7 +648412,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
648230
648412
|
...settings.admin !== void 0 ? { telegramAdmin: settings.admin } : {},
|
|
648231
648413
|
...settings.mode !== void 0 ? { telegramMode: settings.mode } : {}
|
|
648232
648414
|
};
|
|
648233
|
-
|
|
648415
|
+
const projectHasOmnius = existsSync127(join143(repoRoot, ".omnius"));
|
|
648416
|
+
const useProject = settings.local === true || settings.local === void 0 && projectHasOmnius;
|
|
648417
|
+
if (useProject) {
|
|
648234
648418
|
saveProjectSettings(repoRoot, payload);
|
|
648235
648419
|
} else {
|
|
648236
648420
|
saveGlobalSettings(payload);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.61",
|
|
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.61",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED