omnius 1.0.66 → 1.0.68
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 +782 -228
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -552883,6 +552883,11 @@ var init_sessionMetrics = __esm({
|
|
|
552883
552883
|
toolCallsByName = {};
|
|
552884
552884
|
inputTokens = 0;
|
|
552885
552885
|
outputTokens = 0;
|
|
552886
|
+
latestEstimatedContextTokens = 0;
|
|
552887
|
+
peakEstimatedContextTokens = 0;
|
|
552888
|
+
measuredOutputTokens = 0;
|
|
552889
|
+
totalGenerationMs = 0;
|
|
552890
|
+
generationSamples = 0;
|
|
552886
552891
|
filesModified = /* @__PURE__ */ new Set();
|
|
552887
552892
|
tasks = [];
|
|
552888
552893
|
currentTask = null;
|
|
@@ -552903,8 +552908,24 @@ var init_sessionMetrics = __esm({
|
|
|
552903
552908
|
}
|
|
552904
552909
|
/** Record token usage. */
|
|
552905
552910
|
recordTokenUsage(inputTokens, outputTokens) {
|
|
552906
|
-
this.inputTokens += inputTokens;
|
|
552907
|
-
this.outputTokens += outputTokens;
|
|
552911
|
+
this.inputTokens += Math.max(0, Math.trunc(inputTokens || 0));
|
|
552912
|
+
this.outputTokens += Math.max(0, Math.trunc(outputTokens || 0));
|
|
552913
|
+
}
|
|
552914
|
+
/** Record the runner's latest context-token estimate. */
|
|
552915
|
+
recordContextEstimate(tokens) {
|
|
552916
|
+
const normalized = Math.max(0, Math.trunc(tokens || 0));
|
|
552917
|
+
this.latestEstimatedContextTokens = normalized;
|
|
552918
|
+
this.peakEstimatedContextTokens = Math.max(this.peakEstimatedContextTokens, normalized);
|
|
552919
|
+
}
|
|
552920
|
+
/** Record measured generation throughput for one response. */
|
|
552921
|
+
recordGeneration(outputTokens, durationMs) {
|
|
552922
|
+
const tokens = Math.max(0, Math.trunc(outputTokens || 0));
|
|
552923
|
+
const duration = Math.max(0, Math.trunc(durationMs || 0));
|
|
552924
|
+
if (tokens <= 0 || duration <= 0)
|
|
552925
|
+
return;
|
|
552926
|
+
this.measuredOutputTokens += tokens;
|
|
552927
|
+
this.totalGenerationMs += duration;
|
|
552928
|
+
this.generationSamples++;
|
|
552908
552929
|
}
|
|
552909
552930
|
/** Record a file modification. */
|
|
552910
552931
|
recordFileModified(filePath) {
|
|
@@ -552912,6 +552933,9 @@ var init_sessionMetrics = __esm({
|
|
|
552912
552933
|
}
|
|
552913
552934
|
/** Start tracking a new task. */
|
|
552914
552935
|
startTask(description) {
|
|
552936
|
+
if (this.currentTask) {
|
|
552937
|
+
this.endTask();
|
|
552938
|
+
}
|
|
552915
552939
|
this.currentTask = {
|
|
552916
552940
|
description,
|
|
552917
552941
|
startTime: Date.now(),
|
|
@@ -552942,6 +552966,13 @@ var init_sessionMetrics = __esm({
|
|
|
552942
552966
|
toolCallsByName: { ...this.toolCallsByName },
|
|
552943
552967
|
totalInputTokens: this.inputTokens,
|
|
552944
552968
|
totalOutputTokens: this.outputTokens,
|
|
552969
|
+
totalTokens: this.inputTokens + this.outputTokens,
|
|
552970
|
+
latestEstimatedContextTokens: this.latestEstimatedContextTokens,
|
|
552971
|
+
peakEstimatedContextTokens: this.peakEstimatedContextTokens,
|
|
552972
|
+
measuredOutputTokens: this.measuredOutputTokens,
|
|
552973
|
+
totalGenerationMs: this.totalGenerationMs,
|
|
552974
|
+
generationSamples: this.generationSamples,
|
|
552975
|
+
averageOutputTokensPerSecond: this.totalGenerationMs > 0 ? this.measuredOutputTokens / (this.totalGenerationMs / 1e3) : void 0,
|
|
552945
552976
|
filesModified: [...this.filesModified],
|
|
552946
552977
|
tasksCompleted: this.tasks.length,
|
|
552947
552978
|
tasks: [...this.tasks],
|
|
@@ -560860,6 +560891,7 @@ function toTelegramBotCommandName(name10) {
|
|
|
560860
560891
|
function buildTelegramBotCommands(opts = {}) {
|
|
560861
560892
|
const maxCommands = Math.max(1, Math.min(100, opts.maxCommands ?? 100));
|
|
560862
560893
|
const includeAuth = opts.includeAuth !== false;
|
|
560894
|
+
const scope = opts.scope ?? "admin";
|
|
560863
560895
|
const commands = [];
|
|
560864
560896
|
const seen = /* @__PURE__ */ new Set();
|
|
560865
560897
|
const add2 = (command, description, canonical = command) => {
|
|
@@ -560872,6 +560904,14 @@ function buildTelegramBotCommands(opts = {}) {
|
|
|
560872
560904
|
canonical
|
|
560873
560905
|
});
|
|
560874
560906
|
};
|
|
560907
|
+
if (scope === "public") {
|
|
560908
|
+
for (const cmd of TELEGRAM_PUBLIC_BOT_COMMANDS) {
|
|
560909
|
+
if (!includeAuth && cmd.command === "auth") continue;
|
|
560910
|
+
add2(cmd.command, cmd.description, cmd.canonical);
|
|
560911
|
+
if (commands.length >= maxCommands) break;
|
|
560912
|
+
}
|
|
560913
|
+
return commands.slice(0, maxCommands);
|
|
560914
|
+
}
|
|
560875
560915
|
if (includeAuth) {
|
|
560876
560916
|
add2("auth", "Authenticate this Telegram user as the bot admin", "auth");
|
|
560877
560917
|
}
|
|
@@ -561071,7 +561111,7 @@ function inferArgsHint(signature) {
|
|
|
561071
561111
|
function normalizeCommandName(name10) {
|
|
561072
561112
|
return name10.replace(/^\//, "").trim().toLowerCase();
|
|
561073
561113
|
}
|
|
561074
|
-
var COMMAND_SIGNATURES, PLANNED_SIGNATURES, CATEGORY_OVERRIDES, ALIASES, USER_ONLY, DESTRUCTIVE, NETWORKED, SECRET_BEARING, PROFILE_GATED, SELF_MODIFY_ALLOWED, REST_BLOCKED, CANONICAL_BY_ALIAS, DYNAMIC_COMMANDS, SLASH_COMMANDS;
|
|
561114
|
+
var COMMAND_SIGNATURES, PLANNED_SIGNATURES, CATEGORY_OVERRIDES, ALIASES, USER_ONLY, DESTRUCTIVE, NETWORKED, SECRET_BEARING, PROFILE_GATED, SELF_MODIFY_ALLOWED, REST_BLOCKED, TELEGRAM_PUBLIC_BOT_COMMANDS, CANONICAL_BY_ALIAS, DYNAMIC_COMMANDS, SLASH_COMMANDS;
|
|
561075
561115
|
var init_command_registry = __esm({
|
|
561076
561116
|
"packages/cli/src/tui/command-registry.ts"() {
|
|
561077
561117
|
"use strict";
|
|
@@ -561158,6 +561198,7 @@ var init_command_registry = __esm({
|
|
|
561158
561198
|
["/score", "Show inference capability scorecard (memory, compute, speed, models)"],
|
|
561159
561199
|
["/task-type", "Set task type (code, document, analysis, plan, general, auto)"],
|
|
561160
561200
|
["/stats", "Show session dashboard (metrics, tool usage, task history)"],
|
|
561201
|
+
["/metrics", "Show runtime metrics: tokens, context window, throughput, and tool usage"],
|
|
561161
561202
|
["/sessions", "Browse saved sessions"],
|
|
561162
561203
|
["/pause", "Pause after current turn finishes (gentle halt, /resume to continue)"],
|
|
561163
561204
|
["/stop", "Kill current inference immediately and save state (/resume to continue)"],
|
|
@@ -561440,7 +561481,9 @@ var init_command_registry = __esm({
|
|
|
561440
561481
|
selfmodify: "runtime",
|
|
561441
561482
|
debug: "runtime",
|
|
561442
561483
|
selfmod: "runtime",
|
|
561443
|
-
"self-modify": "runtime"
|
|
561484
|
+
"self-modify": "runtime",
|
|
561485
|
+
stats: "session",
|
|
561486
|
+
metrics: "session"
|
|
561444
561487
|
};
|
|
561445
561488
|
ALIASES = {
|
|
561446
561489
|
help: ["h", "?"],
|
|
@@ -561463,7 +561506,7 @@ var init_command_registry = __esm({
|
|
|
561463
561506
|
evaluate: ["eval"],
|
|
561464
561507
|
score: ["inference"],
|
|
561465
561508
|
"task-type": ["tasktype", "tt"],
|
|
561466
|
-
stats: ["
|
|
561509
|
+
stats: ["dashboard"],
|
|
561467
561510
|
memory: ["mem"],
|
|
561468
561511
|
files: ["workspace"],
|
|
561469
561512
|
skills: ["skill"],
|
|
@@ -561627,6 +561670,7 @@ var init_command_registry = __esm({
|
|
|
561627
561670
|
"selfmodify",
|
|
561628
561671
|
"debug",
|
|
561629
561672
|
"stats",
|
|
561673
|
+
"metrics",
|
|
561630
561674
|
"stream",
|
|
561631
561675
|
"style",
|
|
561632
561676
|
"task-type",
|
|
@@ -561646,6 +561690,20 @@ var init_command_registry = __esm({
|
|
|
561646
561690
|
"bg",
|
|
561647
561691
|
"paste"
|
|
561648
561692
|
]);
|
|
561693
|
+
TELEGRAM_PUBLIC_BOT_COMMANDS = [
|
|
561694
|
+
{ command: "start", description: "Show Telegram bridge status", canonical: "start" },
|
|
561695
|
+
{ command: "help", description: "Show available Telegram commands", canonical: "help" },
|
|
561696
|
+
{ command: "commands", description: "Show available Telegram commands", canonical: "commands" },
|
|
561697
|
+
{ command: "auth", description: "Authenticate this Telegram user as bot admin", canonical: "auth" },
|
|
561698
|
+
{ command: "call", description: "Get or request the active voice call link", canonical: "call" },
|
|
561699
|
+
{ command: "reflect", description: "Run scoped Telegram chat reflection", canonical: "reflect" },
|
|
561700
|
+
{ command: "reflection", description: "Alias for scoped Telegram chat reflection", canonical: "reflect" },
|
|
561701
|
+
{ command: "daydream", description: "Alias for scoped Telegram chat reflection", canonical: "reflect" },
|
|
561702
|
+
{ command: "remind", description: "Set a scoped Telegram reminder", canonical: "remind" },
|
|
561703
|
+
{ command: "reminder", description: "List or update scoped Telegram reminders", canonical: "reminder" },
|
|
561704
|
+
{ command: "reminders", description: "Alias for scoped Telegram reminders", canonical: "reminder" },
|
|
561705
|
+
{ command: "image", description: "Generate a scoped image from a prompt", canonical: "image" }
|
|
561706
|
+
];
|
|
561649
561707
|
CANONICAL_BY_ALIAS = /* @__PURE__ */ new Map();
|
|
561650
561708
|
for (const [canonical, aliases] of Object.entries(ALIASES)) {
|
|
561651
561709
|
for (const alias of aliases) CANONICAL_BY_ALIAS.set(alias, canonical);
|
|
@@ -588762,10 +588820,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
588762
588820
|
let key = process.env["OMNIUS_API_KEY"] || "";
|
|
588763
588821
|
if (!key) {
|
|
588764
588822
|
try {
|
|
588765
|
-
const { homedir:
|
|
588823
|
+
const { homedir: homedir53 } = await import("node:os");
|
|
588766
588824
|
const { readFileSync: readFileSync107, existsSync: existsSync131 } = await import("node:fs");
|
|
588767
588825
|
const { join: join148 } = await import("node:path");
|
|
588768
|
-
const p2 = join148(
|
|
588826
|
+
const p2 = join148(homedir53(), ".omnius", "api.key");
|
|
588769
588827
|
if (existsSync131(p2)) key = readFileSync107(p2, "utf8").trim();
|
|
588770
588828
|
} catch {
|
|
588771
588829
|
}
|
|
@@ -588808,12 +588866,12 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
588808
588866
|
if (action === "new") {
|
|
588809
588867
|
try {
|
|
588810
588868
|
const { randomBytes: randomBytes27 } = await import("node:crypto");
|
|
588811
|
-
const { homedir:
|
|
588869
|
+
const { homedir: homedir53 } = await import("node:os");
|
|
588812
588870
|
const { mkdirSync: mkdirSync81, writeFileSync: writeFileSync73 } = await import("node:fs");
|
|
588813
588871
|
const { join: join148 } = await import("node:path");
|
|
588814
588872
|
const newKey = randomBytes27(16).toString("hex");
|
|
588815
588873
|
process.env["OMNIUS_API_KEY"] = newKey;
|
|
588816
|
-
const dir = join148(
|
|
588874
|
+
const dir = join148(homedir53(), ".omnius");
|
|
588817
588875
|
mkdirSync81(dir, { recursive: true });
|
|
588818
588876
|
writeFileSync73(join148(dir, "api.key"), newKey + "\n", "utf8");
|
|
588819
588877
|
renderInfo(`New API key: ${c3.bold(c3.yellow(newKey))}`);
|
|
@@ -589079,10 +589137,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589079
589137
|
"Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client."
|
|
589080
589138
|
);
|
|
589081
589139
|
try {
|
|
589082
|
-
const { homedir:
|
|
589140
|
+
const { homedir: homedir54 } = await import("node:os");
|
|
589083
589141
|
const { mkdirSync: mkdirSync82, writeFileSync: writeFileSync74 } = await import("node:fs");
|
|
589084
589142
|
const { join: join149 } = await import("node:path");
|
|
589085
|
-
const dir = join149(
|
|
589143
|
+
const dir = join149(homedir54(), ".omnius");
|
|
589086
589144
|
mkdirSync82(dir, { recursive: true });
|
|
589087
589145
|
writeFileSync74(join149(dir, "api.key"), apiKey + "\n", "utf8");
|
|
589088
589146
|
} catch {
|
|
@@ -589095,10 +589153,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589095
589153
|
}
|
|
589096
589154
|
const port2 = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
589097
589155
|
try {
|
|
589098
|
-
const { homedir:
|
|
589156
|
+
const { homedir: homedir54 } = await import("node:os");
|
|
589099
589157
|
const { mkdirSync: mkdirSync82, writeFileSync: writeFileSync74 } = await import("node:fs");
|
|
589100
589158
|
const { join: join149 } = await import("node:path");
|
|
589101
|
-
const dir = join149(
|
|
589159
|
+
const dir = join149(homedir54(), ".omnius");
|
|
589102
589160
|
mkdirSync82(dir, { recursive: true });
|
|
589103
589161
|
writeFileSync74(join149(dir, "access"), `${val2}
|
|
589104
589162
|
`, "utf8");
|
|
@@ -589199,10 +589257,10 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589199
589257
|
"Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client."
|
|
589200
589258
|
);
|
|
589201
589259
|
try {
|
|
589202
|
-
const { homedir:
|
|
589260
|
+
const { homedir: homedir54 } = await import("node:os");
|
|
589203
589261
|
const { mkdirSync: mkdirSync82, writeFileSync: writeFileSync74 } = await import("node:fs");
|
|
589204
589262
|
const { join: join149 } = await import("node:path");
|
|
589205
|
-
const dir = join149(
|
|
589263
|
+
const dir = join149(homedir54(), ".omnius");
|
|
589206
589264
|
mkdirSync82(dir, { recursive: true });
|
|
589207
589265
|
writeFileSync74(join149(dir, "api.key"), apiKey + "\n", "utf8");
|
|
589208
589266
|
} catch {
|
|
@@ -589214,11 +589272,11 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589214
589272
|
ctx3.saveSettings({ omniusAccess: val });
|
|
589215
589273
|
}
|
|
589216
589274
|
const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
589217
|
-
const { homedir:
|
|
589275
|
+
const { homedir: homedir53 } = await import("node:os");
|
|
589218
589276
|
const { mkdirSync: mkdirSync81, writeFileSync: writeFileSync73 } = await import("node:fs");
|
|
589219
589277
|
const { join: join148 } = await import("node:path");
|
|
589220
589278
|
try {
|
|
589221
|
-
const dir = join148(
|
|
589279
|
+
const dir = join148(homedir53(), ".omnius");
|
|
589222
589280
|
mkdirSync81(dir, { recursive: true });
|
|
589223
589281
|
writeFileSync73(join148(dir, "access"), `${val}
|
|
589224
589282
|
`, "utf8");
|
|
@@ -589641,7 +589699,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589641
589699
|
);
|
|
589642
589700
|
}
|
|
589643
589701
|
} else if (sub === "name") {
|
|
589644
|
-
const { homedir:
|
|
589702
|
+
const { homedir: homedir53 } = __require("node:os");
|
|
589645
589703
|
const {
|
|
589646
589704
|
existsSync: ex,
|
|
589647
589705
|
readFileSync: rf,
|
|
@@ -589649,7 +589707,7 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589649
589707
|
mkdirSync: mkd
|
|
589650
589708
|
} = __require("node:fs");
|
|
589651
589709
|
const namePath = __require("node:path").join(
|
|
589652
|
-
|
|
589710
|
+
homedir53(),
|
|
589653
589711
|
".omnius",
|
|
589654
589712
|
"agent-name"
|
|
589655
589713
|
);
|
|
@@ -589812,11 +589870,32 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589812
589870
|
}
|
|
589813
589871
|
const summary = ctx3.sessionMetrics.getSummary();
|
|
589814
589872
|
const dur = SessionMetrics.formatDuration(summary.sessionDurationMs);
|
|
589873
|
+
const contextWindowSize = Math.max(0, Math.trunc(ctx3.getContextWindowSize?.() ?? 0));
|
|
589874
|
+
const contextLabel = contextWindowSize > 0 ? formatContextLength(contextWindowSize) : "unknown";
|
|
589875
|
+
const latestContextPct = contextWindowSize > 0 && summary.latestEstimatedContextTokens > 0 ? ` (${Math.round(summary.latestEstimatedContextTokens / contextWindowSize * 100)}%)` : "";
|
|
589876
|
+
const peakContextPct = contextWindowSize > 0 && summary.peakEstimatedContextTokens > 0 ? ` (${Math.round(summary.peakEstimatedContextTokens / contextWindowSize * 100)}%)` : "";
|
|
589877
|
+
const sessionSeconds = Math.max(1, summary.sessionDurationMs / 1e3);
|
|
589878
|
+
const measuredTokPerSec = summary.averageOutputTokensPerSecond;
|
|
589879
|
+
const sessionOutputTokPerSec = summary.totalOutputTokens / sessionSeconds;
|
|
589880
|
+
const avgInputPerTurn = summary.totalTurns > 0 ? summary.totalInputTokens / summary.totalTurns : 0;
|
|
589881
|
+
const avgOutputPerTurn = summary.totalTurns > 0 ? summary.totalOutputTokens / summary.totalTurns : 0;
|
|
589882
|
+
const avgToolsPerTurn = summary.totalTurns > 0 ? summary.totalToolCalls / summary.totalTurns : 0;
|
|
589815
589883
|
const lines = [];
|
|
589816
589884
|
lines.push(`
|
|
589817
|
-
${c3.bold("Session Dashboard")}
|
|
589885
|
+
${c3.bold(cmd === "metrics" ? "Runtime Metrics" : "Session Dashboard")}
|
|
589818
589886
|
`);
|
|
589819
589887
|
lines.push(` Duration: ${c3.bold(dur)}`);
|
|
589888
|
+
lines.push(` Context window: ${c3.bold(contextLabel)}`);
|
|
589889
|
+
if (summary.latestEstimatedContextTokens > 0) {
|
|
589890
|
+
lines.push(
|
|
589891
|
+
` Context now: ${c3.bold(`~${summary.latestEstimatedContextTokens.toLocaleString()}`)} tokens${latestContextPct}`
|
|
589892
|
+
);
|
|
589893
|
+
}
|
|
589894
|
+
if (summary.peakEstimatedContextTokens > 0) {
|
|
589895
|
+
lines.push(
|
|
589896
|
+
` Context peak: ${c3.bold(`~${summary.peakEstimatedContextTokens.toLocaleString()}`)} tokens${peakContextPct}`
|
|
589897
|
+
);
|
|
589898
|
+
}
|
|
589820
589899
|
lines.push(
|
|
589821
589900
|
` Tasks completed: ${c3.bold(String(summary.tasksCompleted))}`
|
|
589822
589901
|
);
|
|
@@ -589828,6 +589907,18 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
589828
589907
|
lines.push(
|
|
589829
589908
|
` Output tokens: ${c3.bold(summary.totalOutputTokens.toLocaleString())}`
|
|
589830
589909
|
);
|
|
589910
|
+
lines.push(
|
|
589911
|
+
` Total tokens: ${c3.bold(summary.totalTokens.toLocaleString())}`
|
|
589912
|
+
);
|
|
589913
|
+
lines.push(
|
|
589914
|
+
` Avg / turn: ${c3.bold(`${Math.round(avgInputPerTurn).toLocaleString()} in / ${Math.round(avgOutputPerTurn).toLocaleString()} out`)}`
|
|
589915
|
+
);
|
|
589916
|
+
lines.push(
|
|
589917
|
+
` Tool / turn: ${c3.bold(avgToolsPerTurn.toFixed(2))}`
|
|
589918
|
+
);
|
|
589919
|
+
lines.push(
|
|
589920
|
+
measuredTokPerSec !== void 0 ? ` Output speed: ${c3.bold(`${measuredTokPerSec.toFixed(1)} tok/s`)} ${c3.dim(`(${summary.generationSamples} measured response${summary.generationSamples === 1 ? "" : "s"})`)}` : ` Output speed: ${c3.bold(`${sessionOutputTokPerSec.toFixed(1)} tok/s`)} ${c3.dim("session average")}`
|
|
589921
|
+
);
|
|
589831
589922
|
if (ctx3.costTracker?.hasPricing) {
|
|
589832
589923
|
lines.push(
|
|
589833
589924
|
` Estimated cost: ${c3.bold(c3.yellow(ctx3.costTracker.formatCost()))}`
|
|
@@ -592504,9 +592595,9 @@ sleep 1
|
|
|
592504
592595
|
let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
|
|
592505
592596
|
if (!sponsorName || sponsorName.length < 2) {
|
|
592506
592597
|
try {
|
|
592507
|
-
const { homedir:
|
|
592598
|
+
const { homedir: homedir53 } = __require("os");
|
|
592508
592599
|
const namePath = __require("path").join(
|
|
592509
|
-
|
|
592600
|
+
homedir53(),
|
|
592510
592601
|
".omnius",
|
|
592511
592602
|
"agent-name"
|
|
592512
592603
|
);
|
|
@@ -593276,6 +593367,21 @@ sleep 1
|
|
|
593276
593367
|
ctx3.telegramStatus?.();
|
|
593277
593368
|
return "handled";
|
|
593278
593369
|
}
|
|
593370
|
+
if (parts[0] === "revoke" || parts[0] === "deauth" || parts[0] === "deauthorize") {
|
|
593371
|
+
const hasGlobalFlagRevoke = parts.includes("--global");
|
|
593372
|
+
const extra = parts.slice(1).filter((part) => part !== "--global");
|
|
593373
|
+
if (extra.length > 0) {
|
|
593374
|
+
renderWarning("Usage: /telegram revoke [--global]");
|
|
593375
|
+
return "handled";
|
|
593376
|
+
}
|
|
593377
|
+
const scope = hasGlobalFlagRevoke ? "global" : "project";
|
|
593378
|
+
const result = ctx3.telegramRevokeAdmin?.(scope);
|
|
593379
|
+
renderInfo(`Telegram admin revoked from ${c3.bold(result?.scope ?? scope)} settings.`);
|
|
593380
|
+
if (!hasGlobalFlagRevoke) {
|
|
593381
|
+
renderInfo("Use /telegram revoke --global to clear the old shared ~/.omnius admin too.");
|
|
593382
|
+
}
|
|
593383
|
+
return "handled";
|
|
593384
|
+
}
|
|
593279
593385
|
if (parts[0] === "mode" || parts[0] === "profile") {
|
|
593280
593386
|
const requested = parts.slice(1).find((part) => !part.startsWith("--"));
|
|
593281
593387
|
if (!requested) {
|
|
@@ -593590,6 +593696,24 @@ sleep 1
|
|
|
593590
593696
|
renderInfo("Use /telegram to start.");
|
|
593591
593697
|
return "handled";
|
|
593592
593698
|
}
|
|
593699
|
+
if (parts.length === 1 && parts[0] === "--global") {
|
|
593700
|
+
if (ctx3.isTelegramActive?.()) {
|
|
593701
|
+
ctx3.telegramStop?.();
|
|
593702
|
+
return "handled";
|
|
593703
|
+
}
|
|
593704
|
+
const settings = ctx3.getTelegramSettings?.("global") ?? {};
|
|
593705
|
+
if (!settings.key) {
|
|
593706
|
+
renderWarning("No global Telegram bot token configured.");
|
|
593707
|
+
renderInfo("Set one with /telegram --key <bot-token> --global, or use /telegram --key <bot-token> for this project.");
|
|
593708
|
+
return "handled";
|
|
593709
|
+
}
|
|
593710
|
+
try {
|
|
593711
|
+
await ctx3.telegramStart?.(settings.key, settings.admin, "global");
|
|
593712
|
+
} catch (err) {
|
|
593713
|
+
renderError(`Telegram error: ${err instanceof Error ? err.message : String(err)}`);
|
|
593714
|
+
}
|
|
593715
|
+
return "handled";
|
|
593716
|
+
}
|
|
593593
593717
|
if (!arg) {
|
|
593594
593718
|
if (ctx3.isTelegramActive?.()) {
|
|
593595
593719
|
ctx3.telegramStop?.();
|
|
@@ -593599,7 +593723,13 @@ sleep 1
|
|
|
593599
593723
|
if (!settings.key) {
|
|
593600
593724
|
renderWarning("No Telegram bot token configured.");
|
|
593601
593725
|
renderInfo("Set one first: /telegram --key <bot-token>");
|
|
593602
|
-
|
|
593726
|
+
const globalSettings = ctx3.getTelegramSettings?.("global") ?? {};
|
|
593727
|
+
if (globalSettings.key) {
|
|
593728
|
+
renderInfo("A global Telegram token exists, but it is no longer used implicitly inside project folders.");
|
|
593729
|
+
renderInfo("Use /telegram --global to start the shared bot, or /telegram --key <bot-token> to isolate this folder.");
|
|
593730
|
+
} else {
|
|
593731
|
+
renderInfo("Get a token from @BotFather on Telegram. The token saves project-locally by default when .omnius/ exists.");
|
|
593732
|
+
}
|
|
593603
593733
|
return "handled";
|
|
593604
593734
|
}
|
|
593605
593735
|
try {
|
|
@@ -593624,7 +593754,7 @@ sleep 1
|
|
|
593624
593754
|
} catch {
|
|
593625
593755
|
}
|
|
593626
593756
|
try {
|
|
593627
|
-
await ctx3.telegramStart?.(settings.key, settings.admin);
|
|
593757
|
+
await ctx3.telegramStart?.(settings.key, settings.admin, settings.keyScope ?? "project");
|
|
593628
593758
|
} catch (err) {
|
|
593629
593759
|
renderError(
|
|
593630
593760
|
`Telegram error: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -593636,7 +593766,9 @@ sleep 1
|
|
|
593636
593766
|
renderInfo("Usage:");
|
|
593637
593767
|
renderInfo(" /telegram --key <token> Save bot token (project-local when .omnius/ exists)");
|
|
593638
593768
|
renderInfo(" /telegram --admin <id> Set admin filter (project-local by default)");
|
|
593769
|
+
renderInfo(" /telegram revoke [--global] Revoke saved admin access");
|
|
593639
593770
|
renderInfo(" /telegram Toggle on/off");
|
|
593771
|
+
renderInfo(" /telegram --global Start/stop legacy shared global token explicitly");
|
|
593640
593772
|
renderInfo(" /telegram stop Stop bridge");
|
|
593641
593773
|
renderInfo(" /telegram status Show status");
|
|
593642
593774
|
renderInfo(" /telegram mode auto|chat|action Set interaction routing profile");
|
|
@@ -594519,7 +594651,7 @@ async function showPlatformOnboardingMenu(ctx3, id) {
|
|
|
594519
594651
|
if (!settings.key) renderWarning("No Telegram bot token configured.");
|
|
594520
594652
|
else if (ctx3.isTelegramActive?.()) {
|
|
594521
594653
|
renderWarning("Telegram bridge already active. Use /telegram stop before restarting.");
|
|
594522
|
-
} else await ctx3.telegramStart?.(settings.key, settings.admin);
|
|
594654
|
+
} else await ctx3.telegramStart?.(settings.key, settings.admin, settings.keyScope ?? "project");
|
|
594523
594655
|
} else if (result.key === "telegram-stop") {
|
|
594524
594656
|
ctx3.telegramStop?.();
|
|
594525
594657
|
}
|
|
@@ -596669,13 +596801,13 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
596669
596801
|
mkdirSync: mkdirSync81,
|
|
596670
596802
|
existsSync: exists2
|
|
596671
596803
|
} = await import("node:fs");
|
|
596672
|
-
const { homedir:
|
|
596804
|
+
const { homedir: homedir53 } = await import("node:os");
|
|
596673
596805
|
const modelName = basename30(onnxDrop.path, ".onnx").replace(
|
|
596674
596806
|
/[^a-zA-Z0-9_-]/g,
|
|
596675
596807
|
"-"
|
|
596676
596808
|
);
|
|
596677
596809
|
const destDir = pathJoin(
|
|
596678
|
-
|
|
596810
|
+
homedir53(),
|
|
596679
596811
|
".omnius",
|
|
596680
596812
|
"voice",
|
|
596681
596813
|
"models",
|
|
@@ -600202,12 +600334,12 @@ var init_commands = __esm({
|
|
|
600202
600334
|
if (val === "any" && !process.env["OMNIUS_API_KEY"]) {
|
|
600203
600335
|
try {
|
|
600204
600336
|
const { randomBytes: randomBytes27 } = await import("node:crypto");
|
|
600205
|
-
const { homedir:
|
|
600337
|
+
const { homedir: homedir53 } = await import("node:os");
|
|
600206
600338
|
const { mkdirSync: mkdirSync81, writeFileSync: writeFileSync73 } = await import("node:fs");
|
|
600207
600339
|
const { join: join148 } = await import("node:path");
|
|
600208
600340
|
const apiKey = randomBytes27(16).toString("hex");
|
|
600209
600341
|
process.env["OMNIUS_API_KEY"] = apiKey;
|
|
600210
|
-
const dir = join148(
|
|
600342
|
+
const dir = join148(homedir53(), ".omnius");
|
|
600211
600343
|
mkdirSync81(dir, { recursive: true });
|
|
600212
600344
|
writeFileSync73(join148(dir, "api.key"), apiKey + "\n", "utf8");
|
|
600213
600345
|
renderInfo(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
|
|
@@ -600227,10 +600359,10 @@ var init_commands = __esm({
|
|
|
600227
600359
|
}
|
|
600228
600360
|
const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
|
|
600229
600361
|
try {
|
|
600230
|
-
const { homedir:
|
|
600362
|
+
const { homedir: homedir53 } = await import("node:os");
|
|
600231
600363
|
const { mkdirSync: mkdirSync81, writeFileSync: writeFileSync73 } = await import("node:fs");
|
|
600232
600364
|
const { join: join148 } = await import("node:path");
|
|
600233
|
-
const dir = join148(
|
|
600365
|
+
const dir = join148(homedir53(), ".omnius");
|
|
600234
600366
|
mkdirSync81(dir, { recursive: true });
|
|
600235
600367
|
writeFileSync73(join148(dir, "access"), `${val}
|
|
600236
600368
|
`, "utf8");
|
|
@@ -609439,6 +609571,7 @@ var init_vision_ingress = __esm({
|
|
|
609439
609571
|
// packages/cli/src/tui/telegram-bridge.ts
|
|
609440
609572
|
import { mkdirSync as mkdirSync65, existsSync as existsSync113, unlinkSync as unlinkSync22, readdirSync as readdirSync40, statSync as statSync39, statfsSync as statfsSync5, readFileSync as readFileSync92, writeFileSync as writeFileSync59, appendFileSync as appendFileSync9 } from "node:fs";
|
|
609441
609573
|
import { join as join127, resolve as resolve43, basename as basename27, relative as relative13, isAbsolute as isAbsolute8, extname as extname16 } from "node:path";
|
|
609574
|
+
import { homedir as homedir40 } from "node:os";
|
|
609442
609575
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
609443
609576
|
import { createHash as createHash23, randomBytes as randomBytes22, randomInt } from "node:crypto";
|
|
609444
609577
|
function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
|
|
@@ -609958,6 +610091,13 @@ function telegramMemoryTokens(text) {
|
|
|
609958
610091
|
}
|
|
609959
610092
|
return tokens;
|
|
609960
610093
|
}
|
|
610094
|
+
function telegramMeaningfulMemoryTokens(text) {
|
|
610095
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
610096
|
+
for (const token of telegramMemoryTokens(text)) {
|
|
610097
|
+
if (!TELEGRAM_MEMORY_GENERIC_QUERY_TOKENS.has(token)) tokens.add(token);
|
|
610098
|
+
}
|
|
610099
|
+
return tokens;
|
|
610100
|
+
}
|
|
609961
610101
|
function telegramMemorySimilarity(a2, b) {
|
|
609962
610102
|
if (a2.size === 0 || b.size === 0) return 0;
|
|
609963
610103
|
let intersection = 0;
|
|
@@ -610096,8 +610236,7 @@ function telegramSyntheticHelpSignatures() {
|
|
|
610096
610236
|
function telegramHelpCommandAllowed(cmd, scope) {
|
|
610097
610237
|
if (cmd.name === "dream") return false;
|
|
610098
610238
|
if (scope === "admin") return cmd.implementationStatus === "implemented";
|
|
610099
|
-
|
|
610100
|
-
return cmd.surfaces.agentTool && !cmd.safety.secretBearing && !cmd.safety.destructive && !cmd.safety.profileGated;
|
|
610239
|
+
return TELEGRAM_PUBLIC_HELP_COMMANDS.has(cmd.name) || TELEGRAM_PUBLIC_BOT_COMMAND_NAMES.has(cmd.name);
|
|
610101
610240
|
}
|
|
610102
610241
|
function buildTelegramHelpHTML(scope, maxPublicCommands = 24) {
|
|
610103
610242
|
const commands = listCommandRegistry({ includePlanned: false }).filter((cmd) => telegramHelpCommandAllowed(cmd, scope));
|
|
@@ -610794,7 +610933,7 @@ function renderTelegramSubAgentError(username, error) {
|
|
|
610794
610933
|
process.stdout.write(` ${c3.dim("│")} ${c3.red("✘")} @${username}: ${c3.dim(preview)}
|
|
610795
610934
|
`);
|
|
610796
610935
|
}
|
|
610797
|
-
var TELEGRAM_TOOL_ACTION_GROUPS, TELEGRAM_TOOL_ACTION_GROUP, TELEGRAM_TOOL_MUTATING_GROUPS, DEFAULT_TELEGRAM_TOOL_GROUP_POLICY, TELEGRAM_TOOL_BUTTON_LABELS, TELEGRAM_SAFETY_PROMPT, ADMIN_DM_PROMPT, ADMIN_GROUP_PROMPT, TELEGRAM_PUBLIC_SOUL_PROFILE, TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT, TELEGRAM_PUBLIC_MEMORY_SCOPE_CONTRACT, TELEGRAM_PUBLIC_VISION_STACK_CONTRACT, GROUP_REPLY_DISCRETION_PROMPT, TELEGRAM_CHAT_MODE_PROMPT, ADMIN_CHAT_PROFILE_PROMPT, TELEGRAM_ACTION_RESPONSE_CONTRACT, TELEGRAM_EXTERNAL_ACQUISITION_CONTRACT, TELEGRAM_STUCK_SELF_TALK_PREFIXES, TELEGRAM_CHAT_HISTORY_LIMIT, TELEGRAM_CONTEXT_RECENT_DEFAULT, TELEGRAM_CONTEXT_LINE_LIMIT, TELEGRAM_CONTEXT_SAMPLE_LIMIT, TELEGRAM_MEMORY_CARD_LIMIT, TELEGRAM_MEMORY_NOTE_LIMIT, TELEGRAM_ASSOCIATIVE_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_USER_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_ACTION_LIMIT, TELEGRAM_ASSOCIATIVE_RELATION_LIMIT, TELEGRAM_MEMORY_STOPWORDS, TELEGRAM_SUB_AGENT_BOUNDED_OPTIONS, TELEGRAM_PUBLIC_HELP_COMMANDS, TELEGRAM_REMINDER_SLASH_COMMANDS, TELEGRAM_REFLECTION_SLASH_COMMANDS, TELEGRAM_IMAGE_EXTENSIONS, MEDIA_CACHE_TTL_MS, TELEGRAM_CHANNEL_DMN_SWEEP_MS, TELEGRAM_CHANNEL_DMN_IDLE_AFTER_MS, TELEGRAM_CHANNEL_DMN_MIN_INTERVAL_MS, TELEGRAM_CHANNEL_DMN_MIN_MESSAGES, TELEGRAM_PUBLIC_TOOL_QUOTAS, TelegramBridge;
|
|
610936
|
+
var TELEGRAM_TOOL_ACTION_GROUPS, TELEGRAM_TOOL_ACTION_GROUP, TELEGRAM_TOOL_MUTATING_GROUPS, DEFAULT_TELEGRAM_TOOL_GROUP_POLICY, TELEGRAM_TOOL_BUTTON_LABELS, TELEGRAM_SAFETY_PROMPT, ADMIN_DM_PROMPT, ADMIN_GROUP_PROMPT, TELEGRAM_PUBLIC_SOUL_PROFILE, TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT, TELEGRAM_PUBLIC_MEMORY_SCOPE_CONTRACT, TELEGRAM_PUBLIC_VISION_STACK_CONTRACT, GROUP_REPLY_DISCRETION_PROMPT, TELEGRAM_CHAT_MODE_PROMPT, ADMIN_CHAT_PROFILE_PROMPT, TELEGRAM_ACTION_RESPONSE_CONTRACT, TELEGRAM_EXTERNAL_ACQUISITION_CONTRACT, TELEGRAM_STUCK_SELF_TALK_PREFIXES, TELEGRAM_CHAT_HISTORY_LIMIT, TELEGRAM_CONTEXT_RECENT_DEFAULT, TELEGRAM_CONTEXT_LINE_LIMIT, TELEGRAM_CONTEXT_SAMPLE_LIMIT, TELEGRAM_MEMORY_CARD_LIMIT, TELEGRAM_MEMORY_NOTE_LIMIT, TELEGRAM_ASSOCIATIVE_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_USER_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_ACTION_LIMIT, TELEGRAM_ASSOCIATIVE_RELATION_LIMIT, TELEGRAM_MEMORY_STOPWORDS, TELEGRAM_MEMORY_GENERIC_QUERY_TOKENS, TELEGRAM_SUB_AGENT_BOUNDED_OPTIONS, TELEGRAM_PUBLIC_HELP_COMMANDS, TELEGRAM_REMINDER_SLASH_COMMANDS, TELEGRAM_REFLECTION_SLASH_COMMANDS, TELEGRAM_PUBLIC_BOT_COMMAND_NAMES, TELEGRAM_IMAGE_EXTENSIONS, MEDIA_CACHE_TTL_MS, TELEGRAM_CHANNEL_DMN_SWEEP_MS, TELEGRAM_CHANNEL_DMN_IDLE_AFTER_MS, TELEGRAM_CHANNEL_DMN_MIN_INTERVAL_MS, TELEGRAM_CHANNEL_DMN_MIN_MESSAGES, TELEGRAM_PUBLIC_TOOL_QUOTAS, TelegramBridge;
|
|
610798
610937
|
var init_telegram_bridge = __esm({
|
|
610799
610938
|
"packages/cli/src/tui/telegram-bridge.ts"() {
|
|
610800
610939
|
"use strict";
|
|
@@ -611118,6 +611257,47 @@ External acquisition contract:
|
|
|
611118
611257
|
"you",
|
|
611119
611258
|
"your"
|
|
611120
611259
|
]);
|
|
611260
|
+
TELEGRAM_MEMORY_GENERIC_QUERY_TOKENS = /* @__PURE__ */ new Set([
|
|
611261
|
+
"active",
|
|
611262
|
+
"activity",
|
|
611263
|
+
"breakdown",
|
|
611264
|
+
"conversation",
|
|
611265
|
+
"convo",
|
|
611266
|
+
"count",
|
|
611267
|
+
"counts",
|
|
611268
|
+
"earliest",
|
|
611269
|
+
"entries",
|
|
611270
|
+
"entry",
|
|
611271
|
+
"find",
|
|
611272
|
+
"first",
|
|
611273
|
+
"give",
|
|
611274
|
+
"group",
|
|
611275
|
+
"latest",
|
|
611276
|
+
"memory",
|
|
611277
|
+
"memories",
|
|
611278
|
+
"mention",
|
|
611279
|
+
"mentioned",
|
|
611280
|
+
"mentions",
|
|
611281
|
+
"message",
|
|
611282
|
+
"messages",
|
|
611283
|
+
"most",
|
|
611284
|
+
"newest",
|
|
611285
|
+
"oldest",
|
|
611286
|
+
"recent",
|
|
611287
|
+
"recall",
|
|
611288
|
+
"show",
|
|
611289
|
+
"some",
|
|
611290
|
+
"stats",
|
|
611291
|
+
"statistics",
|
|
611292
|
+
"summary",
|
|
611293
|
+
"summarize",
|
|
611294
|
+
"tell",
|
|
611295
|
+
"today",
|
|
611296
|
+
"turn",
|
|
611297
|
+
"turns",
|
|
611298
|
+
"who",
|
|
611299
|
+
"yesterday"
|
|
611300
|
+
]);
|
|
611121
611301
|
TELEGRAM_SUB_AGENT_BOUNDED_OPTIONS = {
|
|
611122
611302
|
bruteForce: false,
|
|
611123
611303
|
bruteForceMaxCycles: 0,
|
|
@@ -611126,6 +611306,9 @@ External acquisition contract:
|
|
|
611126
611306
|
TELEGRAM_PUBLIC_HELP_COMMANDS = /* @__PURE__ */ new Set(["help", "start", "auth", "call"]);
|
|
611127
611307
|
TELEGRAM_REMINDER_SLASH_COMMANDS = /* @__PURE__ */ new Set(["remind", "reminder", "reminders"]);
|
|
611128
611308
|
TELEGRAM_REFLECTION_SLASH_COMMANDS = /* @__PURE__ */ new Set(["reflect", "reflection", "daydream", "dream"]);
|
|
611309
|
+
TELEGRAM_PUBLIC_BOT_COMMAND_NAMES = new Set(
|
|
611310
|
+
buildTelegramBotCommands({ scope: "public" }).map((cmd) => cmd.command)
|
|
611311
|
+
);
|
|
611129
611312
|
TELEGRAM_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".tiff", ".tif", ".svg"]);
|
|
611130
611313
|
MEDIA_CACHE_TTL_MS = 30 * 60 * 1e3;
|
|
611131
611314
|
TELEGRAM_CHANNEL_DMN_SWEEP_MS = 2 * 60 * 1e3;
|
|
@@ -611153,6 +611336,7 @@ External acquisition contract:
|
|
|
611153
611336
|
this.telegramConversationDir = resolve43(repoRoot || ".", ".omnius", "telegram-conversations");
|
|
611154
611337
|
this.telegramSqlitePath = resolve43(repoRoot || ".", ".omnius", "telegram.sqlite");
|
|
611155
611338
|
this.telegramToolButtonDir = resolve43(repoRoot || ".", ".omnius", "telegram-tool-buttons");
|
|
611339
|
+
this.hydrateTelegramCommandMap(buildTelegramBotCommands({ scope: "admin" }));
|
|
611156
611340
|
}
|
|
611157
611341
|
botToken;
|
|
611158
611342
|
onMessage;
|
|
@@ -611243,6 +611427,7 @@ External acquisition contract:
|
|
|
611243
611427
|
* (which would cause silent 409 conflicts on getUpdates). Released in stop().
|
|
611244
611428
|
*/
|
|
611245
611429
|
telegramOwnerLockFile = null;
|
|
611430
|
+
telegramOwnerLockFiles = [];
|
|
611246
611431
|
/** Session keys loaded from persistent conversation memory */
|
|
611247
611432
|
loadedConversationState = /* @__PURE__ */ new Set();
|
|
611248
611433
|
/** True once persisted Telegram conversation scopes have been bulk-loaded. */
|
|
@@ -611381,6 +611566,9 @@ External acquisition contract:
|
|
|
611381
611566
|
const botless = first2.startsWith("/") ? first2.slice(1).split("@")[0]?.toLowerCase() : "";
|
|
611382
611567
|
return !!botless && this.telegramCommandMap.has(botless);
|
|
611383
611568
|
}
|
|
611569
|
+
isPublicTelegramSlashName(name10) {
|
|
611570
|
+
return TELEGRAM_PUBLIC_BOT_COMMAND_NAMES.has(name10);
|
|
611571
|
+
}
|
|
611384
611572
|
async handleTelegramReminderSlash(msg, commandText, context2) {
|
|
611385
611573
|
if (!this.repoRoot) {
|
|
611386
611574
|
await this.replyToTelegramMessage(msg, "Reminder storage is not available yet.");
|
|
@@ -613262,32 +613450,170 @@ ${lines.join("\n")}`);
|
|
|
613262
613450
|
ORDER BY received_at DESC
|
|
613263
613451
|
LIMIT ?
|
|
613264
613452
|
`).all(sessionKey, limit);
|
|
613265
|
-
return rows.reverse().map((row) => (
|
|
613266
|
-
role: row.role === "assistant" ? "assistant" : "user",
|
|
613267
|
-
text: String(row.text || ""),
|
|
613268
|
-
ts: Number(row.received_at || 0) || void 0,
|
|
613269
|
-
chatId: row.chat_id,
|
|
613270
|
-
speaker: row.role === "assistant" ? `@${this.state.botUsername || "omnius"}` : row.username ? `@${row.username}` : row.from_user_id ? `user:${row.from_user_id}` : "unknown",
|
|
613271
|
-
username: row.username || void 0,
|
|
613272
|
-
firstName: row.first_name || void 0,
|
|
613273
|
-
fromUserId: typeof row.from_user_id === "number" ? row.from_user_id : void 0,
|
|
613274
|
-
messageId: typeof row.message_id === "number" ? row.message_id : void 0,
|
|
613275
|
-
messageThreadId: typeof row.message_thread_id === "number" ? row.message_thread_id : void 0,
|
|
613276
|
-
replyToMessageId: typeof row.reply_to_message_id === "number" ? row.reply_to_message_id : void 0,
|
|
613277
|
-
chatType: row.chat_type,
|
|
613278
|
-
chatTitle: row.chat_title || void 0,
|
|
613279
|
-
mediaSummary: row.media_json ? "media attached in raw Telegram SQLite mirror" : void 0
|
|
613280
|
-
}));
|
|
613453
|
+
return rows.reverse().map((row) => this.telegramSqliteRowToHistoryEntry(row));
|
|
613281
613454
|
} catch {
|
|
613282
613455
|
return [];
|
|
613283
613456
|
}
|
|
613284
613457
|
}
|
|
613458
|
+
telegramSqliteRowToHistoryEntry(row) {
|
|
613459
|
+
const num = (value2) => {
|
|
613460
|
+
const n2 = Number(value2);
|
|
613461
|
+
return Number.isFinite(n2) ? n2 : void 0;
|
|
613462
|
+
};
|
|
613463
|
+
const role = row.role === "assistant" ? "assistant" : "user";
|
|
613464
|
+
const username = row.username ? String(row.username) : void 0;
|
|
613465
|
+
const fromUserId = num(row.from_user_id);
|
|
613466
|
+
return {
|
|
613467
|
+
role,
|
|
613468
|
+
text: String(row.text || ""),
|
|
613469
|
+
ts: num(row.received_at),
|
|
613470
|
+
chatId: row.chat_id,
|
|
613471
|
+
speaker: role === "assistant" ? `@${this.state.botUsername || username || "omnius"}` : username ? `@${username}` : fromUserId !== void 0 ? `user:${fromUserId}` : "unknown",
|
|
613472
|
+
username,
|
|
613473
|
+
firstName: row.first_name ? String(row.first_name) : void 0,
|
|
613474
|
+
fromUserId,
|
|
613475
|
+
messageId: num(row.message_id),
|
|
613476
|
+
messageThreadId: num(row.message_thread_id),
|
|
613477
|
+
replyToMessageId: num(row.reply_to_message_id),
|
|
613478
|
+
chatType: row.chat_type,
|
|
613479
|
+
chatTitle: row.chat_title || void 0,
|
|
613480
|
+
mediaSummary: row.media_json ? "media attached in raw Telegram SQLite mirror" : void 0
|
|
613481
|
+
};
|
|
613482
|
+
}
|
|
613483
|
+
telegramMergedHistoryForSession(sessionKey, limit = TELEGRAM_CHAT_HISTORY_LIMIT) {
|
|
613484
|
+
const sqliteHistory = this.telegramSqliteHistoryForSession(sessionKey, limit);
|
|
613485
|
+
const rollingHistory = this.chatHistory.get(sessionKey) ?? [];
|
|
613486
|
+
if (sqliteHistory.length === 0) return rollingHistory.slice(-limit);
|
|
613487
|
+
const merged = /* @__PURE__ */ new Map();
|
|
613488
|
+
const keyFor = (entry) => {
|
|
613489
|
+
if (entry.messageId !== void 0 && entry.messageId > 0) {
|
|
613490
|
+
return `msg:${entry.chatId ?? sessionKey}:${entry.role}:${entry.messageId}`;
|
|
613491
|
+
}
|
|
613492
|
+
return `synthetic:${entry.role}:${entry.ts ?? ""}:${telegramHistorySpeaker(entry)}:${entry.text}`;
|
|
613493
|
+
};
|
|
613494
|
+
for (const entry of sqliteHistory) merged.set(keyFor(entry), entry);
|
|
613495
|
+
for (const entry of rollingHistory) merged.set(keyFor(entry), entry);
|
|
613496
|
+
return [...merged.values()].sort((a2, b) => (a2.ts ?? 0) - (b.ts ?? 0)).slice(-limit);
|
|
613497
|
+
}
|
|
613498
|
+
telegramHistoryAnchorsForSession(sessionKey, earliestLimit = 3) {
|
|
613499
|
+
const db = this.telegramDb();
|
|
613500
|
+
if (db) {
|
|
613501
|
+
try {
|
|
613502
|
+
const earliestRows = db.prepare(`
|
|
613503
|
+
SELECT * FROM telegram_messages
|
|
613504
|
+
WHERE session_key = ?
|
|
613505
|
+
ORDER BY received_at ASC, rowid ASC
|
|
613506
|
+
LIMIT ?
|
|
613507
|
+
`).all(sessionKey, Math.max(1, Math.min(10, Math.floor(earliestLimit))));
|
|
613508
|
+
const latestRow = db.prepare(`
|
|
613509
|
+
SELECT * FROM telegram_messages
|
|
613510
|
+
WHERE session_key = ?
|
|
613511
|
+
ORDER BY received_at DESC, rowid DESC
|
|
613512
|
+
LIMIT 1
|
|
613513
|
+
`).get(sessionKey);
|
|
613514
|
+
if (earliestRows.length > 0 || latestRow) {
|
|
613515
|
+
return {
|
|
613516
|
+
earliest: earliestRows.map((row) => this.telegramSqliteRowToHistoryEntry(row)),
|
|
613517
|
+
latest: latestRow ? this.telegramSqliteRowToHistoryEntry(latestRow) : void 0
|
|
613518
|
+
};
|
|
613519
|
+
}
|
|
613520
|
+
} catch {
|
|
613521
|
+
}
|
|
613522
|
+
}
|
|
613523
|
+
const sorted = [...this.chatHistory.get(sessionKey) ?? []].filter((entry) => typeof entry.ts === "number" && Number.isFinite(entry.ts)).sort((a2, b) => (a2.ts ?? 0) - (b.ts ?? 0));
|
|
613524
|
+
return {
|
|
613525
|
+
earliest: sorted.slice(0, Math.max(1, Math.min(10, Math.floor(earliestLimit)))),
|
|
613526
|
+
latest: sorted.length > 0 ? sorted[sorted.length - 1] : void 0
|
|
613527
|
+
};
|
|
613528
|
+
}
|
|
613529
|
+
telegramParticipantActivityStats(sessionKey, options2 = {}) {
|
|
613530
|
+
const limit = Math.max(1, Math.min(20, Math.floor(options2.limit ?? 8)));
|
|
613531
|
+
const username = (options2.username || "").replace(/^@/, "").trim().toLowerCase();
|
|
613532
|
+
const db = this.telegramDb();
|
|
613533
|
+
if (db) {
|
|
613534
|
+
const clauses = ["session_key = ?"];
|
|
613535
|
+
const params = [sessionKey];
|
|
613536
|
+
if (options2.userId !== void 0) {
|
|
613537
|
+
clauses.push("from_user_id = ?");
|
|
613538
|
+
params.push(options2.userId);
|
|
613539
|
+
}
|
|
613540
|
+
if (username) {
|
|
613541
|
+
clauses.push("lower(username) = ?");
|
|
613542
|
+
params.push(username);
|
|
613543
|
+
}
|
|
613544
|
+
if (options2.since !== void 0) {
|
|
613545
|
+
clauses.push("received_at >= ?");
|
|
613546
|
+
params.push(options2.since);
|
|
613547
|
+
}
|
|
613548
|
+
if (options2.until !== void 0) {
|
|
613549
|
+
clauses.push("received_at <= ?");
|
|
613550
|
+
params.push(options2.until);
|
|
613551
|
+
}
|
|
613552
|
+
try {
|
|
613553
|
+
const rows = db.prepare(`
|
|
613554
|
+
SELECT
|
|
613555
|
+
role,
|
|
613556
|
+
from_user_id,
|
|
613557
|
+
lower(COALESCE(username, '')) AS username_key,
|
|
613558
|
+
COALESCE(username, '') AS username,
|
|
613559
|
+
COALESCE(first_name, '') AS first_name,
|
|
613560
|
+
COUNT(*) AS n,
|
|
613561
|
+
MIN(received_at) AS first_ts,
|
|
613562
|
+
MAX(received_at) AS last_ts
|
|
613563
|
+
FROM telegram_messages
|
|
613564
|
+
WHERE ${clauses.join(" AND ")}
|
|
613565
|
+
GROUP BY role, from_user_id, username_key, first_name
|
|
613566
|
+
ORDER BY n DESC, last_ts DESC
|
|
613567
|
+
LIMIT ?
|
|
613568
|
+
`).all(...params, limit);
|
|
613569
|
+
return rows.map((row) => {
|
|
613570
|
+
const role = row.role === "assistant" ? "assistant" : "user";
|
|
613571
|
+
const fromUserId = Number(row.from_user_id);
|
|
613572
|
+
const speaker = role === "assistant" ? `@${this.state.botUsername || row.username || "omnius"}` : row.username ? `@${row.username}` : Number.isFinite(fromUserId) ? `user:${fromUserId}` : row.first_name || "unknown";
|
|
613573
|
+
const firstTs = Number(row.first_ts);
|
|
613574
|
+
const lastTs = Number(row.last_ts);
|
|
613575
|
+
return {
|
|
613576
|
+
speaker,
|
|
613577
|
+
count: Number(row.n) || 0,
|
|
613578
|
+
firstTs: Number.isFinite(firstTs) ? firstTs : void 0,
|
|
613579
|
+
lastTs: Number.isFinite(lastTs) ? lastTs : void 0
|
|
613580
|
+
};
|
|
613581
|
+
});
|
|
613582
|
+
} catch {
|
|
613583
|
+
}
|
|
613584
|
+
}
|
|
613585
|
+
const stats = /* @__PURE__ */ new Map();
|
|
613586
|
+
for (const entry of this.telegramMergedHistoryForSession(sessionKey)) {
|
|
613587
|
+
if (options2.userId !== void 0 && entry.fromUserId !== options2.userId) continue;
|
|
613588
|
+
if (username && (entry.username || "").replace(/^@/, "").toLowerCase() !== username) continue;
|
|
613589
|
+
if (options2.since !== void 0 && (entry.ts ?? 0) < options2.since) continue;
|
|
613590
|
+
if (options2.until !== void 0 && (entry.ts ?? 0) > options2.until) continue;
|
|
613591
|
+
const speaker = telegramHistorySpeaker(entry);
|
|
613592
|
+
const current = stats.get(speaker) ?? { speaker, count: 0 };
|
|
613593
|
+
current.count += 1;
|
|
613594
|
+
if (entry.ts !== void 0) {
|
|
613595
|
+
current.firstTs = current.firstTs === void 0 ? entry.ts : Math.min(current.firstTs, entry.ts);
|
|
613596
|
+
current.lastTs = current.lastTs === void 0 ? entry.ts : Math.max(current.lastTs, entry.ts);
|
|
613597
|
+
}
|
|
613598
|
+
stats.set(speaker, current);
|
|
613599
|
+
}
|
|
613600
|
+
return [...stats.values()].sort((a2, b) => b.count - a2.count || (b.lastTs ?? 0) - (a2.lastTs ?? 0)).slice(0, limit);
|
|
613601
|
+
}
|
|
613602
|
+
formatTelegramParticipantActivityStats(stats) {
|
|
613603
|
+
return stats.map((stat7) => {
|
|
613604
|
+
const first2 = stat7.firstTs ? new Date(stat7.firstTs).toISOString() : "?";
|
|
613605
|
+
const last2 = stat7.lastTs ? new Date(stat7.lastTs).toISOString() : "?";
|
|
613606
|
+
return `- ${stat7.speaker}: ${stat7.count} message${stat7.count === 1 ? "" : "s"} (first:${first2}, last:${last2})`;
|
|
613607
|
+
}).join("\n");
|
|
613608
|
+
}
|
|
613285
613609
|
searchTelegramSqliteMirrorRows(sessionKey, query, options2 = {}) {
|
|
613286
613610
|
const db = this.telegramDb();
|
|
613287
613611
|
if (!db) return [];
|
|
613288
613612
|
const limit = Math.max(1, Math.min(50, Math.floor(options2.limit ?? 12)));
|
|
613289
613613
|
const username = (options2.username || "").replace(/^@/, "").trim().toLowerCase();
|
|
613614
|
+
const direction = options2.bucket === "earliest" ? "ASC" : "DESC";
|
|
613290
613615
|
const tokens = [...telegramMemoryTokens(query)].slice(0, 8);
|
|
613616
|
+
const meaningfulTokens = [...telegramMeaningfulMemoryTokens(query)].slice(0, 8);
|
|
613291
613617
|
const rows = /* @__PURE__ */ new Map();
|
|
613292
613618
|
const addRows = (items) => {
|
|
613293
613619
|
for (const row of items) {
|
|
@@ -613295,44 +613621,66 @@ ${lines.join("\n")}`);
|
|
|
613295
613621
|
if (Number.isFinite(key)) rows.set(key, row);
|
|
613296
613622
|
}
|
|
613297
613623
|
};
|
|
613624
|
+
const baseWhere = (extraClauses = [], extraParams = []) => {
|
|
613625
|
+
const clauses = ["session_key = ?"];
|
|
613626
|
+
const params = [sessionKey];
|
|
613627
|
+
if (options2.since !== void 0) {
|
|
613628
|
+
clauses.push("received_at >= ?");
|
|
613629
|
+
params.push(options2.since);
|
|
613630
|
+
}
|
|
613631
|
+
if (options2.until !== void 0) {
|
|
613632
|
+
clauses.push("received_at <= ?");
|
|
613633
|
+
params.push(options2.until);
|
|
613634
|
+
}
|
|
613635
|
+
clauses.push(...extraClauses);
|
|
613636
|
+
params.push(...extraParams);
|
|
613637
|
+
return { where: clauses.join(" AND "), params };
|
|
613638
|
+
};
|
|
613639
|
+
const scopedWhere = (extraClauses = [], extraParams = []) => {
|
|
613640
|
+
const clauses = [...extraClauses];
|
|
613641
|
+
const params = [...extraParams];
|
|
613642
|
+
if (options2.userId !== void 0) {
|
|
613643
|
+
clauses.unshift("from_user_id = ?");
|
|
613644
|
+
params.unshift(options2.userId);
|
|
613645
|
+
}
|
|
613646
|
+
if (username) {
|
|
613647
|
+
clauses.unshift("lower(username) = ?");
|
|
613648
|
+
params.unshift(username);
|
|
613649
|
+
}
|
|
613650
|
+
return baseWhere(clauses, params);
|
|
613651
|
+
};
|
|
613652
|
+
const selectRows = (where, params, rowLimit = limit) => db.prepare(`
|
|
613653
|
+
SELECT rowid, * FROM telegram_messages
|
|
613654
|
+
WHERE ${where}
|
|
613655
|
+
ORDER BY received_at ${direction}, rowid ${direction}
|
|
613656
|
+
LIMIT ?
|
|
613657
|
+
`).all(...params, rowLimit);
|
|
613298
613658
|
try {
|
|
613299
613659
|
if (options2.userId !== void 0) {
|
|
613300
|
-
|
|
613301
|
-
|
|
613302
|
-
WHERE session_key = ? AND from_user_id = ?
|
|
613303
|
-
ORDER BY received_at DESC
|
|
613304
|
-
LIMIT ?
|
|
613305
|
-
`).all(sessionKey, options2.userId, limit));
|
|
613660
|
+
const { where, params } = baseWhere(["from_user_id = ?"], [options2.userId]);
|
|
613661
|
+
addRows(selectRows(where, params));
|
|
613306
613662
|
}
|
|
613307
613663
|
if (username) {
|
|
613308
|
-
|
|
613309
|
-
|
|
613310
|
-
WHERE session_key = ? AND lower(username) = ?
|
|
613311
|
-
ORDER BY received_at DESC
|
|
613312
|
-
LIMIT ?
|
|
613313
|
-
`).all(sessionKey, username, limit));
|
|
613664
|
+
const { where, params } = baseWhere(["lower(username) = ?"], [username]);
|
|
613665
|
+
addRows(selectRows(where, params));
|
|
613314
613666
|
}
|
|
613315
613667
|
if (tokens.length > 0) {
|
|
613316
|
-
const clauses = tokens.map(() => "text LIKE ?").join(" OR ");
|
|
613317
|
-
|
|
613318
|
-
|
|
613319
|
-
|
|
613320
|
-
ORDER BY received_at DESC
|
|
613321
|
-
LIMIT ?
|
|
613322
|
-
`).all(sessionKey, ...tokens.map((token) => `%${token}%`), limit));
|
|
613668
|
+
const clauses = tokens.map(() => "(text LIKE ? OR lower(username) LIKE ? OR lower(first_name) LIKE ?)").join(" OR ");
|
|
613669
|
+
const tokenParams = tokens.flatMap((token) => [`%${token}%`, `%${token}%`, `%${token}%`]);
|
|
613670
|
+
const { where, params } = scopedWhere([`(${clauses})`], tokenParams);
|
|
613671
|
+
addRows(selectRows(where, params));
|
|
613323
613672
|
}
|
|
613324
|
-
if (rows.size === 0) {
|
|
613325
|
-
|
|
613326
|
-
|
|
613327
|
-
WHERE session_key = ?
|
|
613328
|
-
ORDER BY received_at DESC
|
|
613329
|
-
LIMIT ?
|
|
613330
|
-
`).all(sessionKey, Math.min(limit, 12)));
|
|
613673
|
+
if (rows.size === 0 && meaningfulTokens.length === 0) {
|
|
613674
|
+
const { where, params } = scopedWhere();
|
|
613675
|
+
addRows(selectRows(where, params, Math.min(limit, 20)));
|
|
613331
613676
|
}
|
|
613332
613677
|
} catch {
|
|
613333
613678
|
return [];
|
|
613334
613679
|
}
|
|
613335
|
-
return [...rows.values()].sort((a2, b) =>
|
|
613680
|
+
return [...rows.values()].sort((a2, b) => {
|
|
613681
|
+
const diff = Number(a2.received_at ?? 0) - Number(b.received_at ?? 0);
|
|
613682
|
+
return direction === "ASC" ? diff : -diff;
|
|
613683
|
+
}).slice(0, limit);
|
|
613336
613684
|
}
|
|
613337
613685
|
formatTelegramSqliteMirrorRows(rows, maxText = 260) {
|
|
613338
613686
|
return rows.map((row) => {
|
|
@@ -613463,6 +613811,7 @@ ${lines.join("\n")}`);
|
|
|
613463
613811
|
`- Associative relationships: ${relationshipCount}`,
|
|
613464
613812
|
`- Per-user memories: ${userMemoryCount}`,
|
|
613465
613813
|
`- Rolling history entries retained: ${historyCount}`,
|
|
613814
|
+
`- Addressable conversation history rows: ${Math.max(historyCount, sqliteCount)}`,
|
|
613466
613815
|
`- SQLite mirror rows: ${sqliteCount}`,
|
|
613467
613816
|
`- Episodes (durable, day+ scope): ${episodeCount2}`
|
|
613468
613817
|
];
|
|
@@ -613473,8 +613822,7 @@ ${lines.join("\n")}`);
|
|
|
613473
613822
|
lines.push(` - ${topic}`);
|
|
613474
613823
|
}
|
|
613475
613824
|
}
|
|
613476
|
-
const
|
|
613477
|
-
const sortedByTs = [...sourceHistory].filter((e2) => typeof e2.ts === "number" && Number.isFinite(e2.ts)).sort((a2, b) => (a2.ts ?? 0) - (b.ts ?? 0));
|
|
613825
|
+
const anchors = this.telegramHistoryAnchorsForSession(sessionKey, 3);
|
|
613478
613826
|
const fmtHistoryAnchor = (entry) => {
|
|
613479
613827
|
const when = entry.ts ? new Date(entry.ts).toISOString() : "(unknown ts)";
|
|
613480
613828
|
const speaker = telegramHistorySpeaker(entry);
|
|
@@ -613482,18 +613830,33 @@ ${lines.join("\n")}`);
|
|
|
613482
613830
|
const messageId = entry.messageId ? ` msg:${entry.messageId}` : "";
|
|
613483
613831
|
return `${when} ${speaker}${mode}${messageId}: ${telegramContextJsonString(String(entry.text || ""), 320)}`;
|
|
613484
613832
|
};
|
|
613485
|
-
|
|
613833
|
+
const sameHistoryAnchor = (a2, b) => {
|
|
613834
|
+
if (!a2 || !b) return false;
|
|
613835
|
+
if (a2.messageId !== void 0 && b.messageId !== void 0) return a2.messageId === b.messageId && a2.role === b.role;
|
|
613836
|
+
return a2.ts === b.ts && a2.role === b.role && a2.text === b.text;
|
|
613837
|
+
};
|
|
613838
|
+
if (anchors.earliest.length > 0 || anchors.latest) {
|
|
613486
613839
|
lines.push("");
|
|
613487
|
-
lines.push("Chronological anchors — Telegram conversation history (ground truth for 'oldest/newest memory' questions):");
|
|
613488
|
-
lines.push(` EARLIEST turn: ${fmtHistoryAnchor(
|
|
613489
|
-
if (
|
|
613490
|
-
lines.push(` LATEST turn: ${fmtHistoryAnchor(
|
|
613840
|
+
lines.push("Chronological anchors — Telegram conversation history (SQLite mirror preferred; ground truth for 'oldest/newest memory' questions):");
|
|
613841
|
+
if (anchors.earliest[0]) lines.push(` EARLIEST turn: ${fmtHistoryAnchor(anchors.earliest[0])}`);
|
|
613842
|
+
if (anchors.latest && !sameHistoryAnchor(anchors.earliest[0], anchors.latest)) {
|
|
613843
|
+
lines.push(` LATEST turn: ${fmtHistoryAnchor(anchors.latest)}`);
|
|
613844
|
+
}
|
|
613845
|
+
if (anchors.earliest[1]) {
|
|
613846
|
+
lines.push(` 2nd earliest: ${fmtHistoryAnchor(anchors.earliest[1])}`);
|
|
613491
613847
|
}
|
|
613492
|
-
if (
|
|
613493
|
-
lines.push(`
|
|
613848
|
+
if (anchors.earliest[2]) {
|
|
613849
|
+
lines.push(` 3rd earliest: ${fmtHistoryAnchor(anchors.earliest[2])}`);
|
|
613494
613850
|
}
|
|
613495
|
-
|
|
613496
|
-
|
|
613851
|
+
}
|
|
613852
|
+
const activityStats = this.telegramParticipantActivityStats(sessionKey, { limit: 8 });
|
|
613853
|
+
if (activityStats.length > 0) {
|
|
613854
|
+
lines.push("");
|
|
613855
|
+
lines.push("Activity anchors — participant message counts from the durable mirror/merged history:");
|
|
613856
|
+
for (const stat7 of activityStats) {
|
|
613857
|
+
const first2 = stat7.firstTs ? new Date(stat7.firstTs).toISOString() : "?";
|
|
613858
|
+
const last2 = stat7.lastTs ? new Date(stat7.lastTs).toISOString() : "?";
|
|
613859
|
+
lines.push(` - ${stat7.speaker}: ${stat7.count} message${stat7.count === 1 ? "" : "s"} (first:${first2}, last:${last2})`);
|
|
613497
613860
|
}
|
|
613498
613861
|
}
|
|
613499
613862
|
if (this.repoRoot) {
|
|
@@ -614221,37 +614584,23 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
614221
614584
|
if (!me?.ok) {
|
|
614222
614585
|
throw new Error(`Invalid Telegram bot token: ${me?.description || "unknown error"}`);
|
|
614223
614586
|
}
|
|
614224
|
-
if (
|
|
614587
|
+
if (me.result?.id) {
|
|
614588
|
+
const botUserId = Number(me.result.id);
|
|
614589
|
+
const globalLockDir = process.env["OMNIUS_TELEGRAM_LOCK_DIR"] ? resolve43(process.env["OMNIUS_TELEGRAM_LOCK_DIR"]) : resolve43(homedir40(), ".omnius", "telegram-runner-state");
|
|
614590
|
+
const lockDirs = /* @__PURE__ */ new Set([globalLockDir]);
|
|
614591
|
+
if (this.repoRoot) {
|
|
614592
|
+
lockDirs.add(resolve43(this.repoRoot, ".omnius", "telegram-runner-state"));
|
|
614593
|
+
}
|
|
614594
|
+
const claimed = [];
|
|
614225
614595
|
try {
|
|
614226
|
-
const lockDir
|
|
614227
|
-
|
|
614228
|
-
|
|
614229
|
-
if (existsSync113(lockFile)) {
|
|
614230
|
-
try {
|
|
614231
|
-
const prior = JSON.parse(readFileSync92(lockFile, "utf8"));
|
|
614232
|
-
const priorAlive = typeof prior.pid === "number" && prior.pid !== process.pid ? this.processIsAlive(prior.pid) : false;
|
|
614233
|
-
if (priorAlive) {
|
|
614234
|
-
throw new Error(
|
|
614235
|
-
`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.`
|
|
614236
|
-
);
|
|
614237
|
-
}
|
|
614238
|
-
} catch (e2) {
|
|
614239
|
-
if (e2 instanceof Error && e2.message.startsWith("Telegram bot @")) throw e2;
|
|
614240
|
-
}
|
|
614596
|
+
for (const lockDir of lockDirs) {
|
|
614597
|
+
const lockFile = this.claimTelegramOwnerLock(lockDir, botUserId, me.result.username);
|
|
614598
|
+
claimed.push(lockFile);
|
|
614241
614599
|
}
|
|
614242
|
-
|
|
614243
|
-
|
|
614244
|
-
JSON.stringify({
|
|
614245
|
-
pid: process.pid,
|
|
614246
|
-
cwd: this.repoRoot,
|
|
614247
|
-
botUsername: me.result.username,
|
|
614248
|
-
botUserId: me.result.id,
|
|
614249
|
-
ts: Date.now()
|
|
614250
|
-
}, null, 2),
|
|
614251
|
-
{ encoding: "utf-8", mode: 384 }
|
|
614252
|
-
);
|
|
614253
|
-
this.telegramOwnerLockFile = lockFile;
|
|
614600
|
+
this.telegramOwnerLockFiles = claimed;
|
|
614601
|
+
this.telegramOwnerLockFile = claimed[0] ?? null;
|
|
614254
614602
|
} catch (e2) {
|
|
614603
|
+
for (const lockFile of claimed) this.releaseTelegramOwnerLock(lockFile);
|
|
614255
614604
|
if (e2 instanceof Error && e2.message.startsWith("Telegram bot @")) throw e2;
|
|
614256
614605
|
}
|
|
614257
614606
|
}
|
|
@@ -614309,18 +614658,57 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
614309
614658
|
}
|
|
614310
614659
|
this.telegramSqliteDb = null;
|
|
614311
614660
|
}
|
|
614312
|
-
|
|
614661
|
+
const lockFiles = /* @__PURE__ */ new Set([
|
|
614662
|
+
...this.telegramOwnerLockFiles,
|
|
614663
|
+
...this.telegramOwnerLockFile ? [this.telegramOwnerLockFile] : []
|
|
614664
|
+
]);
|
|
614665
|
+
for (const lockFile of lockFiles) this.releaseTelegramOwnerLock(lockFile);
|
|
614666
|
+
this.telegramOwnerLockFiles = [];
|
|
614667
|
+
this.telegramOwnerLockFile = null;
|
|
614668
|
+
this.subAgents.clear();
|
|
614669
|
+
this.activeChatViews.clear();
|
|
614670
|
+
this.refreshActiveTelegramInteractionCount();
|
|
614671
|
+
}
|
|
614672
|
+
claimTelegramOwnerLock(lockDir, botUserId, botUsername) {
|
|
614673
|
+
mkdirSync65(lockDir, { recursive: true });
|
|
614674
|
+
const lockFile = join127(lockDir, `bot-${botUserId}.owner.lock`);
|
|
614675
|
+
if (existsSync113(lockFile)) {
|
|
614313
614676
|
try {
|
|
614314
|
-
|
|
614315
|
-
|
|
614677
|
+
const prior = JSON.parse(readFileSync92(lockFile, "utf8"));
|
|
614678
|
+
const priorAlive = typeof prior.pid === "number" && prior.pid !== process.pid ? this.processIsAlive(prior.pid) : false;
|
|
614679
|
+
if (priorAlive) {
|
|
614680
|
+
throw new Error(
|
|
614681
|
+
`Telegram bot @${prior.botUsername || botUsername || "unknown"} is already being polled by pid ${prior.pid} (cwd ${prior.cwd || "?"}). Stop that instance or use a different bot token in this project.`
|
|
614682
|
+
);
|
|
614316
614683
|
}
|
|
614684
|
+
} catch (e2) {
|
|
614685
|
+
if (e2 instanceof Error && e2.message.startsWith("Telegram bot @")) throw e2;
|
|
614686
|
+
}
|
|
614687
|
+
}
|
|
614688
|
+
writeFileSync59(
|
|
614689
|
+
lockFile,
|
|
614690
|
+
JSON.stringify({
|
|
614691
|
+
pid: process.pid,
|
|
614692
|
+
cwd: this.repoRoot || process.cwd(),
|
|
614693
|
+
botUsername,
|
|
614694
|
+
botUserId,
|
|
614695
|
+
ts: Date.now()
|
|
614696
|
+
}, null, 2),
|
|
614697
|
+
{ encoding: "utf-8", mode: 384 }
|
|
614698
|
+
);
|
|
614699
|
+
return lockFile;
|
|
614700
|
+
}
|
|
614701
|
+
releaseTelegramOwnerLock(lockFile) {
|
|
614702
|
+
try {
|
|
614703
|
+
if (!existsSync113(lockFile)) return;
|
|
614704
|
+
try {
|
|
614705
|
+
const prior = JSON.parse(readFileSync92(lockFile, "utf8"));
|
|
614706
|
+
if (prior.pid !== process.pid) return;
|
|
614317
614707
|
} catch {
|
|
614318
614708
|
}
|
|
614319
|
-
|
|
614709
|
+
unlinkSync22(lockFile);
|
|
614710
|
+
} catch {
|
|
614320
614711
|
}
|
|
614321
|
-
this.subAgents.clear();
|
|
614322
|
-
this.activeChatViews.clear();
|
|
614323
|
-
this.refreshActiveTelegramInteractionCount();
|
|
614324
614712
|
}
|
|
614325
614713
|
/**
|
|
614326
614714
|
* Cheap liveness probe: kill(pid, 0) throws ESRCH when the process is dead
|
|
@@ -614551,8 +614939,7 @@ Join: ${newUrl}`);
|
|
|
614551
614939
|
return;
|
|
614552
614940
|
}
|
|
614553
614941
|
}
|
|
614554
|
-
|
|
614555
|
-
if (!isAdmin && msg.text.trim().startsWith("/") && this.isKnownTelegramSlash(normalizedCommandText) && !publicCreativeSlash) {
|
|
614942
|
+
if (!isAdmin && msg.text.trim().startsWith("/") && this.isKnownTelegramSlash(normalizedCommandText) && !this.isPublicTelegramSlashName(telegramSlash)) {
|
|
614556
614943
|
await this.replyToTelegramMessage(
|
|
614557
614944
|
msg,
|
|
614558
614945
|
"That command requires Telegram admin authentication. Run /telegram auth in the TUI, then send /auth <code> here."
|
|
@@ -615446,7 +615833,9 @@ ${result.llmContent ?? result.output}` };
|
|
|
615446
615833
|
})(),
|
|
615447
615834
|
execute: async (args) => {
|
|
615448
615835
|
const rawQuery = String(args["query"] || "").trim();
|
|
615449
|
-
const
|
|
615836
|
+
const rawMaxResults = args["max_results"];
|
|
615837
|
+
const explicitMaxResults = typeof rawMaxResults === "number" && Number.isFinite(rawMaxResults);
|
|
615838
|
+
let maxResults = explicitMaxResults ? Math.max(1, Math.min(20, Math.floor(rawMaxResults))) : 8;
|
|
615450
615839
|
if (!rawQuery) return { success: true, output: "Search query is required." };
|
|
615451
615840
|
this.ensureTelegramConversationLoaded(msgSessionKey);
|
|
615452
615841
|
const parseTimeArg = (v) => {
|
|
@@ -615480,6 +615869,9 @@ ${result.llmContent ?? result.output}` };
|
|
|
615480
615869
|
bucket ? `bucket=${bucket}` : ""
|
|
615481
615870
|
].filter(Boolean).join(", ");
|
|
615482
615871
|
}
|
|
615872
|
+
if (!explicitMaxResults && (since !== void 0 || until !== void 0 || bucket !== void 0) && /\b(summary|summarize|conversation|convo|catch\s+me\s+up|what\s+happened|oldest|earliest|newest|latest|most\s+recent)\b/i.test(rawQuery)) {
|
|
615873
|
+
maxResults = 20;
|
|
615874
|
+
}
|
|
615483
615875
|
const inWindow = (ts) => {
|
|
615484
615876
|
if (since === void 0 && until === void 0) return true;
|
|
615485
615877
|
if (ts == null || !Number.isFinite(ts)) return false;
|
|
@@ -615516,6 +615908,7 @@ ${result.llmContent ?? result.output}` };
|
|
|
615516
615908
|
return false;
|
|
615517
615909
|
});
|
|
615518
615910
|
const queryTokens = telegramMemoryTokens(query);
|
|
615911
|
+
const meaningfulQueryTokens = telegramMeaningfulMemoryTokens(query);
|
|
615519
615912
|
const cardResults = cards.filter((card) => inWindow(card.updatedAt ?? card.createdAt)).map((card) => ({
|
|
615520
615913
|
card,
|
|
615521
615914
|
score: telegramMemorySimilarity(
|
|
@@ -615553,12 +615946,19 @@ ${notes2}`;
|
|
|
615553
615946
|
const rawRows = this.searchTelegramSqliteMirrorRows(msgSessionKey, query, {
|
|
615554
615947
|
limit: maxResults,
|
|
615555
615948
|
userId: effectiveUserId,
|
|
615556
|
-
username: effectiveUsername
|
|
615949
|
+
username: effectiveUsername,
|
|
615950
|
+
since,
|
|
615951
|
+
until,
|
|
615952
|
+
bucket
|
|
615557
615953
|
});
|
|
615558
|
-
const episodeResults = this.searchTelegramEpisodeMemory(msgSessionKey, query, maxResults)
|
|
615559
|
-
|
|
615954
|
+
const episodeResults = this.searchTelegramEpisodeMemory(msgSessionKey, query, maxResults).filter((episode) => inWindow(episode.timestamp)).sort((a2, b) => {
|
|
615955
|
+
if (bucket === "earliest") return (a2.timestamp ?? 0) - (b.timestamp ?? 0);
|
|
615956
|
+
if (bucket === "latest") return (b.timestamp ?? 0) - (a2.timestamp ?? 0);
|
|
615957
|
+
return 0;
|
|
615958
|
+
});
|
|
615959
|
+
const historyForScan = this.telegramMergedHistoryForSession(msgSessionKey);
|
|
615560
615960
|
const lowerQuery = query.toLowerCase().trim();
|
|
615561
|
-
const queryWords =
|
|
615961
|
+
const queryWords = [...meaningfulQueryTokens];
|
|
615562
615962
|
const hasTimeConstraint = since !== void 0 || until !== void 0 || bucket !== void 0;
|
|
615563
615963
|
const rawHistoryMatches = [];
|
|
615564
615964
|
if (historyForScan.length > 0) {
|
|
@@ -615570,7 +615970,12 @@ ${notes2}`;
|
|
|
615570
615970
|
if (!matchesUser) continue;
|
|
615571
615971
|
}
|
|
615572
615972
|
if (!inWindow(entry.ts ?? null)) continue;
|
|
615573
|
-
const hay =
|
|
615973
|
+
const hay = [
|
|
615974
|
+
entry.text || "",
|
|
615975
|
+
telegramHistorySpeaker(entry),
|
|
615976
|
+
entry.username || "",
|
|
615977
|
+
entry.firstName || ""
|
|
615978
|
+
].join(" ").toLowerCase();
|
|
615574
615979
|
if (!hay) continue;
|
|
615575
615980
|
let lexMatch = false;
|
|
615576
615981
|
if (lowerQuery.length > 0) {
|
|
@@ -615578,7 +615983,7 @@ ${notes2}`;
|
|
|
615578
615983
|
const tokenHits = queryWords.filter((w) => hay.includes(w)).length;
|
|
615579
615984
|
lexMatch = hasExact || queryWords.length > 0 && tokenHits >= Math.min(2, queryWords.length);
|
|
615580
615985
|
}
|
|
615581
|
-
if (lexMatch || hasTimeConstraint) {
|
|
615986
|
+
if (lexMatch || hasTimeConstraint && queryWords.length === 0) {
|
|
615582
615987
|
rawHistoryMatches.push(entry);
|
|
615583
615988
|
}
|
|
615584
615989
|
}
|
|
@@ -615591,6 +615996,44 @@ ${notes2}`;
|
|
|
615591
615996
|
const rawHistorySliced = rawHistoryMatches.slice(0, maxResults);
|
|
615592
615997
|
const scopeLabel = wantsUserScope ? `user ${effectiveUsername ? `@${effectiveUsername}` : `id ${effectiveUserId}`}` : `chat ${currentGroupId || msgSessionKey}`;
|
|
615593
615998
|
const sections = [];
|
|
615999
|
+
const wantsChronologicalAnchors = bucket !== void 0 || /\b(oldest|earliest|first|newest|latest|most\s+recent|how\s+far\s+back)\b/i.test(rawQuery);
|
|
616000
|
+
if (wantsChronologicalAnchors) {
|
|
616001
|
+
const anchors = this.telegramHistoryAnchorsForSession(msgSessionKey, maxResults);
|
|
616002
|
+
const anchorEntries = [
|
|
616003
|
+
...anchors.earliest.map((entry, index) => ({ label: index === 0 ? "EARLIEST" : `${index + 1}${index === 1 ? "nd" : index === 2 ? "rd" : "th"} earliest`, entry })),
|
|
616004
|
+
...anchors.latest ? [{ label: "LATEST", entry: anchors.latest }] : []
|
|
616005
|
+
];
|
|
616006
|
+
const seen = /* @__PURE__ */ new Set();
|
|
616007
|
+
const lines = anchorEntries.flatMap(({ label, entry }) => {
|
|
616008
|
+
const key = entry.messageId !== void 0 ? `${entry.role}:${entry.messageId}` : `${entry.role}:${entry.ts ?? ""}:${entry.text}`;
|
|
616009
|
+
if (seen.has(key)) return [];
|
|
616010
|
+
seen.add(key);
|
|
616011
|
+
const when = entry.ts ? new Date(entry.ts).toISOString() : "";
|
|
616012
|
+
const speaker = telegramHistorySpeaker(entry);
|
|
616013
|
+
const mode = entry.mode ? `/${entry.mode}` : "";
|
|
616014
|
+
const messageId = entry.messageId ? ` msg:${entry.messageId}` : "";
|
|
616015
|
+
return [`- ${label}: ${when} ${speaker}${mode}${messageId}: ${telegramContextJsonString(String(entry.text || ""), 320)}`];
|
|
616016
|
+
});
|
|
616017
|
+
if (lines.length > 0) {
|
|
616018
|
+
sections.push(`### Chronological Conversation Anchors
|
|
616019
|
+
SQLite mirror preferred; use these for oldest/newest recall.
|
|
616020
|
+
${lines.join("\n")}`);
|
|
616021
|
+
}
|
|
616022
|
+
}
|
|
616023
|
+
const wantsActivityStats = /\b(activity|stats|statistics|most\s+active|message\s+counts?|participant\s+counts?|who\s+(?:has\s+been\s+)?(?:is\s+)?(?:most\s+)?active)\b/i.test(rawQuery);
|
|
616024
|
+
if (wantsActivityStats) {
|
|
616025
|
+
const stats = this.telegramParticipantActivityStats(msgSessionKey, {
|
|
616026
|
+
limit: Math.min(12, maxResults),
|
|
616027
|
+
since,
|
|
616028
|
+
until,
|
|
616029
|
+
userId: effectiveUserId,
|
|
616030
|
+
username: effectiveUsername
|
|
616031
|
+
});
|
|
616032
|
+
if (stats.length > 0) {
|
|
616033
|
+
sections.push(`### Participant Activity Stats
|
|
616034
|
+
${this.formatTelegramParticipantActivityStats(stats)}`);
|
|
616035
|
+
}
|
|
616036
|
+
}
|
|
615594
616037
|
if (cardLines.length > 0) {
|
|
615595
616038
|
sections.push(`### Scoped Memory Cards
|
|
615596
616039
|
${cardLines.join("\n\n")}`);
|
|
@@ -617905,21 +618348,45 @@ Content-Type: ${mimeForPath(pathOrFileId, field === "photo" ? "image" : "video")
|
|
|
617905
618348
|
}
|
|
617906
618349
|
return this.sendMessage(`@${clean5}`, text);
|
|
617907
618350
|
}
|
|
617908
|
-
|
|
618351
|
+
hydrateTelegramCommandMap(commands) {
|
|
618352
|
+
for (const cmd of commands) {
|
|
618353
|
+
this.telegramCommandMap.set(cmd.command, cmd.canonical);
|
|
618354
|
+
}
|
|
618355
|
+
this.telegramCommandMap.set("auth", "auth");
|
|
618356
|
+
this.telegramCommandMap.set("start", "start");
|
|
618357
|
+
}
|
|
618358
|
+
async setMyCommands(commands, options2 = {}) {
|
|
617909
618359
|
const apiCommands = commands.map((cmd) => ({
|
|
617910
618360
|
command: cmd.command,
|
|
617911
618361
|
description: cmd.description
|
|
617912
618362
|
}));
|
|
617913
|
-
const
|
|
618363
|
+
const payload = { commands: apiCommands };
|
|
618364
|
+
if (options2.scope) payload["scope"] = options2.scope;
|
|
618365
|
+
if (options2.languageCode) payload["language_code"] = options2.languageCode;
|
|
618366
|
+
const result = await this.apiCall("setMyCommands", payload);
|
|
617914
618367
|
if (result.ok) {
|
|
617915
|
-
|
|
617916
|
-
this.telegramCommandMap.set(cmd.command, cmd.canonical);
|
|
617917
|
-
}
|
|
617918
|
-
this.telegramCommandMap.set("auth", "auth");
|
|
617919
|
-
this.telegramCommandMap.set("start", "start");
|
|
618368
|
+
this.hydrateTelegramCommandMap(commands);
|
|
617920
618369
|
}
|
|
617921
618370
|
return Boolean(result.ok);
|
|
617922
618371
|
}
|
|
618372
|
+
async registerScopedMyCommands(adminUserId = this.adminUserId) {
|
|
618373
|
+
const publicCommands = buildTelegramBotCommands({ scope: "public" });
|
|
618374
|
+
const adminCommands = buildTelegramBotCommands({ scope: "admin" });
|
|
618375
|
+
this.hydrateTelegramCommandMap([...publicCommands, ...adminCommands]);
|
|
618376
|
+
const publicOk = await this.setMyCommands(publicCommands, { scope: { type: "default" } });
|
|
618377
|
+
const adminId = adminUserId?.trim();
|
|
618378
|
+
if (!adminId || !/^\d+$/.test(adminId)) {
|
|
618379
|
+
return publicOk;
|
|
618380
|
+
}
|
|
618381
|
+
const adminChatId = Number(adminId);
|
|
618382
|
+
if (!Number.isSafeInteger(adminChatId)) {
|
|
618383
|
+
return publicOk;
|
|
618384
|
+
}
|
|
618385
|
+
const adminOk = await this.setMyCommands(adminCommands, {
|
|
618386
|
+
scope: { type: "chat", chat_id: adminChatId }
|
|
618387
|
+
});
|
|
618388
|
+
return publicOk && adminOk;
|
|
618389
|
+
}
|
|
617923
618390
|
async getMyCommands() {
|
|
617924
618391
|
const result = await this.apiCall("getMyCommands");
|
|
617925
618392
|
return Array.isArray(result.result) ? result.result : [];
|
|
@@ -618296,9 +618763,9 @@ import {
|
|
|
618296
618763
|
unlinkSync as unlinkSync23
|
|
618297
618764
|
} from "node:fs";
|
|
618298
618765
|
import { join as join128 } from "node:path";
|
|
618299
|
-
import { homedir as
|
|
618766
|
+
import { homedir as homedir41 } from "node:os";
|
|
618300
618767
|
function sessionsDir() {
|
|
618301
|
-
return join128(
|
|
618768
|
+
return join128(homedir41(), ".omnius", "chat-sessions");
|
|
618302
618769
|
}
|
|
618303
618770
|
function sessionPath(id) {
|
|
618304
618771
|
const safe = id.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
@@ -618938,7 +619405,7 @@ __export(projects_exports, {
|
|
|
618938
619405
|
unregisterProject: () => unregisterProject
|
|
618939
619406
|
});
|
|
618940
619407
|
import { readFileSync as readFileSync94, writeFileSync as writeFileSync61, mkdirSync as mkdirSync67, existsSync as existsSync115, statSync as statSync40, renameSync as renameSync7 } from "node:fs";
|
|
618941
|
-
import { homedir as
|
|
619408
|
+
import { homedir as homedir42 } from "node:os";
|
|
618942
619409
|
import { basename as basename28, join as join129, resolve as resolve44 } from "node:path";
|
|
618943
619410
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
618944
619411
|
function readAll2() {
|
|
@@ -619051,7 +619518,7 @@ var OMNIUS_DIR3, PROJECTS_FILE, CURRENT_FILE, currentRoot;
|
|
|
619051
619518
|
var init_projects = __esm({
|
|
619052
619519
|
"packages/cli/src/api/projects.ts"() {
|
|
619053
619520
|
"use strict";
|
|
619054
|
-
OMNIUS_DIR3 = join129(
|
|
619521
|
+
OMNIUS_DIR3 = join129(homedir42(), ".omnius");
|
|
619055
619522
|
PROJECTS_FILE = join129(OMNIUS_DIR3, "projects.json");
|
|
619056
619523
|
CURRENT_FILE = join129(OMNIUS_DIR3, "current-project");
|
|
619057
619524
|
currentRoot = null;
|
|
@@ -619758,7 +620225,7 @@ var init_access_policy = __esm({
|
|
|
619758
620225
|
// packages/cli/src/api/project-preferences.ts
|
|
619759
620226
|
import { createHash as createHash24 } from "node:crypto";
|
|
619760
620227
|
import { existsSync as existsSync116, mkdirSync as mkdirSync68, readFileSync as readFileSync95, renameSync as renameSync8, writeFileSync as writeFileSync62, unlinkSync as unlinkSync24 } from "node:fs";
|
|
619761
|
-
import { homedir as
|
|
620228
|
+
import { homedir as homedir43 } from "node:os";
|
|
619762
620229
|
import { join as join130, resolve as resolve45 } from "node:path";
|
|
619763
620230
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
619764
620231
|
function projectKey(root) {
|
|
@@ -619839,7 +620306,7 @@ var OMNIUS_DIR4, PROJECTS_DIR, SCHEMA_VERSION, DEFAULT_PREFS;
|
|
|
619839
620306
|
var init_project_preferences = __esm({
|
|
619840
620307
|
"packages/cli/src/api/project-preferences.ts"() {
|
|
619841
620308
|
"use strict";
|
|
619842
|
-
OMNIUS_DIR4 = join130(
|
|
620309
|
+
OMNIUS_DIR4 = join130(homedir43(), ".omnius");
|
|
619843
620310
|
PROJECTS_DIR = join130(OMNIUS_DIR4, "projects");
|
|
619844
620311
|
SCHEMA_VERSION = 1;
|
|
619845
620312
|
DEFAULT_PREFS = {
|
|
@@ -621115,7 +621582,7 @@ __export(aiwg_exports, {
|
|
|
621115
621582
|
});
|
|
621116
621583
|
import { existsSync as existsSync119, readFileSync as readFileSync97, readdirSync as readdirSync42, statSync as statSync42 } from "node:fs";
|
|
621117
621584
|
import { join as join132 } from "node:path";
|
|
621118
|
-
import { homedir as
|
|
621585
|
+
import { homedir as homedir44 } from "node:os";
|
|
621119
621586
|
import { execSync as execSync55 } from "node:child_process";
|
|
621120
621587
|
function resolveAiwgRoot() {
|
|
621121
621588
|
if (_cachedAiwgRoot !== void 0) return _cachedAiwgRoot;
|
|
@@ -621124,7 +621591,7 @@ function resolveAiwgRoot() {
|
|
|
621124
621591
|
_cachedAiwgRoot = envRoot;
|
|
621125
621592
|
return envRoot;
|
|
621126
621593
|
}
|
|
621127
|
-
const shareDir = join132(
|
|
621594
|
+
const shareDir = join132(homedir44(), ".local", "share", "ai-writing-guide");
|
|
621128
621595
|
if (existsSync119(join132(shareDir, "agentic"))) {
|
|
621129
621596
|
_cachedAiwgRoot = shareDir;
|
|
621130
621597
|
return shareDir;
|
|
@@ -621153,8 +621620,8 @@ function resolveAiwgRoot() {
|
|
|
621153
621620
|
}
|
|
621154
621621
|
}
|
|
621155
621622
|
const versionDirs = [
|
|
621156
|
-
join132(
|
|
621157
|
-
join132(
|
|
621623
|
+
join132(homedir44(), ".nvm", "versions", "node"),
|
|
621624
|
+
join132(homedir44(), ".local", "share", "fnm", "node-versions")
|
|
621158
621625
|
];
|
|
621159
621626
|
for (const vdir of versionDirs) {
|
|
621160
621627
|
if (!existsSync119(vdir)) continue;
|
|
@@ -621902,10 +622369,10 @@ __export(runtime_keys_exports, {
|
|
|
621902
622369
|
});
|
|
621903
622370
|
import { existsSync as existsSync120, readFileSync as readFileSync98, writeFileSync as writeFileSync63, mkdirSync as mkdirSync71, chmodSync as chmodSync2 } from "node:fs";
|
|
621904
622371
|
import { join as join133 } from "node:path";
|
|
621905
|
-
import { homedir as
|
|
622372
|
+
import { homedir as homedir45 } from "node:os";
|
|
621906
622373
|
import { randomBytes as randomBytes23 } from "node:crypto";
|
|
621907
622374
|
function ensureDir2() {
|
|
621908
|
-
const dir = join133(
|
|
622375
|
+
const dir = join133(homedir45(), ".omnius");
|
|
621909
622376
|
if (!existsSync120(dir)) mkdirSync71(dir, { recursive: true });
|
|
621910
622377
|
}
|
|
621911
622378
|
function loadAll() {
|
|
@@ -621986,7 +622453,7 @@ var KEYS_FILE;
|
|
|
621986
622453
|
var init_runtime_keys = __esm({
|
|
621987
622454
|
"packages/cli/src/api/runtime-keys.ts"() {
|
|
621988
622455
|
"use strict";
|
|
621989
|
-
KEYS_FILE = join133(
|
|
622456
|
+
KEYS_FILE = join133(homedir45(), ".omnius", "keys.json");
|
|
621990
622457
|
}
|
|
621991
622458
|
});
|
|
621992
622459
|
|
|
@@ -621998,13 +622465,13 @@ __export(tor_fallback_exports, {
|
|
|
621998
622465
|
tunnelViaTor: () => tunnelViaTor
|
|
621999
622466
|
});
|
|
622000
622467
|
import { existsSync as existsSync121, readFileSync as readFileSync99 } from "node:fs";
|
|
622001
|
-
import { homedir as
|
|
622468
|
+
import { homedir as homedir46 } from "node:os";
|
|
622002
622469
|
import { join as join134 } from "node:path";
|
|
622003
622470
|
import { createConnection as createConnection3 } from "node:net";
|
|
622004
622471
|
function getLocalOnion() {
|
|
622005
622472
|
const candidates = [
|
|
622006
|
-
join134(
|
|
622007
|
-
join134(
|
|
622473
|
+
join134(homedir46(), "hidden_service_hostname"),
|
|
622474
|
+
join134(homedir46(), ".omnius", "tor", "hostname"),
|
|
622008
622475
|
"/var/lib/tor/hidden_service/hostname"
|
|
622009
622476
|
];
|
|
622010
622477
|
for (const p2 of candidates) {
|
|
@@ -622273,7 +622740,7 @@ var init_graphical_sudo = __esm({
|
|
|
622273
622740
|
// packages/cli/src/api/routes-v1.ts
|
|
622274
622741
|
import { existsSync as existsSync123, readFileSync as readFileSync100, readdirSync as readdirSync43, statSync as statSync43 } from "node:fs";
|
|
622275
622742
|
import { join as join136, resolve as pathResolve2 } from "node:path";
|
|
622276
|
-
import { homedir as
|
|
622743
|
+
import { homedir as homedir47 } from "node:os";
|
|
622277
622744
|
async function tryRouteV1(ctx3) {
|
|
622278
622745
|
const { pathname, method } = ctx3;
|
|
622279
622746
|
if (pathname === "/v1/skills" && method === "GET") {
|
|
@@ -622508,7 +622975,7 @@ async function handleGetSkill(ctx3, name10) {
|
|
|
622508
622975
|
async function fallbackDiscoverSkills() {
|
|
622509
622976
|
return (_root) => {
|
|
622510
622977
|
const roots = [
|
|
622511
|
-
join136(
|
|
622978
|
+
join136(homedir47(), ".local", "share", "ai-writing-guide")
|
|
622512
622979
|
];
|
|
622513
622980
|
const out = [];
|
|
622514
622981
|
for (const root of roots) {
|
|
@@ -623243,7 +623710,7 @@ async function handleNexusStatus(ctx3) {
|
|
|
623243
623710
|
try {
|
|
623244
623711
|
const statePaths = [
|
|
623245
623712
|
join136(process.cwd(), ".omnius", "nexus-peer-state.json"),
|
|
623246
|
-
join136(
|
|
623713
|
+
join136(homedir47(), ".omnius", "nexus-peer-cache.json")
|
|
623247
623714
|
];
|
|
623248
623715
|
const states = [];
|
|
623249
623716
|
for (const p2 of statePaths) {
|
|
@@ -623276,7 +623743,7 @@ async function handleNexusStatus(ctx3) {
|
|
|
623276
623743
|
}
|
|
623277
623744
|
function loadAgentName() {
|
|
623278
623745
|
try {
|
|
623279
|
-
const p2 = join136(
|
|
623746
|
+
const p2 = join136(homedir47(), ".omnius", "agent-name");
|
|
623280
623747
|
if (existsSync123(p2)) return readFileSync100(p2, "utf-8").trim();
|
|
623281
623748
|
} catch {
|
|
623282
623749
|
}
|
|
@@ -623286,8 +623753,8 @@ async function handleSponsors(ctx3) {
|
|
|
623286
623753
|
const { req: req2, res, url, requestId } = ctx3;
|
|
623287
623754
|
try {
|
|
623288
623755
|
const candidates = [
|
|
623289
|
-
join136(
|
|
623290
|
-
join136(
|
|
623756
|
+
join136(homedir47(), ".omnius", "sponsor-cache.json"),
|
|
623757
|
+
join136(homedir47(), ".omnius", "sponsors.json")
|
|
623291
623758
|
];
|
|
623292
623759
|
let sponsors = [];
|
|
623293
623760
|
for (const p2 of candidates) {
|
|
@@ -623544,9 +624011,9 @@ function resolveLocalPeerId() {
|
|
|
623544
624011
|
const projectScoped = scope === "project" || scope === "local" || projectScopeFlag === "1" || projectScopeFlag === "true" || projectScopeFlag === "yes";
|
|
623545
624012
|
const candidates = projectScoped ? [
|
|
623546
624013
|
join136(process.cwd(), ".omnius", "nexus", "status.json"),
|
|
623547
|
-
join136(
|
|
624014
|
+
join136(homedir47(), ".omnius", "nexus", "status.json")
|
|
623548
624015
|
] : [
|
|
623549
|
-
join136(
|
|
624016
|
+
join136(homedir47(), ".omnius", "nexus", "status.json"),
|
|
623550
624017
|
join136(process.cwd(), ".omnius", "nexus", "status.json")
|
|
623551
624018
|
];
|
|
623552
624019
|
for (const p2 of candidates) {
|
|
@@ -623554,7 +624021,7 @@ function resolveLocalPeerId() {
|
|
|
623554
624021
|
if (r2) return r2;
|
|
623555
624022
|
}
|
|
623556
624023
|
try {
|
|
623557
|
-
const regPath = join136(
|
|
624024
|
+
const regPath = join136(homedir47(), ".omnius", "nexus-registry.json");
|
|
623558
624025
|
if (existsSync123(regPath)) {
|
|
623559
624026
|
const reg = JSON.parse(readFileSync100(regPath, "utf-8"));
|
|
623560
624027
|
const entries = Array.isArray(reg?.dirs) ? reg.dirs : [];
|
|
@@ -623575,7 +624042,7 @@ function resolveLocalPeerId() {
|
|
|
623575
624042
|
let scanResult = null;
|
|
623576
624043
|
try {
|
|
623577
624044
|
const { execSync: execSync60 } = __require("node:child_process");
|
|
623578
|
-
const cmd = `find "${
|
|
624045
|
+
const cmd = `find "${homedir47()}" -maxdepth 4 -path '*/.omnius/nexus/status.json' -type f 2>/dev/null | head -50`;
|
|
623579
624046
|
const out = execSync60(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
623580
624047
|
for (const line of out.split("\n")) {
|
|
623581
624048
|
const f2 = line.trim();
|
|
@@ -623882,9 +624349,9 @@ async function handleRemoteProxy(ctx3) {
|
|
|
623882
624349
|
const tunnelProjectScope = tunnelScope === "project" || tunnelScope === "local" || ["1", "true", "yes"].includes((process.env["OMNIUS_NEXUS_PROJECT_SCOPE"] || "").toLowerCase());
|
|
623883
624350
|
const nexusCandidates = tunnelProjectScope ? [
|
|
623884
624351
|
join136(process.cwd(), ".omnius", "nexus"),
|
|
623885
|
-
join136(
|
|
624352
|
+
join136(homedir47(), ".omnius", "nexus")
|
|
623886
624353
|
] : [
|
|
623887
|
-
join136(
|
|
624354
|
+
join136(homedir47(), ".omnius", "nexus"),
|
|
623888
624355
|
join136(process.cwd(), ".omnius", "nexus")
|
|
623889
624356
|
];
|
|
623890
624357
|
let nexusDirPath = null;
|
|
@@ -624572,7 +625039,7 @@ async function handleListAgentTypes(ctx3) {
|
|
|
624572
625039
|
}
|
|
624573
625040
|
async function handleListEngines(ctx3) {
|
|
624574
625041
|
const { res } = ctx3;
|
|
624575
|
-
const home =
|
|
625042
|
+
const home = homedir47();
|
|
624576
625043
|
sendJson(res, 200, {
|
|
624577
625044
|
engines: [
|
|
624578
625045
|
{ name: "dream", state_file: join136(process.cwd(), ".omnius", "dreams"), controllable_via: "SSE + slash commands" },
|
|
@@ -624665,7 +625132,7 @@ async function tryAimsRoute(ctx3) {
|
|
|
624665
625132
|
return false;
|
|
624666
625133
|
}
|
|
624667
625134
|
function aimsDir() {
|
|
624668
|
-
return join136(
|
|
625135
|
+
return join136(homedir47(), ".omnius", "aims");
|
|
624669
625136
|
}
|
|
624670
625137
|
function readAimsFile(name10, fallback) {
|
|
624671
625138
|
try {
|
|
@@ -625009,7 +625476,7 @@ async function handleAimsSuppliers(ctx3) {
|
|
|
625009
625476
|
}
|
|
625010
625477
|
];
|
|
625011
625478
|
const sponsorPaths = [
|
|
625012
|
-
join136(
|
|
625479
|
+
join136(homedir47(), ".omnius", "sponsor-cache.json")
|
|
625013
625480
|
];
|
|
625014
625481
|
for (const p2 of sponsorPaths) {
|
|
625015
625482
|
if (!existsSync123(p2)) continue;
|
|
@@ -634534,10 +635001,10 @@ var init_usage_tracker = __esm({
|
|
|
634534
635001
|
// packages/cli/src/api/profiles.ts
|
|
634535
635002
|
import { existsSync as existsSync125, readFileSync as readFileSync102, writeFileSync as writeFileSync66, mkdirSync as mkdirSync74, readdirSync as readdirSync44, unlinkSync as unlinkSync25 } from "node:fs";
|
|
634536
635003
|
import { join as join138 } from "node:path";
|
|
634537
|
-
import { homedir as
|
|
635004
|
+
import { homedir as homedir48 } from "node:os";
|
|
634538
635005
|
import { createCipheriv as createCipheriv5, createDecipheriv as createDecipheriv5, randomBytes as randomBytes24, scryptSync as scryptSync3 } from "node:crypto";
|
|
634539
635006
|
function globalProfileDir() {
|
|
634540
|
-
return join138(
|
|
635007
|
+
return join138(homedir48(), ".omnius", "profiles");
|
|
634541
635008
|
}
|
|
634542
635009
|
function projectProfileDir(projectDir2) {
|
|
634543
635010
|
return join138(projectDir2 || process.cwd(), ".omnius", "profiles");
|
|
@@ -634791,7 +635258,7 @@ var init_profiles = __esm({
|
|
|
634791
635258
|
import { execSync as execSync56, spawn as spawn29 } from "node:child_process";
|
|
634792
635259
|
import { existsSync as existsSync126, mkdirSync as mkdirSync75, writeFileSync as writeFileSync67 } from "node:fs";
|
|
634793
635260
|
import { join as join139, resolve as resolve46, dirname as dirname37 } from "node:path";
|
|
634794
|
-
import { homedir as
|
|
635261
|
+
import { homedir as homedir49 } from "node:os";
|
|
634795
635262
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
634796
635263
|
function getDockerDir() {
|
|
634797
635264
|
try {
|
|
@@ -634939,7 +635406,7 @@ async function ensureOmniusImage(force = false) {
|
|
|
634939
635406
|
if (existsSync126(join139(dockerDir, "Dockerfile"))) {
|
|
634940
635407
|
buildContext = dockerDir;
|
|
634941
635408
|
} else {
|
|
634942
|
-
buildContext = join139(
|
|
635409
|
+
buildContext = join139(homedir49(), ".omnius", "docker-build");
|
|
634943
635410
|
mkdirSync75(buildContext, { recursive: true });
|
|
634944
635411
|
writeDockerfiles(buildContext);
|
|
634945
635412
|
}
|
|
@@ -635271,7 +635738,7 @@ import * as https3 from "node:https";
|
|
|
635271
635738
|
import { createRequire as createRequire7 } from "node:module";
|
|
635272
635739
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
635273
635740
|
import { dirname as dirname38, join as join141, resolve as resolve47 } from "node:path";
|
|
635274
|
-
import { homedir as
|
|
635741
|
+
import { homedir as homedir50 } from "node:os";
|
|
635275
635742
|
import { spawn as spawn30, execSync as execSync57 } from "node:child_process";
|
|
635276
635743
|
import { mkdirSync as mkdirSync76, writeFileSync as writeFileSync68, readFileSync as readFileSync103, readdirSync as readdirSync45, existsSync as existsSync127, watch as fsWatch3, renameSync as renameSync9, unlinkSync as unlinkSync26 } from "node:fs";
|
|
635277
635744
|
import { randomBytes as randomBytes25, randomUUID as randomUUID16 } from "node:crypto";
|
|
@@ -635586,7 +636053,7 @@ function isOriginAllowed(origin) {
|
|
|
635586
636053
|
if (!origin) return true;
|
|
635587
636054
|
let accessMode = (process.env["OMNIUS_ACCESS"] || "").toLowerCase().trim();
|
|
635588
636055
|
try {
|
|
635589
|
-
const accessFile = join141(
|
|
636056
|
+
const accessFile = join141(homedir50(), ".omnius", "access");
|
|
635590
636057
|
if (existsSync127(accessFile)) {
|
|
635591
636058
|
const persisted = readFileSync103(accessFile, "utf8").trim().toLowerCase();
|
|
635592
636059
|
if (persisted === "any" || persisted === "lan" || persisted === "loopback") {
|
|
@@ -637825,10 +638292,10 @@ ${task}` : task;
|
|
|
637825
638292
|
});
|
|
637826
638293
|
}
|
|
637827
638294
|
function updateStateFile() {
|
|
637828
|
-
return join141(
|
|
638295
|
+
return join141(homedir50(), ".omnius", "update-state.json");
|
|
637829
638296
|
}
|
|
637830
638297
|
function updateLogPath() {
|
|
637831
|
-
return join141(
|
|
638298
|
+
return join141(homedir50(), ".omnius", "update.log");
|
|
637832
638299
|
}
|
|
637833
638300
|
function readUpdateState() {
|
|
637834
638301
|
try {
|
|
@@ -637841,7 +638308,7 @@ function readUpdateState() {
|
|
|
637841
638308
|
}
|
|
637842
638309
|
function writeUpdateState(state) {
|
|
637843
638310
|
try {
|
|
637844
|
-
const dir = join141(
|
|
638311
|
+
const dir = join141(homedir50(), ".omnius");
|
|
637845
638312
|
mkdirSync76(dir, { recursive: true });
|
|
637846
638313
|
const finalPath = updateStateFile();
|
|
637847
638314
|
const tmpPath = `${finalPath}.tmp.${process.pid}`;
|
|
@@ -637897,7 +638364,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
637897
638364
|
}
|
|
637898
638365
|
if (!npmBin) npmBin = isWin2 ? "npm.cmd" : "npm";
|
|
637899
638366
|
const pkgSpec = `omnius@${targetVersion}`;
|
|
637900
|
-
const dir = join141(
|
|
638367
|
+
const dir = join141(homedir50(), ".omnius");
|
|
637901
638368
|
fs11.mkdirSync(dir, { recursive: true });
|
|
637902
638369
|
const logFd = fs11.openSync(logPath3, "w");
|
|
637903
638370
|
const npmPrefix = dirname38(nodeDir);
|
|
@@ -641132,7 +641599,7 @@ ${steering}`;
|
|
|
641132
641599
|
function getScheduleRoots() {
|
|
641133
641600
|
const rootsEnv = process.env["OMNIUS_SCHEDULE_ROOTS"] || "";
|
|
641134
641601
|
const roots = rootsEnv.split(rootsEnv.includes(";") ? ";" : ":").filter(Boolean);
|
|
641135
|
-
const defaults3 = [process.cwd(), join141(
|
|
641602
|
+
const defaults3 = [process.cwd(), join141(homedir50(), "Documents")];
|
|
641136
641603
|
const set = /* @__PURE__ */ new Set([...defaults3, ...roots]);
|
|
641137
641604
|
return [...set];
|
|
641138
641605
|
}
|
|
@@ -641637,7 +642104,7 @@ function fixupOrMigrateScheduled(mode, dryRun) {
|
|
|
641637
642104
|
try {
|
|
641638
642105
|
if (!f2.workingDir || !f2.task) continue;
|
|
641639
642106
|
const unitBase = `omnius-${f2.id}`;
|
|
641640
|
-
const unitDir = join141(
|
|
642107
|
+
const unitDir = join141(homedir50(), ".config", "systemd", "user");
|
|
641641
642108
|
const svc = join141(unitDir, `${unitBase}.service`);
|
|
641642
642109
|
const tim = join141(unitDir, `${unitBase}.timer`);
|
|
641643
642110
|
const omniusBin = findOmniusBinary4();
|
|
@@ -641930,7 +642397,7 @@ function startApiServer(options2 = {}) {
|
|
|
641930
642397
|
}
|
|
641931
642398
|
let runtimeAccessMode = resolveAccessMode(process.env["OMNIUS_ACCESS"], host);
|
|
641932
642399
|
try {
|
|
641933
|
-
const accessFile = join141(
|
|
642400
|
+
const accessFile = join141(homedir50(), ".omnius", "access");
|
|
641934
642401
|
if (existsSync127(accessFile)) {
|
|
641935
642402
|
const persisted = readFileSync103(accessFile, "utf8").trim();
|
|
641936
642403
|
const resolved = resolveAccessMode(persisted, host);
|
|
@@ -641992,7 +642459,7 @@ function startApiServer(options2 = {}) {
|
|
|
641992
642459
|
const previous = runtimeAccessMode;
|
|
641993
642460
|
runtimeAccessMode = requested;
|
|
641994
642461
|
try {
|
|
641995
|
-
const dir = join141(
|
|
642462
|
+
const dir = join141(homedir50(), ".omnius");
|
|
641996
642463
|
mkdirSync76(dir, { recursive: true });
|
|
641997
642464
|
writeFileSync68(join141(dir, "access"), `${runtimeAccessMode}
|
|
641998
642465
|
`, "utf8");
|
|
@@ -643062,7 +643529,7 @@ import {
|
|
|
643062
643529
|
} from "node:fs";
|
|
643063
643530
|
import { existsSync as existsSync128 } from "node:fs";
|
|
643064
643531
|
import { execSync as execSync59 } from "node:child_process";
|
|
643065
|
-
import { homedir as
|
|
643532
|
+
import { homedir as homedir51 } from "node:os";
|
|
643066
643533
|
function formatTimeAgo2(date) {
|
|
643067
643534
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
643068
643535
|
if (seconds < 60) return "just now";
|
|
@@ -644195,7 +644662,7 @@ function extractGeneratedAudioPath(output, repoRoot) {
|
|
|
644195
644662
|
const match = output.match(/(?:Sound|Music|TTS) generated:\s+([^\n\r]+)/i);
|
|
644196
644663
|
const raw = match?.[1]?.trim().replace(/^["']|["']$/g, "");
|
|
644197
644664
|
if (!raw) return null;
|
|
644198
|
-
return raw.startsWith("/") || raw.startsWith("~") ? raw.replace(/^~(?=\/)/,
|
|
644665
|
+
return raw.startsWith("/") || raw.startsWith("~") ? raw.replace(/^~(?=\/)/, homedir51()) : join143(repoRoot, raw);
|
|
644199
644666
|
}
|
|
644200
644667
|
async function playGeneratedAudioForToolResult(toolName, output, repoRoot, writer) {
|
|
644201
644668
|
if (!toolName || !["generate_audio", "generate_tts", "audio_playback"].includes(toolName) || !output) return;
|
|
@@ -644249,7 +644716,7 @@ async function runSelfImprovementCycle(repoRoot) {
|
|
|
644249
644716
|
} catch {
|
|
644250
644717
|
}
|
|
644251
644718
|
}
|
|
644252
|
-
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction, emotionEngine, flowEnabled, slashCommandHandler, thinkingEnabled, askUserCallback, selfModifyEnabled) {
|
|
644719
|
+
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction, emotionEngine, flowEnabled, slashCommandHandler, thinkingEnabled, askUserCallback, selfModifyEnabled, sessionMetrics) {
|
|
644253
644720
|
const voiceStyleMap = {
|
|
644254
644721
|
concise: 1,
|
|
644255
644722
|
balanced: 3,
|
|
@@ -644271,6 +644738,9 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
644271
644738
|
}
|
|
644272
644739
|
const modelTier = getModelTier(config.model);
|
|
644273
644740
|
const sessionId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
644741
|
+
const taskMetricDescription = cleanForStorage(task).replace(/\s+/g, " ").slice(0, 160) || "task";
|
|
644742
|
+
costTracker?.startTask(taskMetricDescription);
|
|
644743
|
+
sessionMetrics?.startTask(taskMetricDescription);
|
|
644274
644744
|
const projectCtx = buildProjectContext(repoRoot, taskStores?.contextStores);
|
|
644275
644745
|
let dynamicContext = formatContextForPrompt(projectCtx, modelTier);
|
|
644276
644746
|
try {
|
|
@@ -645230,6 +645700,7 @@ ${entry.fullContent}`
|
|
|
645230
645700
|
let lastToolCall = null;
|
|
645231
645701
|
let toolCallStartMs = 0;
|
|
645232
645702
|
let streamStartMs = 0;
|
|
645703
|
+
let lastStreamDurationMs = 0;
|
|
645233
645704
|
let streamTextBuffer = "";
|
|
645234
645705
|
let lastAssistantText = "";
|
|
645235
645706
|
let lastProvenancePath = null;
|
|
@@ -645291,6 +645762,9 @@ ${entry.fullContent}`
|
|
|
645291
645762
|
case "tool_call":
|
|
645292
645763
|
if (_apiCallbacks?.onToolCall)
|
|
645293
645764
|
_apiCallbacks.onToolCall(event.toolName ?? "unknown", event.toolArgs);
|
|
645765
|
+
if (event.toolName && event.toolName !== "task_complete") {
|
|
645766
|
+
sessionMetrics?.recordToolCall(event.toolName);
|
|
645767
|
+
}
|
|
645294
645768
|
toolSequence.push({
|
|
645295
645769
|
tool: event.toolName ?? "unknown",
|
|
645296
645770
|
argKeys: Object.keys(event.toolArgs ?? {})
|
|
@@ -645312,6 +645786,7 @@ ${entry.fullContent}`
|
|
|
645312
645786
|
const name10 = event.toolName ?? "";
|
|
645313
645787
|
if (name10 === "file_write" || name10 === "file_edit" || name10 === "file_patch" || name10 === "batch_edit") {
|
|
645314
645788
|
filesTouched.add(event.toolArgs.path);
|
|
645789
|
+
sessionMetrics?.recordFileModified(event.toolArgs.path);
|
|
645315
645790
|
if (isNeovimActive()) {
|
|
645316
645791
|
notifyNeovimFileChange(event.toolArgs.path).catch(
|
|
645317
645792
|
() => {
|
|
@@ -645540,6 +646015,7 @@ ${entry.fullContent}`
|
|
|
645540
646015
|
break;
|
|
645541
646016
|
case "stream_end": {
|
|
645542
646017
|
const streamDurationMs = streamStartMs > 0 ? Date.now() - streamStartMs : 0;
|
|
646018
|
+
lastStreamDurationMs = streamDurationMs;
|
|
645543
646019
|
streamStartMs = 0;
|
|
645544
646020
|
if (isNeovimActive()) {
|
|
645545
646021
|
writeToNeovimOutput("\r\n");
|
|
@@ -645618,17 +646094,28 @@ ${entry.fullContent}`
|
|
|
645618
646094
|
}
|
|
645619
646095
|
break;
|
|
645620
646096
|
case "token_usage":
|
|
645621
|
-
if (
|
|
646097
|
+
if (event.tokenUsage) {
|
|
646098
|
+
sessionMetrics?.recordTurn();
|
|
645622
646099
|
const lastPromptTokens = event.tokenUsage.lastPromptTokens ?? event.tokenUsage.promptTokens;
|
|
645623
646100
|
const lastCompletionTokens = event.tokenUsage.lastCompletionTokens ?? event.tokenUsage.completionTokens;
|
|
646101
|
+
if (lastPromptTokens > 0 || lastCompletionTokens > 0) {
|
|
646102
|
+
sessionMetrics?.recordTokenUsage(lastPromptTokens, lastCompletionTokens);
|
|
646103
|
+
}
|
|
646104
|
+
sessionMetrics?.recordContextEstimate(event.tokenUsage.estimatedContextTokens);
|
|
646105
|
+
if (lastCompletionTokens > 0 && lastStreamDurationMs > 0) {
|
|
646106
|
+
sessionMetrics?.recordGeneration(lastCompletionTokens, lastStreamDurationMs);
|
|
646107
|
+
lastStreamDurationMs = 0;
|
|
646108
|
+
}
|
|
645624
646109
|
if (costTracker && (lastPromptTokens > 0 || lastCompletionTokens > 0)) {
|
|
645625
646110
|
costTracker.trackTokens(lastPromptTokens, lastCompletionTokens);
|
|
645626
646111
|
}
|
|
645627
|
-
statusBar
|
|
645628
|
-
|
|
645629
|
-
|
|
645630
|
-
|
|
645631
|
-
|
|
646112
|
+
if (statusBar) {
|
|
646113
|
+
statusBar.updateMetrics({
|
|
646114
|
+
...event.tokenUsage,
|
|
646115
|
+
estimatedCost: costTracker?.currentCost,
|
|
646116
|
+
hasPricing: costTracker?.hasPricing
|
|
646117
|
+
});
|
|
646118
|
+
}
|
|
645632
646119
|
if (config.verbose) {
|
|
645633
646120
|
const tu = event.tokenUsage;
|
|
645634
646121
|
const ctxPct = tu.estimatedContextTokens > 0 && statusBar ? ` (ctx: ~${tu.estimatedContextTokens.toLocaleString()} tokens)` : "";
|
|
@@ -645741,6 +646228,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
645741
646228
|
total: result.totalTokens,
|
|
645742
646229
|
estimated: result.estimatedTokens
|
|
645743
646230
|
};
|
|
646231
|
+
costTracker?.endTask();
|
|
646232
|
+
sessionMetrics?.endTask();
|
|
645744
646233
|
if (result.completed) {
|
|
645745
646234
|
statusBar?.removeRecentContentMatchingText(result.summary);
|
|
645746
646235
|
}
|
|
@@ -646224,7 +646713,9 @@ async function startInteractive(config, repoPath) {
|
|
|
646224
646713
|
} catch {
|
|
646225
646714
|
}
|
|
646226
646715
|
initOmniusDirectory(repoRoot);
|
|
646227
|
-
const
|
|
646716
|
+
const globalSettings = loadGlobalSettings();
|
|
646717
|
+
const projectSettings = loadProjectSettings(repoRoot);
|
|
646718
|
+
const savedSettings = { ...globalSettings, ...projectSettings };
|
|
646228
646719
|
try {
|
|
646229
646720
|
if (savedSettings.omniusAccess && !process.env["OMNIUS_ACCESS"]) {
|
|
646230
646721
|
process.env["OMNIUS_ACCESS"] = String(savedSettings.omniusAccess);
|
|
@@ -647385,7 +647876,7 @@ This is an independent background session started from /background.`
|
|
|
647385
647876
|
);
|
|
647386
647877
|
return [hits, line];
|
|
647387
647878
|
}
|
|
647388
|
-
const HISTORY_DIR = join143(
|
|
647879
|
+
const HISTORY_DIR = join143(homedir51(), ".omnius");
|
|
647389
647880
|
const HISTORY_FILE = join143(HISTORY_DIR, "repl-history");
|
|
647390
647881
|
const MAX_HISTORY_LINES = 500;
|
|
647391
647882
|
let savedHistory = [];
|
|
@@ -648247,6 +648738,32 @@ Log: ${nexusLogPath}`)
|
|
|
648247
648738
|
}
|
|
648248
648739
|
};
|
|
648249
648740
|
workEvaluator.setBackend(evalBackend);
|
|
648741
|
+
let activeTelegramSettingsScope = null;
|
|
648742
|
+
const nonEmptyTelegramSetting = (value2) => {
|
|
648743
|
+
const trimmed = String(value2 ?? "").trim();
|
|
648744
|
+
return trimmed ? trimmed : void 0;
|
|
648745
|
+
};
|
|
648746
|
+
const refreshResolvedSettings = () => {
|
|
648747
|
+
const merged = { ...globalSettings, ...projectSettings };
|
|
648748
|
+
for (const key of Object.keys(savedSettings)) {
|
|
648749
|
+
delete savedSettings[key];
|
|
648750
|
+
}
|
|
648751
|
+
Object.assign(savedSettings, merged);
|
|
648752
|
+
};
|
|
648753
|
+
const telegramSettingsForScope = (scope = "project") => {
|
|
648754
|
+
if (scope === "effective") {
|
|
648755
|
+
const activeScope = activeTelegramSettingsScope ?? "project";
|
|
648756
|
+
return telegramSettingsForScope(activeScope);
|
|
648757
|
+
}
|
|
648758
|
+
const source = scope === "global" ? globalSettings : projectSettings;
|
|
648759
|
+
const mode = source.telegramMode ?? savedSettings.telegramMode ?? "auto";
|
|
648760
|
+
return {
|
|
648761
|
+
key: nonEmptyTelegramSetting(source.telegramKey),
|
|
648762
|
+
admin: nonEmptyTelegramSetting(source.telegramAdmin),
|
|
648763
|
+
mode,
|
|
648764
|
+
keyScope: scope
|
|
648765
|
+
};
|
|
648766
|
+
};
|
|
648250
648767
|
const commandCtx = {
|
|
648251
648768
|
get config() {
|
|
648252
648769
|
return currentConfig;
|
|
@@ -648808,7 +649325,7 @@ The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analy
|
|
|
648808
649325
|
return blessEngine?.isActive ?? false;
|
|
648809
649326
|
},
|
|
648810
649327
|
// Telegram bridge
|
|
648811
|
-
async telegramStart(token, adminId) {
|
|
649328
|
+
async telegramStart(token, adminId, scope = "project") {
|
|
648812
649329
|
if (telegramBridge?.isActive) {
|
|
648813
649330
|
writeContent(
|
|
648814
649331
|
() => renderWarning("Telegram bridge already active. Use /telegram stop before restarting.")
|
|
@@ -648848,6 +649365,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
648848
649365
|
currentConfig,
|
|
648849
649366
|
repoRoot
|
|
648850
649367
|
);
|
|
649368
|
+
activeTelegramSettingsScope = scope;
|
|
648851
649369
|
if (resolvedContextWindowSize > 0) {
|
|
648852
649370
|
telegramBridge.setContextWindowSize(resolvedContextWindowSize);
|
|
648853
649371
|
}
|
|
@@ -648857,10 +649375,16 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
648857
649375
|
telegramBridge.setAdmin(adminId);
|
|
648858
649376
|
}
|
|
648859
649377
|
telegramBridge.setAdminAuthHandler((newAdminId, username) => {
|
|
648860
|
-
|
|
648861
|
-
|
|
649378
|
+
if (activeTelegramSettingsScope === "global") {
|
|
649379
|
+
globalSettings.telegramAdmin = newAdminId;
|
|
649380
|
+
saveGlobalSettings({ telegramAdmin: newAdminId });
|
|
649381
|
+
} else {
|
|
649382
|
+
projectSettings.telegramAdmin = newAdminId;
|
|
649383
|
+
saveProjectSettings(repoRoot, { telegramAdmin: newAdminId });
|
|
649384
|
+
}
|
|
649385
|
+
refreshResolvedSettings();
|
|
648862
649386
|
writeContent(
|
|
648863
|
-
() => renderInfo(`Telegram admin authenticated: @${username || "unknown"} (${newAdminId})`)
|
|
649387
|
+
() => renderInfo(`Telegram admin authenticated: @${username || "unknown"} (${newAdminId}) in ${activeTelegramSettingsScope ?? "project"} settings`)
|
|
648864
649388
|
);
|
|
648865
649389
|
});
|
|
648866
649390
|
telegramBridge.setWriteContent(writeContent);
|
|
@@ -648917,6 +649441,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
648917
649441
|
});
|
|
648918
649442
|
});
|
|
648919
649443
|
}
|
|
649444
|
+
} else {
|
|
649445
|
+
emotionEngine.setAdminOutreach(() => {
|
|
649446
|
+
});
|
|
648920
649447
|
}
|
|
648921
649448
|
if (voiceEngine.enabled && voiceEngine.ready) {
|
|
648922
649449
|
telegramBridge.setVoiceEngine(voiceEngine);
|
|
@@ -648957,9 +649484,16 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
648957
649484
|
throw err;
|
|
648958
649485
|
}
|
|
648959
649486
|
});
|
|
648960
|
-
|
|
649487
|
+
try {
|
|
649488
|
+
await telegramBridge.start();
|
|
649489
|
+
} catch (err) {
|
|
649490
|
+
telegramBridge.stop();
|
|
649491
|
+
telegramBridge = null;
|
|
649492
|
+
activeTelegramSettingsScope = null;
|
|
649493
|
+
throw err;
|
|
649494
|
+
}
|
|
648961
649495
|
statusBar.setTelegramStatus(true, telegramBridge.stats.activeSubAgents);
|
|
648962
|
-
telegramBridge.
|
|
649496
|
+
telegramBridge.registerScopedMyCommands(adminId).catch((err) => {
|
|
648963
649497
|
writeContent(
|
|
648964
649498
|
() => renderWarning(`Telegram command registration failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
648965
649499
|
);
|
|
@@ -648975,41 +649509,56 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
648975
649509
|
telegramBridge.stop();
|
|
648976
649510
|
writeContent(() => renderTelegramStop(stats));
|
|
648977
649511
|
telegramBridge = null;
|
|
649512
|
+
activeTelegramSettingsScope = null;
|
|
648978
649513
|
statusBar.setTelegramStatus(false, 0);
|
|
648979
649514
|
}
|
|
648980
649515
|
},
|
|
648981
649516
|
isTelegramActive() {
|
|
648982
649517
|
return telegramBridge?.isActive ?? false;
|
|
648983
649518
|
},
|
|
648984
|
-
getTelegramSettings() {
|
|
648985
|
-
return
|
|
648986
|
-
key: savedSettings.telegramKey,
|
|
648987
|
-
admin: savedSettings.telegramAdmin,
|
|
648988
|
-
mode: savedSettings.telegramMode
|
|
648989
|
-
};
|
|
649519
|
+
getTelegramSettings(scope = "project") {
|
|
649520
|
+
return telegramSettingsForScope(scope);
|
|
648990
649521
|
},
|
|
648991
649522
|
saveTelegramSettings(settings) {
|
|
649523
|
+
const targetScope = settings.local === false ? "global" : "project";
|
|
649524
|
+
const target = targetScope === "global" ? globalSettings : projectSettings;
|
|
648992
649525
|
if (settings.key !== void 0) {
|
|
648993
|
-
|
|
649526
|
+
target.telegramKey = settings.key;
|
|
648994
649527
|
}
|
|
648995
649528
|
if (settings.admin !== void 0) {
|
|
648996
|
-
|
|
649529
|
+
target.telegramAdmin = settings.admin === null ? "" : settings.admin;
|
|
648997
649530
|
}
|
|
648998
649531
|
if (settings.mode !== void 0) {
|
|
648999
|
-
|
|
649532
|
+
target.telegramMode = settings.mode;
|
|
649000
649533
|
}
|
|
649001
649534
|
const payload = {
|
|
649002
649535
|
...settings.key !== void 0 ? { telegramKey: settings.key } : {},
|
|
649003
|
-
...settings.admin !== void 0 ? { telegramAdmin: settings.admin } : {},
|
|
649536
|
+
...settings.admin !== void 0 ? { telegramAdmin: settings.admin === null ? "" : settings.admin } : {},
|
|
649004
649537
|
...settings.mode !== void 0 ? { telegramMode: settings.mode } : {}
|
|
649005
649538
|
};
|
|
649006
|
-
|
|
649007
|
-
const useProject = settings.local === true || settings.local === void 0 && projectHasOmnius;
|
|
649008
|
-
if (useProject) {
|
|
649539
|
+
if (targetScope === "project") {
|
|
649009
649540
|
saveProjectSettings(repoRoot, payload);
|
|
649010
649541
|
} else {
|
|
649011
649542
|
saveGlobalSettings(payload);
|
|
649012
649543
|
}
|
|
649544
|
+
refreshResolvedSettings();
|
|
649545
|
+
},
|
|
649546
|
+
telegramRevokeAdmin(scope) {
|
|
649547
|
+
const target = scope === "global" ? globalSettings : projectSettings;
|
|
649548
|
+
const previousAdmin = nonEmptyTelegramSetting(target.telegramAdmin) ?? null;
|
|
649549
|
+
target.telegramAdmin = "";
|
|
649550
|
+
if (scope === "global") {
|
|
649551
|
+
saveGlobalSettings({ telegramAdmin: "" });
|
|
649552
|
+
} else {
|
|
649553
|
+
saveProjectSettings(repoRoot, { telegramAdmin: "" });
|
|
649554
|
+
}
|
|
649555
|
+
refreshResolvedSettings();
|
|
649556
|
+
if (telegramBridge?.isActive && (activeTelegramSettingsScope ?? "project") === scope) {
|
|
649557
|
+
telegramBridge.setAdmin(null);
|
|
649558
|
+
emotionEngine.setAdminOutreach(() => {
|
|
649559
|
+
});
|
|
649560
|
+
}
|
|
649561
|
+
return { previousAdmin, scope };
|
|
649013
649562
|
},
|
|
649014
649563
|
telegramSetInteractionMode(mode) {
|
|
649015
649564
|
savedSettings.telegramMode = mode;
|
|
@@ -649023,7 +649572,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
649023
649572
|
() => renderTelegramStatus(
|
|
649024
649573
|
active,
|
|
649025
649574
|
botUser,
|
|
649026
|
-
|
|
649575
|
+
telegramSettingsForScope(activeTelegramSettingsScope ?? "project").admin,
|
|
649027
649576
|
subAgents,
|
|
649028
649577
|
savedSettings.telegramMode ?? "auto"
|
|
649029
649578
|
)
|
|
@@ -649108,7 +649657,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
649108
649657
|
const registry4 = createOmniusPlatformRegistry({
|
|
649109
649658
|
telegram: () => ({
|
|
649110
649659
|
active: telegramBridge?.isActive ?? false,
|
|
649111
|
-
configured: !!
|
|
649660
|
+
configured: !!telegramSettingsForScope("project").key,
|
|
649112
649661
|
enabled: telegramBridge?.isActive ?? false,
|
|
649113
649662
|
botUsername: telegramBridge?.botUsername,
|
|
649114
649663
|
activeSessions: telegramBridge?.stats.activeSubAgents ?? 0
|
|
@@ -649952,6 +650501,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
649952
650501
|
statusBar.setContextWindowSize(size);
|
|
649953
650502
|
telegramBridge?.setContextWindowSize(size);
|
|
649954
650503
|
},
|
|
650504
|
+
getContextWindowSize: () => resolvedContextWindowSize,
|
|
649955
650505
|
setCapabilities: (caps) => {
|
|
649956
650506
|
resolvedCaps = caps;
|
|
649957
650507
|
statusBar.setCapabilities(caps);
|
|
@@ -650070,7 +650620,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
650070
650620
|
} catch {
|
|
650071
650621
|
}
|
|
650072
650622
|
try {
|
|
650073
|
-
const voiceDir3 = join143(
|
|
650623
|
+
const voiceDir3 = join143(homedir51(), ".omnius", "voice");
|
|
650074
650624
|
const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
|
|
650075
650625
|
for (const pf of voicePidFiles) {
|
|
650076
650626
|
const pidPath = join143(voiceDir3, pf);
|
|
@@ -650206,14 +650756,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
650206
650756
|
const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
|
|
650207
650757
|
if (isPersonaPlexRunning2()) {
|
|
650208
650758
|
const ppPidFile = join143(
|
|
650209
|
-
|
|
650759
|
+
homedir51(),
|
|
650210
650760
|
".omnius",
|
|
650211
650761
|
"voice",
|
|
650212
650762
|
"personaplex",
|
|
650213
650763
|
"daemon.pid"
|
|
650214
650764
|
);
|
|
650215
650765
|
const ppPortFile = join143(
|
|
650216
|
-
|
|
650766
|
+
homedir51(),
|
|
650217
650767
|
".omnius",
|
|
650218
650768
|
"voice",
|
|
650219
650769
|
"personaplex",
|
|
@@ -650383,12 +650933,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
650383
650933
|
}, 100);
|
|
650384
650934
|
}
|
|
650385
650935
|
}
|
|
650386
|
-
|
|
650936
|
+
const autoTelegramSettings = telegramSettingsForScope("project");
|
|
650937
|
+
if (!isResumed && autoTelegramSettings.key) {
|
|
650387
650938
|
setTimeout(async () => {
|
|
650388
650939
|
try {
|
|
650389
650940
|
await commandCtx.telegramStart(
|
|
650390
|
-
|
|
650391
|
-
|
|
650941
|
+
autoTelegramSettings.key,
|
|
650942
|
+
autoTelegramSettings.admin,
|
|
650943
|
+
"project"
|
|
650392
650944
|
);
|
|
650393
650945
|
} catch (err) {
|
|
650394
650946
|
writeContent(
|
|
@@ -650649,7 +651201,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
650649
651201
|
buildSlashCommandHandler(),
|
|
650650
651202
|
thinkingEnabled,
|
|
650651
651203
|
handleAskUser,
|
|
650652
|
-
selfModifyEnabled
|
|
651204
|
+
selfModifyEnabled,
|
|
651205
|
+
sessionMetrics
|
|
650653
651206
|
);
|
|
650654
651207
|
activeTask = task;
|
|
650655
651208
|
setTerminalTitle(input.slice(0, 60), version4);
|
|
@@ -651077,7 +651630,8 @@ NEW TASK: ${fullInput}`;
|
|
|
651077
651630
|
buildSlashCommandHandler(),
|
|
651078
651631
|
thinkingEnabled,
|
|
651079
651632
|
handleAskUser,
|
|
651080
|
-
selfModifyEnabled
|
|
651633
|
+
selfModifyEnabled,
|
|
651634
|
+
sessionMetrics
|
|
651081
651635
|
);
|
|
651082
651636
|
activeTask = task;
|
|
651083
651637
|
_recallText = null;
|
|
@@ -652381,7 +652935,7 @@ __export(config_exports2, {
|
|
|
652381
652935
|
configCommand: () => configCommand
|
|
652382
652936
|
});
|
|
652383
652937
|
import { join as join145, resolve as resolve51 } from "node:path";
|
|
652384
|
-
import { homedir as
|
|
652938
|
+
import { homedir as homedir52 } from "node:os";
|
|
652385
652939
|
import { cwd as cwd3 } from "node:process";
|
|
652386
652940
|
function redactIfSensitive(key, value2) {
|
|
652387
652941
|
if (SENSITIVE_KEYS.has(key) && typeof value2 === "string" && value2.length > 0) {
|
|
@@ -652463,7 +653017,7 @@ function handleShow(opts, config) {
|
|
|
652463
653017
|
}
|
|
652464
653018
|
}
|
|
652465
653019
|
printSection("Config File");
|
|
652466
|
-
printInfo(`~/.omnius/config.json (${join145(
|
|
653020
|
+
printInfo(`~/.omnius/config.json (${join145(homedir52(), ".omnius", "config.json")})`);
|
|
652467
653021
|
printSection("Priority Chain");
|
|
652468
653022
|
printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
|
|
652469
653023
|
printInfo(" 2. Project .omnius/settings.json (--local)");
|
|
@@ -653340,8 +653894,8 @@ function crashLog(label, err) {
|
|
|
653340
653894
|
try {
|
|
653341
653895
|
const { appendFileSync: appendFileSync12, mkdirSync: mkdirSync81 } = __require("node:fs");
|
|
653342
653896
|
const { join: join148 } = __require("node:path");
|
|
653343
|
-
const { homedir:
|
|
653344
|
-
const logDir = join148(
|
|
653897
|
+
const { homedir: homedir53 } = __require("node:os");
|
|
653898
|
+
const logDir = join148(homedir53(), ".omnius");
|
|
653345
653899
|
mkdirSync81(logDir, { recursive: true });
|
|
653346
653900
|
appendFileSync12(join148(logDir, "crash.log"), logLine);
|
|
653347
653901
|
} catch {
|