omnius 1.0.3 → 1.0.5
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 +406 -136
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7852,7 +7852,6 @@ var init_nexus = __esm({
|
|
|
7852
7852
|
* Usage: node nexus-daemon.mjs <nexus-dir> <agent-name> [agent-type]
|
|
7853
7853
|
*/
|
|
7854
7854
|
|
|
7855
|
-
import { NexusClient } from 'open-agents-nexus';
|
|
7856
7855
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, readdirSync, appendFileSync, watch as fsWatch } from 'node:fs';
|
|
7857
7856
|
import { join } from 'node:path';
|
|
7858
7857
|
import { homedir, hostname } from 'node:os';
|
|
@@ -7930,6 +7929,40 @@ const globalKeyDir = join(homedir(), '.omnius');
|
|
|
7930
7929
|
const globalKeyPath = join(globalKeyDir, 'identity.key');
|
|
7931
7930
|
const projectKeyPath = join(nexusDir, 'identity.key');
|
|
7932
7931
|
const keyPath = existsSync(globalKeyPath) ? globalKeyPath : projectKeyPath;
|
|
7932
|
+
|
|
7933
|
+
function formatStartupError(err) {
|
|
7934
|
+
if (!err) return 'Unknown startup error';
|
|
7935
|
+
var msg = err && err.stack ? String(err.stack) : String(err && err.message ? err.message : err);
|
|
7936
|
+
return msg.replace(/\\x1B\\[[0-?]*[ -/]*[@-~]/g, '').slice(0, 4000);
|
|
7937
|
+
}
|
|
7938
|
+
|
|
7939
|
+
async function loadNexusClientClass() {
|
|
7940
|
+
try {
|
|
7941
|
+
var mod = await import('open-agents-nexus');
|
|
7942
|
+
if (!mod || !mod.NexusClient) throw new Error('open-agents-nexus did not export NexusClient');
|
|
7943
|
+
return mod.NexusClient;
|
|
7944
|
+
} catch (err) {
|
|
7945
|
+
var msg = 'Failed to load open-agents-nexus: ' + formatStartupError(err);
|
|
7946
|
+
try { appendFileSync(join(nexusDir, 'daemon.err'), 'Nexus daemon dependency load failed: ' + msg + '\\n'); } catch {}
|
|
7947
|
+
try {
|
|
7948
|
+
writeFileSync(statusFile, JSON.stringify({
|
|
7949
|
+
pid: process.pid,
|
|
7950
|
+
connected: false,
|
|
7951
|
+
peerId: null,
|
|
7952
|
+
agentName: agentName,
|
|
7953
|
+
agentType: agentType,
|
|
7954
|
+
rooms: [],
|
|
7955
|
+
capabilities: [],
|
|
7956
|
+
blockedPeers: [],
|
|
7957
|
+
connectedAt: null,
|
|
7958
|
+
error: msg,
|
|
7959
|
+
}, null, 2));
|
|
7960
|
+
} catch {}
|
|
7961
|
+
process.exit(1);
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
|
|
7965
|
+
const NexusClient = await loadNexusClientClass();
|
|
7933
7966
|
var nexusOpts = {
|
|
7934
7967
|
keyStorePath: keyPath,
|
|
7935
7968
|
agentName,
|
|
@@ -13188,6 +13221,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13188
13221
|
res((stdout || "").trim());
|
|
13189
13222
|
});
|
|
13190
13223
|
});
|
|
13224
|
+
const isNativeDataChannelError = (text) => /node-datachannel|node_datachannel\.node|datachannel\/dist/i.test(text);
|
|
13225
|
+
const tryRepairNodeDataChannel = async () => {
|
|
13226
|
+
const cmds = existsSync17(join21(this.repoRoot, "pnpm-lock.yaml")) ? ["pnpm rebuild node-datachannel 2>&1", "npm rebuild node-datachannel 2>&1"] : ["npm rebuild node-datachannel 2>&1", "pnpm rebuild node-datachannel 2>&1"];
|
|
13227
|
+
const failures = [];
|
|
13228
|
+
for (const cmd of cmds) {
|
|
13229
|
+
try {
|
|
13230
|
+
await execAsync3(cmd, { cwd: this.repoRoot, timeout: 18e4 });
|
|
13231
|
+
return `Repaired node-datachannel native addon with: ${cmd.replace(" 2>&1", "")}`;
|
|
13232
|
+
} catch (err) {
|
|
13233
|
+
failures.push(`${cmd.replace(" 2>&1", "")}: ${err?.message ?? String(err)}`.slice(0, 500));
|
|
13234
|
+
}
|
|
13235
|
+
}
|
|
13236
|
+
return `node-datachannel native addon repair failed:
|
|
13237
|
+
${failures.join("\n")}`;
|
|
13238
|
+
};
|
|
13191
13239
|
try {
|
|
13192
13240
|
const nexusPkg = join21(nodeModulesDir, "open-agents-nexus", "package.json");
|
|
13193
13241
|
if (existsSync17(nexusPkg)) {
|
|
@@ -13294,7 +13342,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13294
13342
|
errTail = (await readFile9(daemonErrPath, "utf8")).slice(-300);
|
|
13295
13343
|
} catch {
|
|
13296
13344
|
}
|
|
13297
|
-
|
|
13345
|
+
const statusError = String(status.error ?? "");
|
|
13346
|
+
if (!args.__native_repair_attempted && isNativeDataChannelError(`${statusError}
|
|
13347
|
+
${errTail}`)) {
|
|
13348
|
+
const repair = await tryRepairNodeDataChannel();
|
|
13349
|
+
if (/^Repaired /.test(repair)) {
|
|
13350
|
+
return this.doConnect({ ...args, __native_repair_attempted: true });
|
|
13351
|
+
}
|
|
13352
|
+
return `Nexus daemon failed to connect: ${statusError}
|
|
13353
|
+
${repair}${errTail ? "\n" + errTail : ""}`;
|
|
13354
|
+
}
|
|
13355
|
+
return `Nexus daemon failed to connect: ${statusError}${errTail ? "\n" + errTail : ""}`;
|
|
13298
13356
|
}
|
|
13299
13357
|
if (status.connected && status.peerId) {
|
|
13300
13358
|
return [
|
|
@@ -13320,6 +13378,17 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
13320
13378
|
try {
|
|
13321
13379
|
earlyOutput = (await readFile9(daemonLogPath, "utf8")).slice(-500);
|
|
13322
13380
|
} catch {
|
|
13381
|
+
}
|
|
13382
|
+
const earlyCombined = `${earlyError}
|
|
13383
|
+
${earlyOutput}`;
|
|
13384
|
+
if (!args.__native_repair_attempted && isNativeDataChannelError(earlyCombined)) {
|
|
13385
|
+
const repair = await tryRepairNodeDataChannel();
|
|
13386
|
+
if (/^Repaired /.test(repair)) {
|
|
13387
|
+
return this.doConnect({ ...args, __native_repair_attempted: true });
|
|
13388
|
+
}
|
|
13389
|
+
return `Daemon failed to start.
|
|
13390
|
+
${repair}
|
|
13391
|
+
${earlyError ? "\n" + earlyError : ""}${earlyOutput ? "\n" + earlyOutput : ""}`;
|
|
13323
13392
|
}
|
|
13324
13393
|
if (pid) {
|
|
13325
13394
|
return `Daemon spawned (pid: ${pid}) but still connecting. Check status in a moment.${earlyError ? "\nStderr: " + earlyError.slice(0, 200) : ""}`;
|
|
@@ -526480,6 +526549,14 @@ var init_app_state = __esm({
|
|
|
526480
526549
|
});
|
|
526481
526550
|
|
|
526482
526551
|
// packages/orchestrator/dist/streaming-executor.js
|
|
526552
|
+
function stableValueKey(value2) {
|
|
526553
|
+
if (value2 === null || typeof value2 !== "object")
|
|
526554
|
+
return JSON.stringify(value2);
|
|
526555
|
+
if (Array.isArray(value2))
|
|
526556
|
+
return `[${value2.map(stableValueKey).join(",")}]`;
|
|
526557
|
+
const record = value2;
|
|
526558
|
+
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableValueKey(record[key])}`).join(",")}}`;
|
|
526559
|
+
}
|
|
526483
526560
|
var StreamingToolExecutor;
|
|
526484
526561
|
var init_streaming_executor = __esm({
|
|
526485
526562
|
"packages/orchestrator/dist/streaming-executor.js"() {
|
|
@@ -526631,6 +526708,62 @@ var init_streaming_executor = __esm({
|
|
|
526631
526708
|
return true;
|
|
526632
526709
|
return false;
|
|
526633
526710
|
}
|
|
526711
|
+
entryFingerprint(entry) {
|
|
526712
|
+
return `${entry.name}:${stableValueKey(entry.args)}`;
|
|
526713
|
+
}
|
|
526714
|
+
findPriorEquivalent(entry) {
|
|
526715
|
+
const entryIdx = this.insertionOrder.indexOf(entry.id);
|
|
526716
|
+
if (entryIdx <= 0 || !entry.finalized)
|
|
526717
|
+
return null;
|
|
526718
|
+
const fp = this.entryFingerprint(entry);
|
|
526719
|
+
for (let i2 = 0; i2 < entryIdx; i2++) {
|
|
526720
|
+
const prior = this.tools.get(this.insertionOrder[i2]);
|
|
526721
|
+
if (!prior || !prior.finalized)
|
|
526722
|
+
continue;
|
|
526723
|
+
if (this.entryFingerprint(prior) === fp)
|
|
526724
|
+
return prior;
|
|
526725
|
+
}
|
|
526726
|
+
return null;
|
|
526727
|
+
}
|
|
526728
|
+
cloneDuplicateResult(prior) {
|
|
526729
|
+
if (!prior.result)
|
|
526730
|
+
return null;
|
|
526731
|
+
const prefix = `[DUPLICATE STREAM TOOL CALL — reused result from ${prior.id}]
|
|
526732
|
+
`;
|
|
526733
|
+
return {
|
|
526734
|
+
success: prior.result.success,
|
|
526735
|
+
output: prior.result.output ? `${prefix}${prior.result.output}` : prior.result.output,
|
|
526736
|
+
error: prior.result.error
|
|
526737
|
+
};
|
|
526738
|
+
}
|
|
526739
|
+
mirrorPriorEquivalent(entry) {
|
|
526740
|
+
const prior = this.findPriorEquivalent(entry);
|
|
526741
|
+
if (!prior)
|
|
526742
|
+
return false;
|
|
526743
|
+
if ((prior.state === "completed" || prior.state === "failed" || prior.state === "yielded") && prior.result) {
|
|
526744
|
+
entry.state = prior.result.success ? "completed" : "failed";
|
|
526745
|
+
entry.result = this.cloneDuplicateResult(prior) ?? prior.result;
|
|
526746
|
+
entry.startedAt = prior.startedAt;
|
|
526747
|
+
entry.completedAt = prior.completedAt ?? Date.now();
|
|
526748
|
+
return true;
|
|
526749
|
+
}
|
|
526750
|
+
if (prior.state === "executing" && prior.promise) {
|
|
526751
|
+
entry.state = "executing";
|
|
526752
|
+
entry.startedAt = prior.startedAt ?? Date.now();
|
|
526753
|
+
entry.promise = prior.promise.then(() => {
|
|
526754
|
+
entry.result = this.cloneDuplicateResult(prior) ?? {
|
|
526755
|
+
success: false,
|
|
526756
|
+
output: "",
|
|
526757
|
+
error: "Duplicate streaming tool call could not reuse prior result"
|
|
526758
|
+
};
|
|
526759
|
+
entry.state = entry.result.success ? "completed" : "failed";
|
|
526760
|
+
entry.completedAt = Date.now();
|
|
526761
|
+
this.processQueue();
|
|
526762
|
+
});
|
|
526763
|
+
return true;
|
|
526764
|
+
}
|
|
526765
|
+
return false;
|
|
526766
|
+
}
|
|
526634
526767
|
/**
|
|
526635
526768
|
* Process the queue in insertion order.
|
|
526636
526769
|
* Starts tools that can execute, stops at first exclusive tool that must wait.
|
|
@@ -526640,6 +526773,8 @@ var init_streaming_executor = __esm({
|
|
|
526640
526773
|
const entry = this.tools.get(id);
|
|
526641
526774
|
if (!entry || entry.state !== "queued")
|
|
526642
526775
|
continue;
|
|
526776
|
+
if (this.mirrorPriorEquivalent(entry))
|
|
526777
|
+
continue;
|
|
526643
526778
|
if (this.canExecute(entry)) {
|
|
526644
526779
|
this.startExecution(entry);
|
|
526645
526780
|
} else if (!entry.concurrencySafe) {
|
|
@@ -535397,6 +535532,7 @@ ${sr.result.output}`;
|
|
|
535397
535532
|
this.emit({
|
|
535398
535533
|
type: "assistant_text",
|
|
535399
535534
|
content: summary,
|
|
535535
|
+
source: "task_complete_summary",
|
|
535400
535536
|
turn,
|
|
535401
535537
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
535402
535538
|
});
|
|
@@ -535437,6 +535573,7 @@ ${sr.result.output}`;
|
|
|
535437
535573
|
this.emit({
|
|
535438
535574
|
type: "assistant_text",
|
|
535439
535575
|
content: summary,
|
|
535576
|
+
source: "task_complete_summary",
|
|
535440
535577
|
turn,
|
|
535441
535578
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
535442
535579
|
});
|
|
@@ -535512,6 +535649,7 @@ ${sr.result.output}`;
|
|
|
535512
535649
|
this.emit({
|
|
535513
535650
|
type: "assistant_text",
|
|
535514
535651
|
content: summary,
|
|
535652
|
+
source: "task_complete_summary",
|
|
535515
535653
|
turn,
|
|
535516
535654
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
535517
535655
|
});
|
|
@@ -536237,6 +536375,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
536237
536375
|
this.emit({
|
|
536238
536376
|
type: "assistant_text",
|
|
536239
536377
|
content: summary,
|
|
536378
|
+
source: "task_complete_summary",
|
|
536240
536379
|
turn,
|
|
536241
536380
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
536242
536381
|
});
|
|
@@ -540083,6 +540222,7 @@ ${description}`
|
|
|
540083
540222
|
this.emit({
|
|
540084
540223
|
type: "assistant_text",
|
|
540085
540224
|
content: cleanContent,
|
|
540225
|
+
source: "model_visible_text",
|
|
540086
540226
|
turn,
|
|
540087
540227
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
540088
540228
|
});
|
|
@@ -549721,27 +549861,27 @@ var init_theme = __esm({
|
|
|
549721
549861
|
},
|
|
549722
549862
|
branding: {
|
|
549723
549863
|
mode: "branding",
|
|
549724
|
-
bg:
|
|
549725
|
-
//
|
|
549726
|
-
accent:
|
|
549727
|
-
//
|
|
549728
|
-
textPrimary:
|
|
549729
|
-
//
|
|
549864
|
+
bg: -1,
|
|
549865
|
+
// terminal default background
|
|
549866
|
+
accent: 37,
|
|
549867
|
+
// teal
|
|
549868
|
+
textPrimary: 37,
|
|
549869
|
+
// teal
|
|
549730
549870
|
textDim: 240,
|
|
549731
549871
|
// grey
|
|
549732
|
-
boxColor:
|
|
549733
|
-
//
|
|
549872
|
+
boxColor: 37
|
|
549873
|
+
// teal
|
|
549734
549874
|
},
|
|
549735
549875
|
custom: {
|
|
549736
549876
|
mode: "custom",
|
|
549737
|
-
bg:
|
|
549738
|
-
accent:
|
|
549877
|
+
bg: -1,
|
|
549878
|
+
accent: 37,
|
|
549739
549879
|
textPrimary: 252,
|
|
549740
549880
|
textDim: 245,
|
|
549741
549881
|
boxColor: 252
|
|
549742
549882
|
}
|
|
549743
549883
|
};
|
|
549744
|
-
_config2 = { ...PRESETS.
|
|
549884
|
+
_config2 = { ...PRESETS.system };
|
|
549745
549885
|
}
|
|
549746
549886
|
});
|
|
549747
549887
|
|
|
@@ -551291,10 +551431,10 @@ var init_render = __esm({
|
|
|
551291
551431
|
warn: (t2) => fg256(214, t2),
|
|
551292
551432
|
/** Success text — green for confirmations */
|
|
551293
551433
|
ok: (t2) => fg256(78, t2),
|
|
551294
|
-
/** Accent —
|
|
551295
|
-
accent: (t2) => fg256(
|
|
551296
|
-
/** Muted accent — dim
|
|
551297
|
-
accentDim: (t2) => fg256(
|
|
551434
|
+
/** Accent — teal matching header/banner */
|
|
551435
|
+
accent: (t2) => fg256(37, t2),
|
|
551436
|
+
/** Muted accent — dim teal for secondary accent */
|
|
551437
|
+
accentDim: (t2) => fg256(30, t2)
|
|
551298
551438
|
};
|
|
551299
551439
|
pastel = {
|
|
551300
551440
|
pink: (t2) => fg256(218, t2),
|
|
@@ -551402,11 +551542,11 @@ var init_render = __esm({
|
|
|
551402
551542
|
// User interaction
|
|
551403
551543
|
ask_user: "Ask user"
|
|
551404
551544
|
};
|
|
551405
|
-
accent = (t2) => fg256(
|
|
551406
|
-
accentBright = (t2) => fg256(
|
|
551407
|
-
accentDim = (t2) => fg256(
|
|
551408
|
-
accentWarm = (t2) => fg256(
|
|
551409
|
-
accentSoft = (t2) => fg256(
|
|
551545
|
+
accent = (t2) => fg256(37, t2);
|
|
551546
|
+
accentBright = (t2) => fg256(44, t2);
|
|
551547
|
+
accentDim = (t2) => fg256(30, t2);
|
|
551548
|
+
accentWarm = (t2) => fg256(43, t2);
|
|
551549
|
+
accentSoft = (t2) => fg256(80, t2);
|
|
551410
551550
|
TOOL_COLORS = {
|
|
551411
551551
|
file_read: accentSoft,
|
|
551412
551552
|
file_write: accentWarm,
|
|
@@ -557646,8 +557786,8 @@ var init_braille_spinner = __esm({
|
|
|
557646
557786
|
return (x * x * 31 + x * 17 + 59) % 97 / 97;
|
|
557647
557787
|
};
|
|
557648
557788
|
MOOD_RAMPS = {
|
|
557649
|
-
neutral: [237,
|
|
557650
|
-
// default
|
|
557789
|
+
neutral: [237, 24, 30, 36, 37, 43, 44, 50, 51],
|
|
557790
|
+
// default teal/cyan
|
|
557651
557791
|
success: [237, 22, 28, 34, 40, 46, 47, 48, 49],
|
|
557652
557792
|
// green pulse
|
|
557653
557793
|
error: [237, 52, 88, 124, 160, 196, 197, 203, 209],
|
|
@@ -557658,8 +557798,8 @@ var init_braille_spinner = __esm({
|
|
|
557658
557798
|
// purple contemplation
|
|
557659
557799
|
};
|
|
557660
557800
|
THEME_DEFAULT = {
|
|
557661
|
-
ramp: [237,
|
|
557662
|
-
// grey
|
|
557801
|
+
ramp: [237, 24, 30, 36, 37, 43, 44, 50, 51],
|
|
557802
|
+
// grey -> teal/cyan
|
|
557663
557803
|
speed: 2
|
|
557664
557804
|
};
|
|
557665
557805
|
THEME_FILE = {
|
|
@@ -557679,7 +557819,7 @@ var init_braille_spinner = __esm({
|
|
|
557679
557819
|
speed: 4
|
|
557680
557820
|
};
|
|
557681
557821
|
THEME_MEMORY = {
|
|
557682
|
-
ramp: [237,
|
|
557822
|
+
ramp: [237, 23, 29, 35, 36, 37, 43, 44, 50],
|
|
557683
557823
|
speed: 1
|
|
557684
557824
|
};
|
|
557685
557825
|
THEME_SKILL = {
|
|
@@ -557691,7 +557831,7 @@ var init_braille_spinner = __esm({
|
|
|
557691
557831
|
speed: 2
|
|
557692
557832
|
};
|
|
557693
557833
|
THEME_DREAM = {
|
|
557694
|
-
ramp: [237,
|
|
557834
|
+
ramp: [237, 24, 30, 36, 37, 43, 44, 50, 51],
|
|
557695
557835
|
speed: 1
|
|
557696
557836
|
};
|
|
557697
557837
|
DEFAULT_METRICS = {
|
|
@@ -558303,7 +558443,7 @@ var init_text_selection = __esm({
|
|
|
558303
558443
|
"packages/cli/src/tui/text-selection.ts"() {
|
|
558304
558444
|
"use strict";
|
|
558305
558445
|
init_layout2();
|
|
558306
|
-
SEL_BG =
|
|
558446
|
+
SEL_BG = 37;
|
|
558307
558447
|
SEL_FG = 30;
|
|
558308
558448
|
SEL_START = `\x1B[${SEL_FG}m\x1B[48;5;${SEL_BG}m`;
|
|
558309
558449
|
SEL_END = `\x1B[0m`;
|
|
@@ -559594,8 +559734,8 @@ var init_status_bar = __esm({
|
|
|
559594
559734
|
const decorateMenuButton = (cmd, label) => {
|
|
559595
559735
|
const isBranding = themeMode() === "branding";
|
|
559596
559736
|
if (isBranding) {
|
|
559597
|
-
const BRAND_BG =
|
|
559598
|
-
const BRAND_FG =
|
|
559737
|
+
const BRAND_BG = 37;
|
|
559738
|
+
const BRAND_FG = 0;
|
|
559599
559739
|
return linkify(
|
|
559600
559740
|
cmd,
|
|
559601
559741
|
`\x1B[38;5;${BRAND_FG}m\x1B[48;5;${BRAND_BG}m ${label} \x1B[0m${PANEL_BG_SEQ}`
|
|
@@ -561516,7 +561656,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
561516
561656
|
if (this._contentScrollOffset > 0) {
|
|
561517
561657
|
const label = " ↓ scroll to bottom ";
|
|
561518
561658
|
const startCol = 3;
|
|
561519
|
-
buf += `\x1B[${spacerRow};${startCol}H\x1B[
|
|
561659
|
+
buf += `\x1B[${spacerRow};${startCol}H\x1B[38;5;37m${label}\x1B[0m${CONTENT_BG_SEQ}`;
|
|
561520
561660
|
this._scrollBtnRegion = {
|
|
561521
561661
|
row: spacerRow,
|
|
561522
561662
|
start: startCol,
|
|
@@ -564239,6 +564379,23 @@ import { promisify as promisify5 } from "node:util";
|
|
|
564239
564379
|
import { existsSync as existsSync85, writeFileSync as writeFileSync46, readFileSync as readFileSync71, appendFileSync as appendFileSync4, mkdirSync as mkdirSync49 } from "node:fs";
|
|
564240
564380
|
import { join as join102 } from "node:path";
|
|
564241
564381
|
import { homedir as homedir30, platform as platform4 } from "node:os";
|
|
564382
|
+
function wrapText(value2, width) {
|
|
564383
|
+
const words = value2.split(/\s+/).filter(Boolean);
|
|
564384
|
+
const lines = [];
|
|
564385
|
+
let line = "";
|
|
564386
|
+
for (const word2 of words) {
|
|
564387
|
+
if (!line) {
|
|
564388
|
+
line = word2;
|
|
564389
|
+
} else if (Array.from(line).length + 1 + Array.from(word2).length <= width) {
|
|
564390
|
+
line += " " + word2;
|
|
564391
|
+
} else {
|
|
564392
|
+
lines.push(line);
|
|
564393
|
+
line = word2;
|
|
564394
|
+
}
|
|
564395
|
+
}
|
|
564396
|
+
if (line) lines.push(line);
|
|
564397
|
+
return lines.length > 0 ? lines : [""];
|
|
564398
|
+
}
|
|
564242
564399
|
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
564243
564400
|
if (_toolSupportCache.has(modelName)) return _toolSupportCache.get(modelName);
|
|
564244
564401
|
try {
|
|
@@ -564459,7 +564616,7 @@ function ensureCurl() {
|
|
|
564459
564616
|
if (hasCmd("curl")) return true;
|
|
564460
564617
|
const plat = platform4();
|
|
564461
564618
|
if (plat === "win32") {
|
|
564462
|
-
process.stdout.write(` ${c3.
|
|
564619
|
+
process.stdout.write(` ${c3.cyan("⚠")} curl not found on Windows — install it manually.
|
|
564463
564620
|
`);
|
|
564464
564621
|
return false;
|
|
564465
564622
|
}
|
|
@@ -564483,7 +564640,7 @@ function ensureCurl() {
|
|
|
564483
564640
|
return true;
|
|
564484
564641
|
}
|
|
564485
564642
|
} catch {
|
|
564486
|
-
process.stdout.write(` ${c3.
|
|
564643
|
+
process.stdout.write(` ${c3.cyan("⚠")} ${s2.label} install failed, trying next...
|
|
564487
564644
|
`);
|
|
564488
564645
|
}
|
|
564489
564646
|
}
|
|
@@ -564520,7 +564677,7 @@ function ensureZstd() {
|
|
|
564520
564677
|
else if (hasCmd("apk")) installCmd = "apk add --no-cache zstd";
|
|
564521
564678
|
if (!installCmd) {
|
|
564522
564679
|
process.stdout.write(`
|
|
564523
|
-
${c3.
|
|
564680
|
+
${c3.cyan("⚠")} Could not detect package manager to install zstd.
|
|
564524
564681
|
`);
|
|
564525
564682
|
return false;
|
|
564526
564683
|
}
|
|
@@ -564689,7 +564846,7 @@ function runElevatedCommand(command, opts = {}) {
|
|
|
564689
564846
|
function runOllamaInstallScript() {
|
|
564690
564847
|
const zstdReady = ensureZstd();
|
|
564691
564848
|
if (!zstdReady) {
|
|
564692
|
-
process.stdout.write(` ${c3.
|
|
564849
|
+
process.stdout.write(` ${c3.cyan("⚠")} Proceeding without zstd — install may fail if the script requires it.
|
|
564693
564850
|
`);
|
|
564694
564851
|
}
|
|
564695
564852
|
const elevated = buildElevatedInstall();
|
|
@@ -564700,9 +564857,9 @@ function runOllamaInstallScript() {
|
|
|
564700
564857
|
process.stdout.write(` ${c3.cyan("●")} Elevation: SUDO_ASKPASS (GUI password modal)
|
|
564701
564858
|
`);
|
|
564702
564859
|
} else {
|
|
564703
|
-
process.stdout.write(` ${c3.
|
|
564860
|
+
process.stdout.write(` ${c3.cyan("⚠")} No GUI password helper available — install may stall waiting for sudo.
|
|
564704
564861
|
`);
|
|
564705
|
-
process.stdout.write(` ${c3.
|
|
564862
|
+
process.stdout.write(` ${c3.cyan("⚠")} Install one of: pkexec / zenity / kdialog / yad / ssh-askpass
|
|
564706
564863
|
`);
|
|
564707
564864
|
}
|
|
564708
564865
|
const runOnce = () => {
|
|
@@ -564722,7 +564879,7 @@ function runOllamaInstallScript() {
|
|
|
564722
564879
|
const combined = stderr + "\n" + message2;
|
|
564723
564880
|
if (combined.includes("requires zstd") || combined.includes("install zstd")) {
|
|
564724
564881
|
process.stdout.write(`
|
|
564725
|
-
${c3.
|
|
564882
|
+
${c3.cyan("⚠")} Ollama install script requires zstd. Attempting to install it...
|
|
564726
564883
|
`);
|
|
564727
564884
|
if (ensureZstd()) {
|
|
564728
564885
|
runOnce();
|
|
@@ -564747,7 +564904,7 @@ async function autoInstallOllama(rl) {
|
|
|
564747
564904
|
} else if (plat === "win32") {
|
|
564748
564905
|
return installOllamaWindows();
|
|
564749
564906
|
}
|
|
564750
|
-
process.stdout.write(` ${c3.
|
|
564907
|
+
process.stdout.write(` ${c3.cyan("⚠")} Unsupported platform: ${plat}
|
|
564751
564908
|
`);
|
|
564752
564909
|
process.stdout.write(` ${c3.dim("Visit https://ollama.com to install manually.")}
|
|
564753
564910
|
|
|
@@ -564768,7 +564925,7 @@ function installOllamaLinux() {
|
|
|
564768
564925
|
return true;
|
|
564769
564926
|
}
|
|
564770
564927
|
process.stdout.write(`
|
|
564771
|
-
${c3.
|
|
564928
|
+
${c3.cyan("⚠")} Install script ran but ollama not found on PATH.
|
|
564772
564929
|
`);
|
|
564773
564930
|
return false;
|
|
564774
564931
|
} catch (err) {
|
|
@@ -564802,7 +564959,7 @@ async function installOllamaMac(_rl) {
|
|
|
564802
564959
|
`);
|
|
564803
564960
|
} else {
|
|
564804
564961
|
process.stdout.write(`
|
|
564805
|
-
${c3.
|
|
564962
|
+
${c3.cyan("⚠")} Homebrew install completed but brew not found on PATH.
|
|
564806
564963
|
`);
|
|
564807
564964
|
process.stdout.write(` ${c3.dim('Try: eval "$(/opt/homebrew/bin/brew shellenv)"')}
|
|
564808
564965
|
|
|
@@ -564832,7 +564989,7 @@ async function installOllamaMac(_rl) {
|
|
|
564832
564989
|
return true;
|
|
564833
564990
|
}
|
|
564834
564991
|
process.stdout.write(`
|
|
564835
|
-
${c3.
|
|
564992
|
+
${c3.cyan("⚠")} brew install completed but ollama not found on PATH.
|
|
564836
564993
|
`);
|
|
564837
564994
|
return false;
|
|
564838
564995
|
} catch (err) {
|
|
@@ -564859,7 +565016,7 @@ function installOllamaWindows() {
|
|
|
564859
565016
|
return true;
|
|
564860
565017
|
}
|
|
564861
565018
|
process.stdout.write(`
|
|
564862
|
-
${c3.
|
|
565019
|
+
${c3.cyan("⚠")} Install script ran but ollama not found on PATH.
|
|
564863
565020
|
`);
|
|
564864
565021
|
return false;
|
|
564865
565022
|
} catch (err) {
|
|
@@ -564874,7 +565031,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
564874
565031
|
if (!ollamaInstalled) {
|
|
564875
565032
|
if (rl) {
|
|
564876
565033
|
process.stdout.write(`
|
|
564877
|
-
${c3.
|
|
565034
|
+
${c3.cyan("⚠")} Ollama is not installed on this system.
|
|
564878
565035
|
`);
|
|
564879
565036
|
const answer = await ask(rl, ` ${c3.bold("Install Ollama now?")} (Y/n) `);
|
|
564880
565037
|
if (answer.toLowerCase() === "n") {
|
|
@@ -564901,7 +565058,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
564901
565058
|
const child = spawn24("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
564902
565059
|
child.unref();
|
|
564903
565060
|
} catch {
|
|
564904
|
-
process.stdout.write(` ${c3.
|
|
565061
|
+
process.stdout.write(` ${c3.cyan("⚠")} Could not start ollama serve.
|
|
564905
565062
|
|
|
564906
565063
|
`);
|
|
564907
565064
|
return false;
|
|
@@ -564921,7 +565078,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
|
|
|
564921
565078
|
} catch {
|
|
564922
565079
|
}
|
|
564923
565080
|
}
|
|
564924
|
-
process.stdout.write(` ${c3.
|
|
565081
|
+
process.stdout.write(` ${c3.cyan("⚠")} Ollama started but not responding. Try ${c3.bold("ollama serve")} manually.
|
|
564925
565082
|
|
|
564926
565083
|
`);
|
|
564927
565084
|
return false;
|
|
@@ -564996,7 +565153,7 @@ function pullModelWithAutoUpdate(tag) {
|
|
|
564996
565153
|
const combined = errMsg + "\n" + stderr;
|
|
564997
565154
|
if (combined.includes("412") || combined.includes("newer version") || combined.includes("requires a newer version")) {
|
|
564998
565155
|
process.stdout.write(`
|
|
564999
|
-
${c3.
|
|
565156
|
+
${c3.cyan("⚠")} Ollama needs to be updated for this model.
|
|
565000
565157
|
`);
|
|
565001
565158
|
if (!ensureCurl()) {
|
|
565002
565159
|
throw new Error("curl is required to update Ollama but could not be installed.");
|
|
@@ -565124,7 +565281,7 @@ function ensurePython3() {
|
|
|
565124
565281
|
}
|
|
565125
565282
|
}
|
|
565126
565283
|
}
|
|
565127
|
-
process.stdout.write(` ${c3.
|
|
565284
|
+
process.stdout.write(` ${c3.cyan("⚠")} Could not install Python3 automatically. Install manually.
|
|
565128
565285
|
|
|
565129
565286
|
`);
|
|
565130
565287
|
}
|
|
@@ -565163,7 +565320,7 @@ function ensurePythonVenv() {
|
|
|
565163
565320
|
}
|
|
565164
565321
|
}
|
|
565165
565322
|
}
|
|
565166
|
-
process.stdout.write(` ${c3.
|
|
565323
|
+
process.stdout.write(` ${c3.cyan("⚠")} Could not install python3-venv. Install manually: sudo apt install python3-venv
|
|
565167
565324
|
|
|
565168
565325
|
`);
|
|
565169
565326
|
}
|
|
@@ -565249,12 +565406,12 @@ async function promptForCustomEndpoint(config, rl) {
|
|
|
565249
565406
|
}
|
|
565250
565407
|
}
|
|
565251
565408
|
if (!testOk) {
|
|
565252
|
-
process.stdout.write(` ${c3.
|
|
565409
|
+
process.stdout.write(` ${c3.cyan("⚠")} Endpoint returned HTTP ${resp.status}
|
|
565253
565410
|
`);
|
|
565254
565411
|
}
|
|
565255
565412
|
}
|
|
565256
565413
|
} catch (err) {
|
|
565257
|
-
process.stdout.write(` ${c3.
|
|
565414
|
+
process.stdout.write(` ${c3.cyan("⚠")} Could not reach endpoint: ${err instanceof Error ? err.message : String(err)}
|
|
565258
565415
|
`);
|
|
565259
565416
|
}
|
|
565260
565417
|
if (!testOk) {
|
|
@@ -565292,7 +565449,7 @@ async function promptForCustomEndpoint(config, rl) {
|
|
|
565292
565449
|
}
|
|
565293
565450
|
async function doSetup(config, rl) {
|
|
565294
565451
|
process.stdout.write(`
|
|
565295
|
-
|
|
565452
|
+
${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
565296
565453
|
`);
|
|
565297
565454
|
process.stdout.write(` ${c3.dim("─".repeat(60))}
|
|
565298
565455
|
`);
|
|
@@ -565329,36 +565486,43 @@ async function doSetup(config, rl) {
|
|
|
565329
565486
|
const bw = 30;
|
|
565330
565487
|
const sw = 24;
|
|
565331
565488
|
const boxW = 52;
|
|
565332
|
-
const boxLine = (content
|
|
565489
|
+
const boxLine = (content) => {
|
|
565490
|
+
const visLen = visibleLen(content);
|
|
565333
565491
|
const pad = Math.max(0, boxW - visLen);
|
|
565334
565492
|
return ` ${c3.dim("│")}${content}${" ".repeat(pad)}${c3.dim("│")}
|
|
565335
565493
|
`;
|
|
565336
565494
|
};
|
|
565495
|
+
const boxWrappedDimLine = (content, indent = " ") => {
|
|
565496
|
+
const lines = wrapText(content, Math.max(1, boxW - visibleLen(indent)));
|
|
565497
|
+
for (const line of lines) {
|
|
565498
|
+
process.stdout.write(boxLine(`${indent}${c3.dim(line)}`));
|
|
565499
|
+
}
|
|
565500
|
+
};
|
|
565337
565501
|
const hLine = (ch) => ` ${c3.dim(ch + "─".repeat(boxW) + (ch === "┌" ? "┐" : ch === "├" ? "┤" : "┘"))}
|
|
565338
565502
|
`;
|
|
565339
565503
|
process.stdout.write("\n");
|
|
565340
565504
|
process.stdout.write(hLine("┌"));
|
|
565341
|
-
process.stdout.write(boxLine(` ${c3.bold("Inference Capability")}
|
|
565505
|
+
process.stdout.write(boxLine(` ${c3.bold("Inference Capability")}`));
|
|
565342
565506
|
process.stdout.write(hLine("├"));
|
|
565343
|
-
process.stdout.write(boxLine(` ${c3.bold("Overall")}
|
|
565507
|
+
process.stdout.write(boxLine(` ${c3.bold("Overall")}`));
|
|
565344
565508
|
const overallBar = renderScoreBar(score.overall, bw);
|
|
565345
565509
|
const overallLabel = `${String(score.overall).padStart(3)}/100`;
|
|
565346
|
-
process.stdout.write(boxLine(` ${overallBar} ${c3.bold(overallLabel)}
|
|
565347
|
-
|
|
565510
|
+
process.stdout.write(boxLine(` ${overallBar} ${c3.bold(overallLabel)}`));
|
|
565511
|
+
boxWrappedDimLine(score.summary);
|
|
565348
565512
|
process.stdout.write(hLine("├"));
|
|
565349
565513
|
const memLabel = `${specs.totalRamGB.toFixed(0)} GB RAM` + (specs.gpuVramGB > 0 ? ` + ${specs.gpuVramGB.toFixed(0)} GB VRAM` : "");
|
|
565350
|
-
process.stdout.write(boxLine(` ${c3.bold("Memory")} ${c3.dim(memLabel)}
|
|
565351
|
-
process.stdout.write(boxLine(` ${renderScoreBar(score.memory, sw)} ${String(score.memory).padStart(3)}
|
|
565352
|
-
process.stdout.write(boxLine(""
|
|
565514
|
+
process.stdout.write(boxLine(` ${c3.bold("Memory")} ${c3.dim(memLabel)}`));
|
|
565515
|
+
process.stdout.write(boxLine(` ${renderScoreBar(score.memory, sw)} ${String(score.memory).padStart(3)}`));
|
|
565516
|
+
process.stdout.write(boxLine(""));
|
|
565353
565517
|
const gpuLabel = specs.gpuVramGB > 0 ? specs.gpuName || "NVIDIA GPU" : "CPU only";
|
|
565354
|
-
process.stdout.write(boxLine(` ${c3.bold("Compute")} ${c3.dim(gpuLabel)}
|
|
565355
|
-
process.stdout.write(boxLine(` ${renderScoreBar(score.compute, sw)} ${String(score.compute).padStart(3)}
|
|
565356
|
-
process.stdout.write(boxLine(""
|
|
565518
|
+
process.stdout.write(boxLine(` ${c3.bold("Compute")} ${c3.dim(gpuLabel)}`));
|
|
565519
|
+
process.stdout.write(boxLine(` ${renderScoreBar(score.compute, sw)} ${String(score.compute).padStart(3)}`));
|
|
565520
|
+
process.stdout.write(boxLine(""));
|
|
565357
565521
|
const speedLabel = specs.gpuVramGB > 0 ? "GPU accelerated" : "CPU inference";
|
|
565358
|
-
process.stdout.write(boxLine(` ${c3.bold("Speed")} ${c3.dim(speedLabel)}
|
|
565359
|
-
process.stdout.write(boxLine(` ${renderScoreBar(score.speed, sw)} ${String(score.speed).padStart(3)}
|
|
565522
|
+
process.stdout.write(boxLine(` ${c3.bold("Speed")} ${c3.dim(speedLabel)}`));
|
|
565523
|
+
process.stdout.write(boxLine(` ${renderScoreBar(score.speed, sw)} ${String(score.speed).padStart(3)}`));
|
|
565360
565524
|
process.stdout.write(hLine("├"));
|
|
565361
|
-
process.stdout.write(boxLine(` ${c3.bold("Model Compatibility")}
|
|
565525
|
+
process.stdout.write(boxLine(` ${c3.bold("Model Compatibility")}`));
|
|
565362
565526
|
for (const compat of score.modelCompat) {
|
|
565363
565527
|
const icon = compat.fits ? c3.green("✔") : c3.red("✖");
|
|
565364
565528
|
const tag = compat.fits ? compat.tag : c3.dim(compat.tag);
|
|
@@ -565372,7 +565536,7 @@ async function doSetup(config, rl) {
|
|
|
565372
565536
|
process.stdout.write("\n");
|
|
565373
565537
|
let hasPython = hasCmd("python3") || hasCmd("python");
|
|
565374
565538
|
if (!hasPython) {
|
|
565375
|
-
process.stdout.write(` ${c3.
|
|
565539
|
+
process.stdout.write(` ${c3.cyan("⚠")} Python3 not found (needed for vision, OCR, browser automation).
|
|
565376
565540
|
`);
|
|
565377
565541
|
const installPy = await ask(rl, ` ${c3.bold("Install Python3?")} (Y/n) `);
|
|
565378
565542
|
if (installPy.toLowerCase() !== "n") {
|
|
@@ -565383,7 +565547,7 @@ async function doSetup(config, rl) {
|
|
|
565383
565547
|
if (hasPython) {
|
|
565384
565548
|
const hasVenv = checkPythonVenv();
|
|
565385
565549
|
if (!hasVenv) {
|
|
565386
|
-
process.stdout.write(` ${c3.
|
|
565550
|
+
process.stdout.write(` ${c3.cyan("⚠")} Python3 venv module not found (needed for Moondream, OCR, browser automation).
|
|
565387
565551
|
`);
|
|
565388
565552
|
const installVenv = await ask(rl, ` ${c3.bold("Install python3-venv?")} (Y/n) `);
|
|
565389
565553
|
if (installVenv.toLowerCase() !== "n") {
|
|
@@ -565396,7 +565560,7 @@ async function doSetup(config, rl) {
|
|
|
565396
565560
|
try {
|
|
565397
565561
|
models = await fetchOllamaModels(config.backendUrl);
|
|
565398
565562
|
} catch {
|
|
565399
|
-
process.stdout.write(` ${c3.
|
|
565563
|
+
process.stdout.write(` ${c3.cyan("⚠")} Cannot reach Ollama at ${c3.bold(config.backendUrl)}
|
|
565400
565564
|
|
|
565401
565565
|
`);
|
|
565402
565566
|
const useCustom = await ask(rl, ` ${c3.bold("Use a custom inference endpoint instead?")} (Y/n) `);
|
|
@@ -565422,12 +565586,12 @@ async function doSetup(config, rl) {
|
|
|
565422
565586
|
|
|
565423
565587
|
`);
|
|
565424
565588
|
} catch {
|
|
565425
|
-
process.stdout.write(` ${c3.
|
|
565589
|
+
process.stdout.write(` ${c3.cyan("⚠")} Ollama started but not responding yet. It may need a moment.
|
|
565426
565590
|
|
|
565427
565591
|
`);
|
|
565428
565592
|
}
|
|
565429
565593
|
} catch {
|
|
565430
|
-
process.stdout.write(` ${c3.
|
|
565594
|
+
process.stdout.write(` ${c3.cyan("⚠")} Could not start Ollama. Try running ${c3.bold("ollama serve")} manually.
|
|
565431
565595
|
|
|
565432
565596
|
`);
|
|
565433
565597
|
}
|
|
@@ -565450,12 +565614,12 @@ async function doSetup(config, rl) {
|
|
|
565450
565614
|
|
|
565451
565615
|
`);
|
|
565452
565616
|
} catch {
|
|
565453
|
-
process.stdout.write(` ${c3.
|
|
565617
|
+
process.stdout.write(` ${c3.cyan("⚠")} Ollama installed but not responding yet. Try ${c3.bold("ollama serve")} manually.
|
|
565454
565618
|
|
|
565455
565619
|
`);
|
|
565456
565620
|
}
|
|
565457
565621
|
} catch {
|
|
565458
|
-
process.stdout.write(` ${c3.
|
|
565622
|
+
process.stdout.write(` ${c3.cyan("⚠")} Ollama installed. Start it with: ${c3.bold("ollama serve")}
|
|
565459
565623
|
|
|
565460
565624
|
`);
|
|
565461
565625
|
}
|
|
@@ -565482,7 +565646,7 @@ async function doSetup(config, rl) {
|
|
|
565482
565646
|
`);
|
|
565483
565647
|
return currentModel.name;
|
|
565484
565648
|
}
|
|
565485
|
-
process.stdout.write(` ${c3.
|
|
565649
|
+
process.stdout.write(` ${c3.cyan("⚠")} Default model ${c3.bold(config.model)} is not available.
|
|
565486
565650
|
|
|
565487
565651
|
`);
|
|
565488
565652
|
if (models.length > 0) {
|
|
@@ -565514,7 +565678,7 @@ async function doSetup(config, rl) {
|
|
|
565514
565678
|
return selected.name;
|
|
565515
565679
|
}
|
|
565516
565680
|
} else {
|
|
565517
|
-
process.stdout.write(` ${c3.
|
|
565681
|
+
process.stdout.write(` ${c3.cyan("⚠")} No models found on this system.
|
|
565518
565682
|
|
|
565519
565683
|
`);
|
|
565520
565684
|
}
|
|
@@ -566584,7 +566748,7 @@ export PATH="${binDir}:$PATH" # Added by omnius for nvim
|
|
|
566584
566748
|
} catch {
|
|
566585
566749
|
}
|
|
566586
566750
|
}
|
|
566587
|
-
var execAsync2, QWEN_VARIANTS, _toolSupportCache, _cloudflaredInstallPromise;
|
|
566751
|
+
var execAsync2, OMNIUS_FIRST_RUN_BANNER, ANSI_RE, visibleLen, QWEN_VARIANTS, _toolSupportCache, _cloudflaredInstallPromise;
|
|
566588
566752
|
var init_setup = __esm({
|
|
566589
566753
|
"packages/cli/src/tui/setup.ts"() {
|
|
566590
566754
|
"use strict";
|
|
@@ -566594,6 +566758,17 @@ var init_setup = __esm({
|
|
|
566594
566758
|
init_dist();
|
|
566595
566759
|
init_tui_select();
|
|
566596
566760
|
execAsync2 = promisify5(exec4);
|
|
566761
|
+
OMNIUS_FIRST_RUN_BANNER = [
|
|
566762
|
+
" ░▒▓██████▓▒░░▒▓██████████████▓▒░░▒▓███████▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ ",
|
|
566763
|
+
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ",
|
|
566764
|
+
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ",
|
|
566765
|
+
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓██████▓▒░ ",
|
|
566766
|
+
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ",
|
|
566767
|
+
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ",
|
|
566768
|
+
" ░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░ "
|
|
566769
|
+
].join("\n");
|
|
566770
|
+
ANSI_RE = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
566771
|
+
visibleLen = (value2) => Array.from(value2.replace(ANSI_RE, "")).length;
|
|
566597
566772
|
QWEN_VARIANTS = [
|
|
566598
566773
|
{ tag: "qwen3.5:0.8b", sizeGB: 1, label: "0.8B params (1.0 GB)", cloud: false },
|
|
566599
566774
|
{ tag: "qwen3.5:2b", sizeGB: 2.7, label: "2B params (2.7 GB)", cloud: false },
|
|
@@ -581466,7 +581641,7 @@ async function showColorMenu(ctx3) {
|
|
|
581466
581641
|
{
|
|
581467
581642
|
key: "branding",
|
|
581468
581643
|
label: `Omnius Branding${currentConfig.mode === "branding" ? " (active)" : ""}`,
|
|
581469
|
-
detail: "
|
|
581644
|
+
detail: "Teal accent on terminal background"
|
|
581470
581645
|
},
|
|
581471
581646
|
{
|
|
581472
581647
|
key: "custom",
|
|
@@ -587626,30 +587801,30 @@ function getNodeMnemonic() {
|
|
|
587626
587801
|
function createDefaultBanner(version4 = "0.120.0") {
|
|
587627
587802
|
const width = termCols();
|
|
587628
587803
|
const rows = headerHeight();
|
|
587629
|
-
const
|
|
587804
|
+
const accent2 = tuiAccent() < 0 ? -1 : tuiAccent();
|
|
587630
587805
|
const bgBlack = tuiBg() < 0 ? -1 : tuiBg();
|
|
587631
587806
|
const grid = [];
|
|
587632
587807
|
const innerW = width - 2;
|
|
587633
587808
|
const topRow = [];
|
|
587634
|
-
topRow.push({ char: "╭", fg:
|
|
587809
|
+
topRow.push({ char: "╭", fg: accent2, bg: bgBlack, bold: false });
|
|
587635
587810
|
for (let c9 = 0; c9 < innerW; c9++) {
|
|
587636
|
-
topRow.push({ char: "─", fg:
|
|
587811
|
+
topRow.push({ char: "─", fg: accent2, bg: bgBlack, bold: false });
|
|
587637
587812
|
}
|
|
587638
|
-
topRow.push({ char: "╮", fg:
|
|
587813
|
+
topRow.push({ char: "╮", fg: accent2, bg: bgBlack, bold: false });
|
|
587639
587814
|
grid.push(topRow);
|
|
587640
587815
|
const midRow = [];
|
|
587641
|
-
midRow.push({ char: "│", fg:
|
|
587816
|
+
midRow.push({ char: "│", fg: accent2, bg: bgBlack, bold: false });
|
|
587642
587817
|
for (let c9 = 0; c9 < innerW; c9++) {
|
|
587643
587818
|
midRow.push({ char: " ", fg: 0, bg: bgBlack, bold: false });
|
|
587644
587819
|
}
|
|
587645
|
-
midRow.push({ char: "│", fg:
|
|
587820
|
+
midRow.push({ char: "│", fg: accent2, bg: bgBlack, bold: false });
|
|
587646
587821
|
grid.push(midRow);
|
|
587647
587822
|
const botRow = [];
|
|
587648
|
-
botRow.push({ char: "╰", fg:
|
|
587823
|
+
botRow.push({ char: "╰", fg: accent2, bg: bgBlack, bold: false });
|
|
587649
587824
|
for (let c9 = 0; c9 < innerW; c9++) {
|
|
587650
|
-
botRow.push({ char: "─", fg:
|
|
587825
|
+
botRow.push({ char: "─", fg: accent2, bg: bgBlack, bold: false });
|
|
587651
587826
|
}
|
|
587652
|
-
botRow.push({ char: "╯", fg:
|
|
587827
|
+
botRow.push({ char: "╯", fg: accent2, bg: bgBlack, bold: false });
|
|
587653
587828
|
grid.push(botRow);
|
|
587654
587829
|
return {
|
|
587655
587830
|
id: "default-header",
|
|
@@ -588330,7 +588505,7 @@ var init_carousel_descriptors = __esm({
|
|
|
588330
588505
|
},
|
|
588331
588506
|
{
|
|
588332
588507
|
name: "memory",
|
|
588333
|
-
colors: [
|
|
588508
|
+
colors: [23, 29, 35, 36, 37, 43, 44, 50],
|
|
588334
588509
|
tools: ["memory_read", "memory_write"]
|
|
588335
588510
|
},
|
|
588336
588511
|
{
|
|
@@ -593226,7 +593401,7 @@ import { mkdirSync as mkdirSync60, existsSync as existsSync105, unlinkSync as un
|
|
|
593226
593401
|
import { join as join120, resolve as resolve39, basename as basename22 } from "node:path";
|
|
593227
593402
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
593228
593403
|
import { createHash as createHash19, randomInt } from "node:crypto";
|
|
593229
|
-
function parseTelegramInteractionDecision(text, forcedRoute) {
|
|
593404
|
+
function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
|
|
593230
593405
|
const cleaned = stripTelegramHiddenThinking(text).replace(/```(?:json)?/gi, "").replace(/```/g, "").trim();
|
|
593231
593406
|
const jsonText = cleaned.startsWith("{") ? cleaned : cleaned.match(/\{[\s\S]*\}/)?.[0] ?? "";
|
|
593232
593407
|
if (!jsonText) return null;
|
|
@@ -593236,7 +593411,7 @@ function parseTelegramInteractionDecision(text, forcedRoute) {
|
|
|
593236
593411
|
const route = forcedRoute ?? parsedRoute;
|
|
593237
593412
|
if (!route) return null;
|
|
593238
593413
|
const shouldReplyRaw = parsed["should_reply"] ?? parsed["shouldReply"];
|
|
593239
|
-
const shouldReply = typeof shouldReplyRaw === "boolean" ? shouldReplyRaw : true;
|
|
593414
|
+
const shouldReply = typeof shouldReplyRaw === "boolean" ? shouldReplyRaw : options2.defaultShouldReply ?? true;
|
|
593240
593415
|
const confidenceRaw = Number(parsed["confidence"]);
|
|
593241
593416
|
const confidence = Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : 0;
|
|
593242
593417
|
const reason = String(parsed["reason"] ?? "live inference decision").slice(0, 240);
|
|
@@ -593299,6 +593474,41 @@ function sanitizeTelegramProgressText(text, maxLength) {
|
|
|
593299
593474
|
const compact = stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
|
|
593300
593475
|
return compact.length > maxLength ? compact.slice(0, Math.max(0, maxLength - 3)) + "..." : compact;
|
|
593301
593476
|
}
|
|
593477
|
+
function compactTelegramVisibleText(text) {
|
|
593478
|
+
return stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
|
|
593479
|
+
}
|
|
593480
|
+
function isTelegramPotentialNoReplyPrefix(text) {
|
|
593481
|
+
const lower = compactTelegramVisibleText(text).toLowerCase();
|
|
593482
|
+
return Boolean(lower) && "no_reply".startsWith(lower);
|
|
593483
|
+
}
|
|
593484
|
+
function isTelegramNoReplySentinel(text) {
|
|
593485
|
+
const lower = compactTelegramVisibleText(text).toLowerCase();
|
|
593486
|
+
return lower === "no_reply" || lower.startsWith("no_reply");
|
|
593487
|
+
}
|
|
593488
|
+
function isTelegramInternalStatusText(text) {
|
|
593489
|
+
const compact = compactTelegramVisibleText(text);
|
|
593490
|
+
if (!compact) return false;
|
|
593491
|
+
const lower = compact.toLowerCase();
|
|
593492
|
+
if (isTelegramNoReplySentinel(compact)) return true;
|
|
593493
|
+
if (lower === "complete" || lower === "completed") return true;
|
|
593494
|
+
if (/^memory stage:/i.test(compact)) return true;
|
|
593495
|
+
if (/^\[ppr[-_\s]?skip\]/i.test(compact)) return true;
|
|
593496
|
+
if (/^(casual|ambient|group)\b.{0,180}\b(skipping|skipped|not directed|no action needed|no reply)\b/i.test(compact)) return true;
|
|
593497
|
+
if (/^no further action needed\b/i.test(compact)) return true;
|
|
593498
|
+
if (/^no action needed\b.{0,120}\b(task|complete|completed|done)\b/i.test(compact)) return true;
|
|
593499
|
+
if (/^(there'?s|there is) no active task\b/i.test(compact)) return true;
|
|
593500
|
+
if (/^everything'?s (done|complete|completed|wrapped up)\b/i.test(compact)) return true;
|
|
593501
|
+
if (/\balready (been )?(provided|answered|handled|delivered) above\b/i.test(compact)) return true;
|
|
593502
|
+
if (/\b(no remaining work|nothing left to do|task is complete|task has been completed)\b/i.test(compact)) return true;
|
|
593503
|
+
return false;
|
|
593504
|
+
}
|
|
593505
|
+
function cleanTelegramVisibleReply(text, options2 = {}) {
|
|
593506
|
+
const clean3 = stripTelegramHiddenThinking(text).trim();
|
|
593507
|
+
if (!clean3) return "";
|
|
593508
|
+
if (options2.suppressPotentialNoReplyPrefix && isTelegramPotentialNoReplyPrefix(clean3)) return "";
|
|
593509
|
+
if (isTelegramInternalStatusText(clean3)) return "";
|
|
593510
|
+
return clean3;
|
|
593511
|
+
}
|
|
593302
593512
|
function truncateTelegramContext(text, maxLength) {
|
|
593303
593513
|
const trimmed = text.trim();
|
|
593304
593514
|
if (trimmed.length <= maxLength) return trimmed;
|
|
@@ -593419,13 +593629,14 @@ function selectTelegramFinalResponse(args) {
|
|
|
593419
593629
|
args.streamText,
|
|
593420
593630
|
args.accumulated,
|
|
593421
593631
|
args.assistantText
|
|
593422
|
-
].map((candidate) =>
|
|
593632
|
+
].map((candidate) => cleanTelegramVisibleReply(candidate || "")).filter(Boolean);
|
|
593423
593633
|
if (visibleCandidates.length > 0) {
|
|
593424
593634
|
return visibleCandidates.reduce(
|
|
593425
593635
|
(best, current) => current.length > best.length ? current : best
|
|
593426
593636
|
);
|
|
593427
593637
|
}
|
|
593428
|
-
|
|
593638
|
+
void args.summary;
|
|
593639
|
+
return "";
|
|
593429
593640
|
}
|
|
593430
593641
|
function formatTelegramProgressEvent(event) {
|
|
593431
593642
|
if (event.type === "tool_call" && event.toolName === "task_complete") return null;
|
|
@@ -593435,23 +593646,25 @@ function formatTelegramProgressEvent(event) {
|
|
|
593435
593646
|
}
|
|
593436
593647
|
if (event.type === "tool_result") {
|
|
593437
593648
|
const preview = sanitizeTelegramProgressText(event.content || "", 80);
|
|
593649
|
+
if (isTelegramInternalStatusText(preview)) return null;
|
|
593438
593650
|
const toolName = escapeTelegramHTML(event.toolName || "tool");
|
|
593439
593651
|
if (preview) return `${toolName}: ${escapeTelegramHTML(preview)}`;
|
|
593440
593652
|
return event.success ? `${toolName} completed` : `${toolName} failed`;
|
|
593441
593653
|
}
|
|
593442
593654
|
if (event.type === "status") {
|
|
593443
593655
|
const content = sanitizeTelegramProgressText(event.content || "", 120);
|
|
593656
|
+
if (isTelegramInternalStatusText(content)) return null;
|
|
593444
593657
|
return content ? escapeTelegramHTML(content) : null;
|
|
593445
593658
|
}
|
|
593446
593659
|
return null;
|
|
593447
593660
|
}
|
|
593448
593661
|
function renderTelegramLiveProgressHTML(progressLines, accumulated) {
|
|
593449
|
-
const draft =
|
|
593662
|
+
const draft = cleanTelegramVisibleReply(accumulated, { suppressPotentialNoReplyPrefix: true });
|
|
593450
593663
|
if (draft) {
|
|
593451
593664
|
const clipped = draft.length > 2e3 ? `${draft.slice(0, 1997).trimEnd()}...` : draft;
|
|
593452
593665
|
return convertMarkdownToTelegramHTML(clipped);
|
|
593453
593666
|
}
|
|
593454
|
-
return progressLines.slice(-6).map((line) => line.trim()).filter(Boolean).join("\n");
|
|
593667
|
+
return progressLines.slice(-6).map((line) => line.trim()).filter((line) => !isTelegramInternalStatusText(line)).filter(Boolean).join("\n");
|
|
593455
593668
|
}
|
|
593456
593669
|
function telegramSyntheticHelpSignatures() {
|
|
593457
593670
|
return [
|
|
@@ -593935,14 +594148,17 @@ RULES FOR GROUP CONTEXT:
|
|
|
593935
594148
|
6. You may share general knowledge and helpful guidance
|
|
593936
594149
|
`.trim();
|
|
593937
594150
|
GROUP_REPLY_DISCRETION_PROMPT = `
|
|
593938
|
-
REPLY DISCRETION: You are in a group chat.
|
|
593939
|
-
|
|
593940
|
-
|
|
593941
|
-
|
|
593942
|
-
|
|
593943
|
-
|
|
593944
|
-
|
|
593945
|
-
|
|
594151
|
+
REPLY DISCRETION: You are in a group chat. The live router has already filtered
|
|
594152
|
+
most ambient chatter. Continue to be selective:
|
|
594153
|
+
1. Respond when someone directly addresses the bot, replies to the bot, or keeps
|
|
594154
|
+
an active bot-involved task moving.
|
|
594155
|
+
2. Stay silent for conversation between other people, third-person commentary
|
|
594156
|
+
about the bot, status chatter, or questions clearly meant for someone else.
|
|
594157
|
+
3. Do not reply just because you know an answer or could add color.
|
|
594158
|
+
|
|
594159
|
+
If you determine no visible reply should be sent, call task_complete with summary
|
|
594160
|
+
"no_reply". Never write "no_reply", "skipping", "no action needed", or a status
|
|
594161
|
+
explanation as assistant text.
|
|
593946
594162
|
`.trim();
|
|
593947
594163
|
TELEGRAM_CHAT_MODE_PROMPT = `
|
|
593948
594164
|
You are Omnius replying in Telegram quick-chat mode.
|
|
@@ -593956,6 +594172,7 @@ Rules:
|
|
|
593956
594172
|
6. Use the Telegram conversation context stream as the source of truth for who said what, recent group dynamics, and retained earlier context.
|
|
593957
594173
|
7. Do not claim older chat is unavailable when the context stream contains it. If asked what you see, summarize the supplied transcript, speakers, and relationship/tone signals.
|
|
593958
594174
|
8. Mirror the current sender's tone and directness while staying safe and clear.
|
|
594175
|
+
9. Never send router decisions, skip explanations, memory-stage notes, task-complete summaries, or "no_reply" as chat text.
|
|
593959
594176
|
`.trim();
|
|
593960
594177
|
ADMIN_CHAT_PROFILE_PROMPT = `
|
|
593961
594178
|
You are replying to the authenticated Telegram admin in a private DM.
|
|
@@ -593972,6 +594189,7 @@ Capabilities:
|
|
|
593972
594189
|
Telegram response contract:
|
|
593973
594190
|
- Write the actual Telegram reply as normal assistant text before completion.
|
|
593974
594191
|
- task_complete is only an internal completion signal; do not put status reports, wrap-up notes, or meta-commentary there.
|
|
594192
|
+
- "no_reply" is an internal silent-skip sentinel only; never emit it or explain it in assistant text.
|
|
593975
594193
|
- Do not summarize the fact that you answered; the visible assistant text must be the answer itself.
|
|
593976
594194
|
- If you delegated long-running work, include the sub-agent id/status and what the admin should expect next.
|
|
593977
594195
|
`.trim();
|
|
@@ -594076,6 +594294,8 @@ Telegram response contract:
|
|
|
594076
594294
|
groupSkipLogAt = /* @__PURE__ */ new Map();
|
|
594077
594295
|
/** Telegram interaction routing profile */
|
|
594078
594296
|
interactionMode = "auto";
|
|
594297
|
+
/** Actual model context window discovered by the main TUI. */
|
|
594298
|
+
contextWindowSize = 0;
|
|
594079
594299
|
/** Event handler for forwarding sub-agent events to parent TUI */
|
|
594080
594300
|
onSubAgentEvent = null;
|
|
594081
594301
|
/** Tool policy config — user overrides from config */
|
|
@@ -594126,6 +594346,9 @@ Telegram response contract:
|
|
|
594126
594346
|
getInteractionMode() {
|
|
594127
594347
|
return this.interactionMode;
|
|
594128
594348
|
}
|
|
594349
|
+
setContextWindowSize(size) {
|
|
594350
|
+
this.contextWindowSize = Number.isFinite(size) && size > 0 ? Math.trunc(size) : 0;
|
|
594351
|
+
}
|
|
594129
594352
|
/** Update tool policy config at runtime (e.g., from /disable command) */
|
|
594130
594353
|
setToolPolicyConfig(config) {
|
|
594131
594354
|
this.toolPolicyConfig = config;
|
|
@@ -594627,6 +594850,7 @@ ${lines.join("\n")}`);
|
|
|
594627
594850
|
return sections.join("\n\n");
|
|
594628
594851
|
}
|
|
594629
594852
|
maybeLogTelegramGroupSkip(msg, reason) {
|
|
594853
|
+
if (process.env["OMNIUS_TELEGRAM_DEBUG_SKIPS"] !== "1") return;
|
|
594630
594854
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
594631
594855
|
const now = Date.now();
|
|
594632
594856
|
const last2 = this.groupSkipLogAt.get(sessionKey) ?? 0;
|
|
@@ -594637,17 +594861,17 @@ ${lines.join("\n")}`);
|
|
|
594637
594861
|
async inferTelegramInteractionDecision(msg, toolContext) {
|
|
594638
594862
|
const config = this.agentConfig;
|
|
594639
594863
|
const forcedRoute = this.interactionMode === "chat" || this.interactionMode === "action" ? this.interactionMode : null;
|
|
594864
|
+
const isGroup = msg.chatType !== "private";
|
|
594640
594865
|
if (!config) {
|
|
594641
594866
|
return {
|
|
594642
594867
|
route: forcedRoute ?? "action",
|
|
594643
|
-
shouldReply:
|
|
594868
|
+
shouldReply: !isGroup,
|
|
594644
594869
|
confidence: 0,
|
|
594645
|
-
reason: "router inference unavailable;
|
|
594870
|
+
reason: isGroup ? "router inference unavailable; public group fails closed without keyword heuristics" : "router inference unavailable; private chat defaults to reply",
|
|
594646
594871
|
source: "inference-unavailable"
|
|
594647
594872
|
};
|
|
594648
594873
|
}
|
|
594649
594874
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
594650
|
-
const isGroup = msg.chatType !== "private";
|
|
594651
594875
|
const backend = new OllamaAgenticBackend(
|
|
594652
594876
|
config.backendUrl,
|
|
594653
594877
|
config.model,
|
|
@@ -594665,7 +594889,9 @@ ${lines.join("\n")}`);
|
|
|
594665
594889
|
`- chat: a short conversational answer can be produced without tools.`,
|
|
594666
594890
|
`- action: tools, workspace context, media processing, web lookup, delegation, or a multi-step agent loop may be needed.`,
|
|
594667
594891
|
``,
|
|
594668
|
-
`Reply discretion: infer from the live thread, speaker relationships, direct mentions, replies, tone, and current message. Do not use static keyword rules
|
|
594892
|
+
`Reply discretion: infer from the live thread, speaker relationships, direct mentions, replies, tone, and current message. Do not use static keyword rules.`,
|
|
594893
|
+
`Private chats: should_reply is normally true.`,
|
|
594894
|
+
`Group/public chats: default should_reply to false unless the current message clearly addresses the bot, replies to the bot, continues an active bot-involved exchange, assigns the bot work, or asks for the bot's view. Ambient chatter, third-person discussion about the bot, commands meant for a human, or questions among other people are false. Do not set true just because the bot could help.`,
|
|
594669
594895
|
forcedLine,
|
|
594670
594896
|
``,
|
|
594671
594897
|
`Tool context: ${toolContext}`,
|
|
@@ -594692,19 +594918,21 @@ ${msg.text}`
|
|
|
594692
594918
|
tools: [],
|
|
594693
594919
|
temperature: 0,
|
|
594694
594920
|
maxTokens: 220,
|
|
594695
|
-
timeoutMs: Math.min(config.timeoutMs ?? 3e4, 15e3),
|
|
594921
|
+
timeoutMs: Math.min(Math.max(config.timeoutMs ?? 3e4, 5e3), 15e3),
|
|
594696
594922
|
think: false
|
|
594697
594923
|
});
|
|
594698
594924
|
const text = result.choices[0]?.message?.content ?? "";
|
|
594699
|
-
const parsed = parseTelegramInteractionDecision(text, forcedRoute
|
|
594925
|
+
const parsed = parseTelegramInteractionDecision(text, forcedRoute, {
|
|
594926
|
+
defaultShouldReply: !isGroup
|
|
594927
|
+
});
|
|
594700
594928
|
if (parsed) return parsed;
|
|
594701
594929
|
} catch {
|
|
594702
594930
|
}
|
|
594703
594931
|
return {
|
|
594704
594932
|
route: forcedRoute ?? "action",
|
|
594705
|
-
shouldReply:
|
|
594933
|
+
shouldReply: !isGroup,
|
|
594706
594934
|
confidence: 0,
|
|
594707
|
-
reason: "router inference failed;
|
|
594935
|
+
reason: isGroup ? "router inference failed; public group fails closed without keyword heuristics" : "router inference failed; private chat defaults to reply",
|
|
594708
594936
|
source: "inference-unavailable"
|
|
594709
594937
|
};
|
|
594710
594938
|
}
|
|
@@ -594718,6 +594946,19 @@ ${msg.text}`
|
|
|
594718
594946
|
return `Workspace context unavailable: ${reason}`;
|
|
594719
594947
|
}
|
|
594720
594948
|
}
|
|
594949
|
+
telegramFallbackCompactionThreshold(modelTier) {
|
|
594950
|
+
if (modelTier === "small") return 12e3;
|
|
594951
|
+
if (modelTier === "medium") return 24e3;
|
|
594952
|
+
return 4e4;
|
|
594953
|
+
}
|
|
594954
|
+
telegramWorkspaceBudget(profile) {
|
|
594955
|
+
if (this.contextWindowSize > 0) {
|
|
594956
|
+
const ratio = profile === "chat" ? 0.08 : 0.12;
|
|
594957
|
+
const floor = profile === "chat" ? 16e3 : 24e3;
|
|
594958
|
+
return Math.max(floor, Math.floor(this.contextWindowSize * ratio));
|
|
594959
|
+
}
|
|
594960
|
+
return profile === "chat" ? 16e3 : 24e3;
|
|
594961
|
+
}
|
|
594721
594962
|
buildPrimaryTuiSessionContext(telegramSessionId) {
|
|
594722
594963
|
const primarySessionId = process.env["OMNIUS_SESSION_ID"] || process.env["OMNIUS_TUI_SESSION_ID"] || "";
|
|
594723
594964
|
if (!primarySessionId || primarySessionId === telegramSessionId) return "";
|
|
@@ -594775,7 +595016,7 @@ ${ADMIN_CHAT_PROFILE_PROMPT}`);
|
|
|
594775
595016
|
if (primarySessionContext) sections.push(`## Primary TUI Session State
|
|
594776
595017
|
|
|
594777
595018
|
${primarySessionContext}`);
|
|
594778
|
-
const workspaceContext = this.buildTelegramWorkspaceContext(modelTier, profile
|
|
595019
|
+
const workspaceContext = this.buildTelegramWorkspaceContext(modelTier, this.telegramWorkspaceBudget(profile));
|
|
594779
595020
|
if (workspaceContext) sections.push(`## Workspace Context
|
|
594780
595021
|
|
|
594781
595022
|
${workspaceContext}`);
|
|
@@ -595096,6 +595337,20 @@ Join: ${newUrl}`);
|
|
|
595096
595337
|
}
|
|
595097
595338
|
const existing = this.subAgents.get(sessionKey);
|
|
595098
595339
|
if (existing && !existing.aborted) {
|
|
595340
|
+
const isGroup = msg.chatType !== "private";
|
|
595341
|
+
if (isGroup) {
|
|
595342
|
+
this.recordTelegramUserMessage(msg, "ambient");
|
|
595343
|
+
const decision2 = await this.inferTelegramInteractionDecision(msg, existing.toolContext || toolContext);
|
|
595344
|
+
this.markLastTelegramUserMessageMode(msg, decision2.shouldReply ? "steering" : "ambient");
|
|
595345
|
+
this.subAgentViewCallbacks?.onWrite(
|
|
595346
|
+
existing.viewId,
|
|
595347
|
+
`live steering: ${decision2.shouldReply ? decision2.route : "no_reply"} (${decision2.source}, confidence ${decision2.confidence.toFixed(2)}): ${decision2.reason}`
|
|
595348
|
+
);
|
|
595349
|
+
if (!decision2.shouldReply) {
|
|
595350
|
+
this.maybeLogTelegramGroupSkip(msg, `live inference: no steering — ${decision2.reason}`);
|
|
595351
|
+
return;
|
|
595352
|
+
}
|
|
595353
|
+
}
|
|
595099
595354
|
let steeringText = msg.text;
|
|
595100
595355
|
if (msg.media) {
|
|
595101
595356
|
const mediaContext = await this.processMedia(msg);
|
|
@@ -595106,7 +595361,11 @@ Join: ${newUrl}`);
|
|
|
595106
595361
|
${mediaContext}`;
|
|
595107
595362
|
}
|
|
595108
595363
|
}
|
|
595109
|
-
|
|
595364
|
+
if (isGroup) {
|
|
595365
|
+
this.markLastTelegramUserMessageMode(msg, "steering");
|
|
595366
|
+
} else {
|
|
595367
|
+
this.recordTelegramUserMessage(msg, "steering", steeringText);
|
|
595368
|
+
}
|
|
595110
595369
|
if (existing.runner) {
|
|
595111
595370
|
existing.runner.injectUserMessage(steeringText);
|
|
595112
595371
|
this.tuiWrite(() => renderTelegramSubAgentEvent(msg.username, "mid-conversation steering injected"));
|
|
@@ -595172,7 +595431,8 @@ ${mediaContext}`;
|
|
|
595172
595431
|
clearInterval(subAgent.typingInterval);
|
|
595173
595432
|
subAgent.typingInterval = null;
|
|
595174
595433
|
}
|
|
595175
|
-
|
|
595434
|
+
const finalText = cleanTelegramVisibleReply(result || "");
|
|
595435
|
+
if (!finalText) {
|
|
595176
595436
|
if (msg.chatType !== "private") {
|
|
595177
595437
|
this.maybeLogTelegramGroupSkip(msg, "discretion: skipped reply");
|
|
595178
595438
|
} else {
|
|
@@ -595186,20 +595446,10 @@ ${mediaContext}`;
|
|
|
595186
595446
|
}
|
|
595187
595447
|
return;
|
|
595188
595448
|
}
|
|
595189
|
-
const finalText = stripTelegramHiddenThinking(result || "").trim();
|
|
595190
595449
|
if (subAgent.liveMessagePromise) {
|
|
595191
595450
|
await subAgent.liveMessagePromise.catch(() => {
|
|
595192
595451
|
});
|
|
595193
595452
|
}
|
|
595194
|
-
if (!finalText) {
|
|
595195
|
-
if (subAgent.liveMessageId && !msg.guestQueryId) {
|
|
595196
|
-
await this.deleteLiveMessage(msg.chatId, subAgent.liveMessageId).catch(() => {
|
|
595197
|
-
});
|
|
595198
|
-
}
|
|
595199
|
-
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, "completed: no model reply");
|
|
595200
|
-
this.subAgentViewCallbacks?.onStatus(subAgent.viewId, "completed");
|
|
595201
|
-
return;
|
|
595202
|
-
}
|
|
595203
595453
|
this.recordTelegramAssistantMessage(msg, finalText, "action");
|
|
595204
595454
|
const finalHtml = convertMarkdownToTelegramHTML(finalText);
|
|
595205
595455
|
await this.sendOrEditFinalTelegramHTML(msg, finalHtml, subAgent.liveMessageId);
|
|
@@ -595280,7 +595530,7 @@ ${mediaContext}`;
|
|
|
595280
595530
|
clearInterval(subAgent.typingInterval);
|
|
595281
595531
|
subAgent.typingInterval = null;
|
|
595282
595532
|
}
|
|
595283
|
-
const finalText =
|
|
595533
|
+
const finalText = cleanTelegramVisibleReply(result || "");
|
|
595284
595534
|
if (subAgent.liveMessagePromise) {
|
|
595285
595535
|
await subAgent.liveMessagePromise.catch(() => {
|
|
595286
595536
|
});
|
|
@@ -595370,10 +595620,12 @@ ${mediaContext}`;
|
|
|
595370
595620
|
}
|
|
595371
595621
|
if (liveMessageId && !msg.guestQueryId && now - lastEditMs > 900) {
|
|
595372
595622
|
lastEditMs = now;
|
|
595623
|
+
const html = renderTelegramLiveProgressHTML(progressLines, accumulated);
|
|
595624
|
+
if (!html.trim()) return;
|
|
595373
595625
|
await this.editLiveMessage(
|
|
595374
595626
|
msg.chatId,
|
|
595375
595627
|
liveMessageId,
|
|
595376
|
-
|
|
595628
|
+
html
|
|
595377
595629
|
).catch(() => {
|
|
595378
595630
|
});
|
|
595379
595631
|
} else if (!liveMessageId && !liveMessagePromise && !msg.guestQueryId) {
|
|
@@ -595399,7 +595651,7 @@ ${mediaContext}`;
|
|
|
595399
595651
|
clearInterval(typingInterval);
|
|
595400
595652
|
typingInterval = null;
|
|
595401
595653
|
}
|
|
595402
|
-
const cleaned =
|
|
595654
|
+
const cleaned = cleanTelegramVisibleReply(finalText || accumulated);
|
|
595403
595655
|
const pendingLiveMessage = liveMessagePromise;
|
|
595404
595656
|
if (pendingLiveMessage) {
|
|
595405
595657
|
await pendingLiveMessage.catch(() => {
|
|
@@ -595452,7 +595704,7 @@ ${mediaContext}`;
|
|
|
595452
595704
|
isGroup ? 44 : 24
|
|
595453
595705
|
);
|
|
595454
595706
|
const safety = isAdminDM ? "Admin private DM. The user is trusted, but quick-chat mode still has no tool access." : isAdminGroup ? ADMIN_GROUP_PROMPT : TELEGRAM_SAFETY_PROMPT;
|
|
595455
|
-
const groupHint = isGroup ? `Telegram group: ${msg.chatTitle || "unknown"}.
|
|
595707
|
+
const groupHint = isGroup ? `Telegram group: ${msg.chatTitle || "unknown"}. The live router selected this turn as reply-worthy; keep the reply short and relevant. Never output a skip decision, no_reply marker, memory-stage note, or completion status.` : "Telegram private chat.";
|
|
595456
595708
|
const runtime = buildTelegramRuntimeContext(/* @__PURE__ */ new Date());
|
|
595457
595709
|
const messages2 = [
|
|
595458
595710
|
{
|
|
@@ -595523,6 +595775,7 @@ ${mediaContext}` : ""}`
|
|
|
595523
595775
|
const isGroup = msg.chatType !== "private";
|
|
595524
595776
|
const creativeWorkspace = subAgent.creativeWorkspaceRoot ? formatTelegramCreativeWorkspacePrompt(subAgent.creativeWorkspaceRoot) : "";
|
|
595525
595777
|
const sessionContext = this.buildTelegramSessionContext(msg, ctx3, profile, modelTier);
|
|
595778
|
+
const contextWindowSize = this.contextWindowSize;
|
|
595526
595779
|
const backend = new OllamaAgenticBackend(
|
|
595527
595780
|
config.backendUrl,
|
|
595528
595781
|
config.model,
|
|
@@ -595534,7 +595787,8 @@ ${mediaContext}` : ""}`
|
|
|
595534
595787
|
temperature: 0.3,
|
|
595535
595788
|
requestTimeoutMs: config.timeoutMs,
|
|
595536
595789
|
taskTimeoutMs: isAdminDM ? config.timeoutMs * 3 : config.timeoutMs,
|
|
595537
|
-
compactionThreshold: modelTier
|
|
595790
|
+
compactionThreshold: this.telegramFallbackCompactionThreshold(modelTier),
|
|
595791
|
+
contextWindowSize,
|
|
595538
595792
|
modelTier,
|
|
595539
595793
|
streamEnabled: true,
|
|
595540
595794
|
dynamicContext: sessionContext.context,
|
|
@@ -595567,7 +595821,7 @@ ${mediaContext}` : ""}`
|
|
|
595567
595821
|
}
|
|
595568
595822
|
} else if (event.type === "status" && event.content) {
|
|
595569
595823
|
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, `status: ${event.content}`);
|
|
595570
|
-
} else if (event.type === "assistant_text" && event.content) {
|
|
595824
|
+
} else if (event.type === "assistant_text" && event.content && event.source !== "task_complete_summary") {
|
|
595571
595825
|
subAgent.assistantText = event.content;
|
|
595572
595826
|
} else if (event.type === "stream_end" && event.content) {
|
|
595573
595827
|
subAgent.streamText = event.content;
|
|
@@ -595642,7 +595896,7 @@ ${toolHint}
|
|
|
595642
595896
|
Telegram message from @${msg.username}${chatLabel}:
|
|
595643
595897
|
${msg.text}
|
|
595644
595898
|
|
|
595645
|
-
Respond concisely and safely.`;
|
|
595899
|
+
Respond concisely and safely. Send the actual chat reply, not router/status/completion commentary.`;
|
|
595646
595900
|
}
|
|
595647
595901
|
if (mediaContext) {
|
|
595648
595902
|
userPrompt += `
|
|
@@ -595671,11 +595925,11 @@ ${creativeWorkspace}` : ""}`;
|
|
|
595671
595925
|
buildSubAgentTools(context2, repoRoot, chatId, todoSessionId) {
|
|
595672
595926
|
const taskComplete = {
|
|
595673
595927
|
name: "task_complete",
|
|
595674
|
-
description: "Internal completion signal for Telegram runs. Put the actual user-facing reply in assistant text before calling this. Use summary 'no_reply' only to silently skip responding.",
|
|
595928
|
+
description: "Internal completion signal for Telegram runs. Put the actual user-facing reply in assistant text before calling this. Use summary 'no_reply' only to silently skip responding; never write that sentinel as assistant text.",
|
|
595675
595929
|
parameters: {
|
|
595676
595930
|
type: "object",
|
|
595677
595931
|
properties: {
|
|
595678
|
-
summary: { type: "string", description: "Internal completion note, or 'no_reply' to skip when no assistant reply should be sent" }
|
|
595932
|
+
summary: { type: "string", description: "Internal completion note, or 'no_reply' to skip when no assistant reply should be sent. This is never shown directly to Telegram." }
|
|
595679
595933
|
},
|
|
595680
595934
|
required: ["summary"]
|
|
595681
595935
|
},
|
|
@@ -595778,6 +596032,13 @@ ${creativeWorkspace}` : ""}`;
|
|
|
595778
596032
|
fullSubAgentTool
|
|
595779
596033
|
];
|
|
595780
596034
|
const allTools = context2 === "telegram-admin-dm" ? adminTools : sharedReadMemoryWebTools;
|
|
596035
|
+
if (this.contextWindowSize > 0) {
|
|
596036
|
+
for (const tool of allTools) {
|
|
596037
|
+
if ("setContextWindowSize" in tool && typeof tool.setContextWindowSize === "function") {
|
|
596038
|
+
tool.setContextWindowSize(this.contextWindowSize);
|
|
596039
|
+
}
|
|
596040
|
+
}
|
|
596041
|
+
}
|
|
595781
596042
|
let adaptedTools = allTools.map((tool) => adaptTool5(tool, todoSessionId));
|
|
595782
596043
|
adaptedTools = applyToolPolicy(adaptedTools, context2, this.toolPolicyConfig);
|
|
595783
596044
|
if (context2 !== "telegram-admin-dm") {
|
|
@@ -624050,6 +624311,7 @@ ${result.summary}`
|
|
|
624050
624311
|
resolvedContextWindowSize = ctxSize;
|
|
624051
624312
|
statusBar.setContextWindowSize(ctxSize);
|
|
624052
624313
|
setActiveTaskContextWindowSize(ctxSize);
|
|
624314
|
+
telegramBridge?.setContextWindowSize(ctxSize);
|
|
624053
624315
|
}
|
|
624054
624316
|
}).catch(() => {
|
|
624055
624317
|
});
|
|
@@ -624977,8 +625239,12 @@ This is an independent background session started from /background.`
|
|
|
624977
625239
|
await new Promise((r3) => setTimeout(r3, 5e3));
|
|
624978
625240
|
return _tryNexusConnect(attempt + 1);
|
|
624979
625241
|
}
|
|
625242
|
+
const nexusLogPath = join136(repoRoot, ".omnius", "nexus", "daemon.err");
|
|
625243
|
+
const visibleOut = out.length > 1200 ? `${out.slice(0, 1200)}...` : out;
|
|
624980
625244
|
writeContent(
|
|
624981
|
-
() => renderWarning(`Nexus auto-connect failed:
|
|
625245
|
+
() => renderWarning(`Nexus auto-connect failed:
|
|
625246
|
+
${visibleOut}
|
|
625247
|
+
Log: ${nexusLogPath}`)
|
|
624982
625248
|
);
|
|
624983
625249
|
} else if (out.includes("still connecting") || out.includes("spawned")) {
|
|
624984
625250
|
for (let i2 = 0; i2 < 30; i2++) {
|
|
@@ -625974,6 +626240,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
625974
626240
|
currentConfig,
|
|
625975
626241
|
repoRoot
|
|
625976
626242
|
);
|
|
626243
|
+
if (resolvedContextWindowSize > 0) {
|
|
626244
|
+
telegramBridge.setContextWindowSize(resolvedContextWindowSize);
|
|
626245
|
+
}
|
|
625977
626246
|
telegramBridge.setInteractionMode(savedSettings.telegramMode ?? "auto");
|
|
625978
626247
|
if (adminId) {
|
|
625979
626248
|
telegramBridge.setAdmin(adminId);
|
|
@@ -626015,7 +626284,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
626015
626284
|
}
|
|
626016
626285
|
});
|
|
626017
626286
|
telegramBridge.setOnSubAgentEvent((chatId, username, event) => {
|
|
626018
|
-
if (event.type === "tool_call" && event.toolName) {
|
|
626287
|
+
if (event.type === "tool_call" && event.toolName && event.toolName !== "task_complete") {
|
|
626019
626288
|
const argsPreview = event.toolArgs ? JSON.stringify(event.toolArgs).slice(0, 60) : "";
|
|
626020
626289
|
writeContent(
|
|
626021
626290
|
() => renderTelegramSubAgentToolCall(
|
|
@@ -626024,7 +626293,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
626024
626293
|
argsPreview
|
|
626025
626294
|
)
|
|
626026
626295
|
);
|
|
626027
|
-
} else if (event.type === "status" && event.content) {
|
|
626296
|
+
} else if (event.type === "status" && event.content && process.env["OMNIUS_TELEGRAM_DEBUG_STATUS"] === "1") {
|
|
626028
626297
|
writeContent(
|
|
626029
626298
|
() => renderTelegramSubAgentEvent(username, event.content)
|
|
626030
626299
|
);
|
|
@@ -626728,7 +626997,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
626728
626997
|
},
|
|
626729
626998
|
onAgentSpeech(text) {
|
|
626730
626999
|
writeContent(
|
|
626731
|
-
() => renderInfo(`\x1B[38;5;
|
|
627000
|
+
() => renderInfo(`\x1B[38;5;37m[agent]\x1B[0m ${text.slice(0, 120)}`)
|
|
626732
627001
|
);
|
|
626733
627002
|
},
|
|
626734
627003
|
// Keep state changes silent
|
|
@@ -627042,6 +627311,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
627042
627311
|
setContextWindowSize: (size) => {
|
|
627043
627312
|
resolvedContextWindowSize = size;
|
|
627044
627313
|
statusBar.setContextWindowSize(size);
|
|
627314
|
+
telegramBridge?.setContextWindowSize(size);
|
|
627045
627315
|
},
|
|
627046
627316
|
setCapabilities: (caps) => {
|
|
627047
627317
|
resolvedCaps = caps;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.5",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED