omnius 1.0.120 → 1.0.127
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 +293 -116
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -553442,14 +553442,29 @@ ${description}`
|
|
|
553442
553442
|
poolSlot.release(success);
|
|
553443
553443
|
poolSlot = null;
|
|
553444
553444
|
};
|
|
553445
|
+
const streamTimeoutMs = Number.isFinite(request.timeoutMs) && request.timeoutMs > 0 ? Math.max(request.timeoutMs, 1e4) : 3e5;
|
|
553446
|
+
const streamAbort = new AbortController();
|
|
553447
|
+
const streamTimeoutHandle = setTimeout(() => {
|
|
553448
|
+
streamAbort.abort(new Error(`stream timeout: no response or chunk within ${(streamTimeoutMs / 1e3).toFixed(0)}s`));
|
|
553449
|
+
}, streamTimeoutMs);
|
|
553450
|
+
if (typeof streamTimeoutHandle.unref === "function") {
|
|
553451
|
+
streamTimeoutHandle.unref();
|
|
553452
|
+
}
|
|
553453
|
+
const externalAbortListener = this._abortSignal ? () => streamAbort.abort(this._abortSignal?.reason ?? new Error("external abort")) : null;
|
|
553454
|
+
if (this._abortSignal && externalAbortListener) {
|
|
553455
|
+
if (this._abortSignal.aborted) {
|
|
553456
|
+
externalAbortListener();
|
|
553457
|
+
} else {
|
|
553458
|
+
this._abortSignal.addEventListener("abort", externalAbortListener, { once: true });
|
|
553459
|
+
}
|
|
553460
|
+
}
|
|
553445
553461
|
try {
|
|
553446
553462
|
const streamFetchOpts = {
|
|
553447
553463
|
method: "POST",
|
|
553448
553464
|
headers: this.authHeaders(),
|
|
553449
|
-
body: JSON.stringify(body)
|
|
553465
|
+
body: JSON.stringify(body),
|
|
553466
|
+
signal: streamAbort.signal
|
|
553450
553467
|
};
|
|
553451
|
-
if (this._abortSignal)
|
|
553452
|
-
streamFetchOpts.signal = this._abortSignal;
|
|
553453
553468
|
let resp = await fetch(`${requestBaseUrl}/v1/chat/completions`, streamFetchOpts);
|
|
553454
553469
|
if (!resp.ok) {
|
|
553455
553470
|
const text = await resp.text().catch(() => "");
|
|
@@ -553548,6 +553563,13 @@ ${description}`
|
|
|
553548
553563
|
this._finalizeStreamGuard(effectiveThink, accumulatedContent, accumulatedThinking, sawReasoningTokens);
|
|
553549
553564
|
poolSuccess = true;
|
|
553550
553565
|
} finally {
|
|
553566
|
+
clearTimeout(streamTimeoutHandle);
|
|
553567
|
+
if (this._abortSignal && externalAbortListener) {
|
|
553568
|
+
try {
|
|
553569
|
+
this._abortSignal.removeEventListener("abort", externalAbortListener);
|
|
553570
|
+
} catch {
|
|
553571
|
+
}
|
|
553572
|
+
}
|
|
553551
553573
|
releasePoolSlot(poolSuccess);
|
|
553552
553574
|
}
|
|
553553
553575
|
}
|
|
@@ -558131,7 +558153,7 @@ function ensureVenvForTranscribeCli() {
|
|
|
558131
558153
|
}
|
|
558132
558154
|
}
|
|
558133
558155
|
function ensureTranscribeCliBackground() {
|
|
558134
|
-
if (_bgInstallPromise) return;
|
|
558156
|
+
if (_bgInstallPromise) return _bgInstallPromise;
|
|
558135
558157
|
_bgInstallPromise = (async () => {
|
|
558136
558158
|
try {
|
|
558137
558159
|
const globalRoot = execSync46("npm root -g", {
|
|
@@ -558155,6 +558177,7 @@ function ensureTranscribeCliBackground() {
|
|
|
558155
558177
|
return false;
|
|
558156
558178
|
}
|
|
558157
558179
|
})();
|
|
558180
|
+
return _bgInstallPromise;
|
|
558158
558181
|
}
|
|
558159
558182
|
async function waitForTranscribeCli() {
|
|
558160
558183
|
if (_bgInstallPromise) {
|
|
@@ -579896,6 +579919,158 @@ function ensurePythonVenv() {
|
|
|
579896
579919
|
}
|
|
579897
579920
|
process.stdout.write(` ${c3.cyan("⚠")} Could not install python3-venv. Install manually: sudo apt install python3-venv
|
|
579898
579921
|
|
|
579922
|
+
`);
|
|
579923
|
+
}
|
|
579924
|
+
async function pretuiSudoPasswordCallback(rl) {
|
|
579925
|
+
process.stdout.write(` ${c3.dim("Some dependencies need administrator access to install system packages.")}
|
|
579926
|
+
`);
|
|
579927
|
+
const pw2 = await askSecret(rl, ` ${c3.bold("sudo password")} ${c3.dim("(empty to skip this dep)")}: `);
|
|
579928
|
+
if (!pw2) {
|
|
579929
|
+
process.stdout.write(` ${c3.dim("Skipped — install can be re-attempted later via /vision-status or by re-running omnius setup.")}
|
|
579930
|
+
|
|
579931
|
+
`);
|
|
579932
|
+
return null;
|
|
579933
|
+
}
|
|
579934
|
+
return pw2;
|
|
579935
|
+
}
|
|
579936
|
+
async function runOptionalDepsSetup(rl) {
|
|
579937
|
+
const canPrompt = process.stdout.isTTY && process.stdin.isTTY && process.env["CI"] !== "true" && process.env["OMNIUS_SETUP_AUTO_CONTINUE"] !== "1";
|
|
579938
|
+
if (!canPrompt) {
|
|
579939
|
+
process.stdout.write(` ${c3.dim("Non-interactive mode — skipping optional dependency prompts.")}
|
|
579940
|
+
|
|
579941
|
+
`);
|
|
579942
|
+
return;
|
|
579943
|
+
}
|
|
579944
|
+
const logTo = (label) => (msg) => {
|
|
579945
|
+
process.stdout.write(` ${c3.dim(`[${label}]`)} ${msg}
|
|
579946
|
+
`);
|
|
579947
|
+
};
|
|
579948
|
+
process.stdout.write(` ${c3.bold("Optional dependencies")}
|
|
579949
|
+
`);
|
|
579950
|
+
process.stdout.write(` ${c3.dim("These add features (vision/OCR, voice tunnel, live transcription). You can install them now or later via the in-TUI commands.")}
|
|
579951
|
+
|
|
579952
|
+
`);
|
|
579953
|
+
const askVision = await ask(rl, ` ${c3.bold("Install vision / OCR deps?")} (Y/n) `);
|
|
579954
|
+
if (askVision.toLowerCase() !== "n") {
|
|
579955
|
+
process.stdout.write(` ${c3.cyan("●")} Installing vision + OCR deps...
|
|
579956
|
+
`);
|
|
579957
|
+
try {
|
|
579958
|
+
await ensureVisionDeps(
|
|
579959
|
+
logTo("vision"),
|
|
579960
|
+
() => pretuiSudoPasswordCallback(rl)
|
|
579961
|
+
);
|
|
579962
|
+
process.stdout.write(` ${c3.green("✔")} Vision deps complete.
|
|
579963
|
+
|
|
579964
|
+
`);
|
|
579965
|
+
} catch (err) {
|
|
579966
|
+
process.stdout.write(` ${c3.cyan("⚠")} Vision deps install hit an error: ${err instanceof Error ? err.message : String(err)}
|
|
579967
|
+
`);
|
|
579968
|
+
process.stdout.write(` ${c3.dim("Continuing — vision features may be limited.")}
|
|
579969
|
+
|
|
579970
|
+
`);
|
|
579971
|
+
}
|
|
579972
|
+
} else {
|
|
579973
|
+
process.stdout.write(` ${c3.dim("Skipped vision deps.")}
|
|
579974
|
+
|
|
579975
|
+
`);
|
|
579976
|
+
}
|
|
579977
|
+
const askCloudflared = await ask(rl, ` ${c3.bold("Install cloudflared for voice tunnel?")} (Y/n) `);
|
|
579978
|
+
if (askCloudflared.toLowerCase() !== "n") {
|
|
579979
|
+
process.stdout.write(` ${c3.cyan("●")} Installing cloudflared...
|
|
579980
|
+
`);
|
|
579981
|
+
const ok3 = await ensureCloudflaredBackground((msg) => {
|
|
579982
|
+
process.stdout.write(` ${c3.dim("[cloudflared]")} ${msg}
|
|
579983
|
+
`);
|
|
579984
|
+
});
|
|
579985
|
+
if (ok3) {
|
|
579986
|
+
process.stdout.write(` ${c3.green("✔")} Cloudflared ready.
|
|
579987
|
+
|
|
579988
|
+
`);
|
|
579989
|
+
} else {
|
|
579990
|
+
process.stdout.write(` ${c3.cyan("⚠")} Cloudflared install did not complete — voice tunnel will be unavailable.
|
|
579991
|
+
|
|
579992
|
+
`);
|
|
579993
|
+
}
|
|
579994
|
+
} else {
|
|
579995
|
+
process.stdout.write(` ${c3.dim("Skipped cloudflared.")}
|
|
579996
|
+
|
|
579997
|
+
`);
|
|
579998
|
+
}
|
|
579999
|
+
const askTranscribe = await ask(rl, ` ${c3.bold("Install transcribe-cli for live transcription?")} (Y/n) `);
|
|
580000
|
+
if (askTranscribe.toLowerCase() !== "n") {
|
|
580001
|
+
process.stdout.write(` ${c3.cyan("●")} Installing transcribe-cli (npm i -g transcribe-cli)...
|
|
580002
|
+
`);
|
|
580003
|
+
try {
|
|
580004
|
+
const ok3 = await ensureTranscribeCliBackground();
|
|
580005
|
+
if (ok3) {
|
|
580006
|
+
process.stdout.write(` ${c3.green("✔")} Transcribe-CLI installed.
|
|
580007
|
+
|
|
580008
|
+
`);
|
|
580009
|
+
} else {
|
|
580010
|
+
process.stdout.write(` ${c3.cyan("⚠")} transcribe-cli install did not complete — live transcription will be unavailable.
|
|
580011
|
+
|
|
580012
|
+
`);
|
|
580013
|
+
}
|
|
580014
|
+
} catch (err) {
|
|
580015
|
+
process.stdout.write(` ${c3.cyan("⚠")} transcribe-cli install hit an error: ${err instanceof Error ? err.message : String(err)}
|
|
580016
|
+
|
|
580017
|
+
`);
|
|
580018
|
+
}
|
|
580019
|
+
} else {
|
|
580020
|
+
process.stdout.write(` ${c3.dim("Skipped transcribe-cli.")}
|
|
580021
|
+
|
|
580022
|
+
`);
|
|
580023
|
+
}
|
|
580024
|
+
}
|
|
580025
|
+
function writeSetupIncompleteWalkthrough(cc) {
|
|
580026
|
+
process.stdout.write(`
|
|
580027
|
+
${cc.bold("Setup incomplete — no model configured.")}
|
|
580028
|
+
`);
|
|
580029
|
+
process.stdout.write(` ${cc.dim("Nothing was saved. The primary TUI was NOT started so you can finish setup on your terms.")}
|
|
580030
|
+
|
|
580031
|
+
`);
|
|
580032
|
+
process.stdout.write(` ${cc.bold("To finish setup, pick one of:")}
|
|
580033
|
+
|
|
580034
|
+
`);
|
|
580035
|
+
process.stdout.write(` ${cc.cyan("1.")} ${cc.bold("Use a local Ollama model")}
|
|
580036
|
+
`);
|
|
580037
|
+
process.stdout.write(` ${cc.dim("# install / start Ollama")}
|
|
580038
|
+
`);
|
|
580039
|
+
process.stdout.write(` curl -fsSL https://ollama.com/install.sh | sh
|
|
580040
|
+
`);
|
|
580041
|
+
process.stdout.write(` ollama serve &
|
|
580042
|
+
`);
|
|
580043
|
+
process.stdout.write(` ${cc.dim("# pull a tool-capable model (any of these works)")}
|
|
580044
|
+
`);
|
|
580045
|
+
process.stdout.write(` ollama pull qwen3.6:35b ${cc.dim("# recommended on a 32GB+ VRAM rig")}
|
|
580046
|
+
`);
|
|
580047
|
+
process.stdout.write(` ollama pull qwen3.5:9b ${cc.dim("# smaller fallback")}
|
|
580048
|
+
`);
|
|
580049
|
+
process.stdout.write(` ${cc.dim("# then re-run setup")}
|
|
580050
|
+
`);
|
|
580051
|
+
process.stdout.write(` omnius
|
|
580052
|
+
|
|
580053
|
+
`);
|
|
580054
|
+
process.stdout.write(` ${cc.cyan("2.")} ${cc.bold("Use a remote OpenAI-compatible endpoint")}
|
|
580055
|
+
`);
|
|
580056
|
+
process.stdout.write(` omnius config set backendUrl https://api.example.com/v1
|
|
580057
|
+
`);
|
|
580058
|
+
process.stdout.write(` omnius config set model your-model-name
|
|
580059
|
+
`);
|
|
580060
|
+
process.stdout.write(` omnius config set apiKey sk-...
|
|
580061
|
+
`);
|
|
580062
|
+
process.stdout.write(` omnius config set backendType vllm
|
|
580063
|
+
`);
|
|
580064
|
+
process.stdout.write(` omnius
|
|
580065
|
+
|
|
580066
|
+
`);
|
|
580067
|
+
process.stdout.write(` ${cc.cyan("3.")} ${cc.bold("Open the setup wizard again")}
|
|
580068
|
+
`);
|
|
580069
|
+
process.stdout.write(` omnius setup ${cc.dim("# explicit re-entry")}
|
|
580070
|
+
|
|
580071
|
+
`);
|
|
580072
|
+
process.stdout.write(` ${cc.dim("Docs: ")}${cc.bold("https://github.com/<repo>/blob/main/README.md")}${cc.dim(' — "Quickstart"')}
|
|
580073
|
+
|
|
579899
580074
|
`);
|
|
579900
580075
|
}
|
|
579901
580076
|
async function runSetupWizard(config) {
|
|
@@ -580108,6 +580283,13 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580108
580283
|
}
|
|
580109
580284
|
process.stdout.write(hLine("└"));
|
|
580110
580285
|
process.stdout.write("\n");
|
|
580286
|
+
const canPause = process.stdout.isTTY && process.stdin.isTTY && process.env["CI"] !== "true" && process.env["OMNIUS_SETUP_AUTO_CONTINUE"] !== "1";
|
|
580287
|
+
if (canPause) {
|
|
580288
|
+
process.stdout.write(` ${c3.dim("Review the capability summary above. ")}${c3.bold("Press Enter to continue")}${c3.dim(", or Ctrl+C to exit.")}
|
|
580289
|
+
`);
|
|
580290
|
+
await ask(rl, " > ");
|
|
580291
|
+
process.stdout.write("\n");
|
|
580292
|
+
}
|
|
580111
580293
|
let hasPython = hasCmd("python3") || hasCmd("python");
|
|
580112
580294
|
if (!hasPython) {
|
|
580113
580295
|
process.stdout.write(` ${c3.cyan("⚠")} Python3 not found (needed for vision, OCR, browser automation).
|
|
@@ -580223,6 +580405,21 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580223
580405
|
process.stdout.write(` ${c3.cyan("⚠")} Default model ${c3.bold(config.model)} is not available.
|
|
580224
580406
|
|
|
580225
580407
|
`);
|
|
580408
|
+
if (canPause) {
|
|
580409
|
+
process.stdout.write(` ${c3.bold("Next step:")} ${c3.dim("choose a model.")}
|
|
580410
|
+
`);
|
|
580411
|
+
process.stdout.write(` ${c3.dim("[Enter] open model picker / [s] skip + configure later / [c] custom endpoint")}
|
|
580412
|
+
`);
|
|
580413
|
+
const next = (await ask(rl, " > ")).trim().toLowerCase();
|
|
580414
|
+
if (next === "s" || next === "skip") {
|
|
580415
|
+
writeSetupIncompleteWalkthrough(c3);
|
|
580416
|
+
process.exit(0);
|
|
580417
|
+
}
|
|
580418
|
+
if (next === "c" || next === "custom") {
|
|
580419
|
+
const endpointResult = await promptForCustomEndpoint(config, rl);
|
|
580420
|
+
if (endpointResult) return endpointResult;
|
|
580421
|
+
}
|
|
580422
|
+
}
|
|
580226
580423
|
if (models.length > 0) {
|
|
580227
580424
|
const backendUrl2 = config.backendUrl || "http://localhost:11434";
|
|
580228
580425
|
const modelChecks = await Promise.all(
|
|
@@ -580249,8 +580446,13 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580249
580446
|
${c3.green("✔")} Selected ${c3.bold(selected.name)} — ${mode}. Saved to config.
|
|
580250
580447
|
|
|
580251
580448
|
`);
|
|
580449
|
+
await runOptionalDepsSetup(rl);
|
|
580252
580450
|
return selected.name;
|
|
580253
580451
|
}
|
|
580452
|
+
if (!modelResult.confirmed) {
|
|
580453
|
+
writeSetupIncompleteWalkthrough(c3);
|
|
580454
|
+
process.exit(0);
|
|
580455
|
+
}
|
|
580254
580456
|
} else {
|
|
580255
580457
|
process.stdout.write(` ${c3.cyan("⚠")} No models found on this system.
|
|
580256
580458
|
|
|
@@ -580274,11 +580476,8 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580274
580476
|
});
|
|
580275
580477
|
let selectedVariant;
|
|
580276
580478
|
if (!pullResult.confirmed || !pullResult.key) {
|
|
580277
|
-
|
|
580278
|
-
|
|
580279
|
-
|
|
580280
|
-
`);
|
|
580281
|
-
return config.model;
|
|
580479
|
+
writeSetupIncompleteWalkthrough(c3);
|
|
580480
|
+
process.exit(0);
|
|
580282
580481
|
}
|
|
580283
580482
|
selectedVariant = QWEN_VARIANTS.find((v) => v.tag === pullResult.key) ?? recommended;
|
|
580284
580483
|
process.stdout.write(`
|
|
@@ -580332,6 +580531,7 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580332
580531
|
process.stdout.write(` ${c3.green("✔")} Saved as default model in config.
|
|
580333
580532
|
|
|
580334
580533
|
`);
|
|
580534
|
+
await runOptionalDepsSetup(rl);
|
|
580335
580535
|
return customName;
|
|
580336
580536
|
} catch (err) {
|
|
580337
580537
|
renderWarning(`Could not create custom model: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -580343,6 +580543,7 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580343
580543
|
${c3.green("✔")} Saved ${c3.bold(selectedVariant.tag)} as default model.
|
|
580344
580544
|
|
|
580345
580545
|
`);
|
|
580546
|
+
await runOptionalDepsSetup(rl);
|
|
580346
580547
|
return selectedVariant.tag;
|
|
580347
580548
|
}
|
|
580348
580549
|
setConfigValue("model", selectedVariant.tag);
|
|
@@ -580350,6 +580551,7 @@ ${c3.cyan(OMNIUS_FIRST_RUN_BANNER)}
|
|
|
580350
580551
|
${c3.green("✔")} Saved ${c3.bold(selectedVariant.tag)} as default model.
|
|
580351
580552
|
|
|
580352
580553
|
`);
|
|
580554
|
+
await runOptionalDepsSetup(rl);
|
|
580353
580555
|
return selectedVariant.tag;
|
|
580354
580556
|
}
|
|
580355
580557
|
async function isModelAvailable(config) {
|
|
@@ -580802,10 +581004,10 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
580802
581004
|
}
|
|
580803
581005
|
}
|
|
580804
581006
|
function ensureCloudflaredBackground(onInfo) {
|
|
580805
|
-
if (_cloudflaredInstallPromise) return;
|
|
581007
|
+
if (_cloudflaredInstallPromise) return _cloudflaredInstallPromise;
|
|
580806
581008
|
if (hasCmd("cloudflared")) {
|
|
580807
581009
|
_cloudflaredInstallPromise = Promise.resolve(true);
|
|
580808
|
-
return;
|
|
581010
|
+
return _cloudflaredInstallPromise;
|
|
580809
581011
|
}
|
|
580810
581012
|
const log22 = onInfo ?? (() => {
|
|
580811
581013
|
});
|
|
@@ -580858,6 +581060,7 @@ function ensureCloudflaredBackground(onInfo) {
|
|
|
580858
581060
|
log22("cloudflared not available — live voice sessions disabled.");
|
|
580859
581061
|
return false;
|
|
580860
581062
|
})();
|
|
581063
|
+
return _cloudflaredInstallPromise;
|
|
580861
581064
|
}
|
|
580862
581065
|
async function isCloudflaredReady() {
|
|
580863
581066
|
if (hasCmd("cloudflared")) return true;
|
|
@@ -581367,6 +581570,7 @@ var init_setup = __esm({
|
|
|
581367
581570
|
init_config();
|
|
581368
581571
|
init_dist();
|
|
581369
581572
|
init_tui_select();
|
|
581573
|
+
init_listen();
|
|
581370
581574
|
execAsync2 = promisify6(exec4);
|
|
581371
581575
|
OMNIUS_FIRST_RUN_BANNER = [
|
|
581372
581576
|
" ░▒▓██████▓▒░░▒▓██████████████▓▒░░▒▓███████▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ ",
|
|
@@ -603033,13 +603237,13 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
603033
603237
|
}
|
|
603034
603238
|
if (!hasCf) {
|
|
603035
603239
|
installOverlay.setStatus("Installing cloudflared...");
|
|
603036
|
-
ensureCloudflaredBackground(() => {
|
|
603240
|
+
void ensureCloudflaredBackground(() => {
|
|
603037
603241
|
});
|
|
603038
603242
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
603039
603243
|
} else {
|
|
603040
603244
|
installOverlay.setStatus("cloudflared ready");
|
|
603041
603245
|
}
|
|
603042
|
-
ensureTranscribeCliBackground();
|
|
603246
|
+
void ensureTranscribeCliBackground();
|
|
603043
603247
|
}
|
|
603044
603248
|
if (!primaryUpdated) {
|
|
603045
603249
|
installOverlay.stop("Done — no restart needed");
|
|
@@ -619882,24 +620086,57 @@ ${lines.join("\n")}`);
|
|
|
619882
620086
|
`inference ${inferenceId} [${entry.kind}] ${elapsed}s content=${entry.contentTokens}t thinking=${entry.thinkingTokens}t (${thinkRatio}% think) live=${JSON.stringify(preview)}`
|
|
619883
620087
|
));
|
|
619884
620088
|
};
|
|
619885
|
-
|
|
619886
|
-
|
|
619887
|
-
|
|
619888
|
-
|
|
619889
|
-
|
|
619890
|
-
|
|
619891
|
-
|
|
619892
|
-
|
|
619893
|
-
|
|
619894
|
-
|
|
619895
|
-
|
|
619896
|
-
|
|
619897
|
-
|
|
619898
|
-
|
|
619899
|
-
|
|
619900
|
-
|
|
619901
|
-
|
|
619902
|
-
|
|
620089
|
+
const inactivityMs = this.telegramStreamInactivityMs();
|
|
620090
|
+
const iter = streamFn(request)[Symbol.asyncIterator]();
|
|
620091
|
+
try {
|
|
620092
|
+
while (true) {
|
|
620093
|
+
let timeoutHandle = null;
|
|
620094
|
+
const inactivityPromise = new Promise((_, reject) => {
|
|
620095
|
+
timeoutHandle = setTimeout(
|
|
620096
|
+
() => reject(new Error(
|
|
620097
|
+
`stream-inactivity: no chunks for ${(inactivityMs / 1e3).toFixed(0)}s (content=${contentBuf.length}c thinking=${thinkingBuf.length}c so far) — Ollama likely cold-loading the model or wedged; falling back to non-stream`
|
|
620098
|
+
)),
|
|
620099
|
+
inactivityMs
|
|
620100
|
+
);
|
|
620101
|
+
if (typeof timeoutHandle.unref === "function") {
|
|
620102
|
+
timeoutHandle.unref();
|
|
620103
|
+
}
|
|
620104
|
+
});
|
|
620105
|
+
let next;
|
|
620106
|
+
try {
|
|
620107
|
+
next = await Promise.race([iter.next(), inactivityPromise]);
|
|
620108
|
+
} finally {
|
|
620109
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
620110
|
+
}
|
|
620111
|
+
if (next.done) break;
|
|
620112
|
+
const chunk = next.value;
|
|
620113
|
+
if (chunk.type === "content" && chunk.content) {
|
|
620114
|
+
const entry = this.telegramActiveInferences.get(inferenceId);
|
|
620115
|
+
if (entry && entry.firstChunkAt === void 0) {
|
|
620116
|
+
entry.firstChunkAt = performance.now();
|
|
620117
|
+
}
|
|
620118
|
+
if (chunk.thinking) {
|
|
620119
|
+
thinkingBuf += chunk.content;
|
|
620120
|
+
this.bumpTelegramInferenceTokens(inferenceId, 0, 1);
|
|
620121
|
+
} else {
|
|
620122
|
+
contentBuf += chunk.content;
|
|
620123
|
+
this.bumpTelegramInferenceTokens(inferenceId, 1, 0);
|
|
620124
|
+
}
|
|
620125
|
+
flushPreview(false);
|
|
620126
|
+
} else if (chunk.type === "finish") {
|
|
620127
|
+
finishReason = chunk.finishReason;
|
|
620128
|
+
} else if (chunk.type === "usage") {
|
|
620129
|
+
usage = {
|
|
620130
|
+
prompt_tokens: chunk.promptTokens,
|
|
620131
|
+
completion_tokens: chunk.completionTokens,
|
|
620132
|
+
total_tokens: chunk.totalTokens
|
|
620133
|
+
};
|
|
620134
|
+
}
|
|
620135
|
+
}
|
|
620136
|
+
} finally {
|
|
620137
|
+
try {
|
|
620138
|
+
await iter.return?.(void 0);
|
|
620139
|
+
} catch {
|
|
619903
620140
|
}
|
|
619904
620141
|
}
|
|
619905
620142
|
flushPreview(true);
|
|
@@ -619970,9 +620207,10 @@ ${lines.join("\n")}`);
|
|
|
619970
620207
|
const dur = ((performance.now() - entry.startTs) / 1e3).toFixed(1);
|
|
619971
620208
|
const totalTokens = entry.contentTokens + entry.thinkingTokens;
|
|
619972
620209
|
const ratio = totalTokens > 0 ? Math.round(entry.thinkingTokens * 100 / totalTokens) : 0;
|
|
620210
|
+
const ttfb = entry.firstChunkAt !== void 0 ? `${((entry.firstChunkAt - entry.startTs) / 1e3).toFixed(1)}s` : "never";
|
|
619973
620211
|
this.tuiWrite(() => renderTelegramSubAgentEvent(
|
|
619974
620212
|
entry.sessionKey,
|
|
619975
|
-
`inference ${id} [${entry.kind}] done in ${dur}s — ${entry.contentTokens}t content / ${entry.thinkingTokens}t thinking (${ratio}% think)`
|
|
620213
|
+
`inference ${id} [${entry.kind}] done in ${dur}s (ttfb=${ttfb}) — ${entry.contentTokens}t content / ${entry.thinkingTokens}t thinking (${ratio}% think)`
|
|
619976
620214
|
));
|
|
619977
620215
|
}
|
|
619978
620216
|
}
|
|
@@ -619988,7 +620226,10 @@ ${lines.join("\n")}`);
|
|
|
619988
620226
|
return Array.from(this.telegramActiveInferences.values()).map((e2) => ({
|
|
619989
620227
|
...e2,
|
|
619990
620228
|
elapsedSec: (now - e2.startTs) / 1e3,
|
|
619991
|
-
idleSec: (now - e2.lastTokenAt) / 1e3
|
|
620229
|
+
idleSec: (now - e2.lastTokenAt) / 1e3,
|
|
620230
|
+
// Undefined when no chunk has arrived yet (still cold-loading or wedged).
|
|
620231
|
+
// A dashboard renderer should display "—" or "waiting" in that case.
|
|
620232
|
+
ttfbSec: e2.firstChunkAt !== void 0 ? (e2.firstChunkAt - e2.startTs) / 1e3 : void 0
|
|
619992
620233
|
}));
|
|
619993
620234
|
}
|
|
619994
620235
|
/**
|
|
@@ -620260,6 +620501,25 @@ ${retryText}`,
|
|
|
620260
620501
|
telegramSubAgentWatchdogIntervalMs() {
|
|
620261
620502
|
return 3e4;
|
|
620262
620503
|
}
|
|
620504
|
+
/**
|
|
620505
|
+
* Per-chunk inactivity window for the bridge's stream consumer. If no
|
|
620506
|
+
* chunk arrives within this window, the streaming consumer in
|
|
620507
|
+
* streamTelegramInferenceToCompletion aborts via Promise.race + clears
|
|
620508
|
+
* the iterator, and telegramObservableInference falls back to the
|
|
620509
|
+
* non-streaming chatCompletion path. This gives operators a clean
|
|
620510
|
+
* "stream silent for 60s, falling back" signal instead of the opaque
|
|
620511
|
+
* 180s coalescer hard-deadline.
|
|
620512
|
+
*
|
|
620513
|
+
* Default 60s — comfortably longer than a healthy cold-load of a 35B
|
|
620514
|
+
* model on a warm VRAM cache (typically <30s) but short enough to
|
|
620515
|
+
* surface a real wedge before the 180s coalescer fires. Override via
|
|
620516
|
+
* OMNIUS_TG_STREAM_INACTIVITY_MS (clamped to [10s, 5min]).
|
|
620517
|
+
*/
|
|
620518
|
+
telegramStreamInactivityMs() {
|
|
620519
|
+
const raw = Number.parseInt(process.env["OMNIUS_TG_STREAM_INACTIVITY_MS"] ?? "", 10);
|
|
620520
|
+
if (Number.isFinite(raw) && raw >= 1e4 && raw <= 3e5) return raw;
|
|
620521
|
+
return 6e4;
|
|
620522
|
+
}
|
|
620263
620523
|
/**
|
|
620264
620524
|
* Start the periodic stale-sub-agent reaper. Idempotent — safe to call
|
|
620265
620525
|
* multiple times (no-op if already running). Stopped by stop() and on
|
|
@@ -654316,75 +654576,6 @@ ${result.summary}`
|
|
|
654316
654576
|
const workEvaluator = new WorkEvaluator();
|
|
654317
654577
|
let setupReady = false;
|
|
654318
654578
|
const setupTasks = [];
|
|
654319
|
-
ensureTranscribeCliBackground();
|
|
654320
|
-
ensureCloudflaredBackground((msg) => {
|
|
654321
|
-
if (statusBar?.isActive) {
|
|
654322
|
-
statusBar.beginContentWrite();
|
|
654323
|
-
renderInfo(msg);
|
|
654324
|
-
statusBar.endContentWrite();
|
|
654325
|
-
}
|
|
654326
|
-
});
|
|
654327
|
-
let depSudoResolver = null;
|
|
654328
|
-
let depSudoPromptPending = false;
|
|
654329
|
-
const visionDepsPromise = ensureVisionDeps(
|
|
654330
|
-
(msg) => {
|
|
654331
|
-
if (statusBar?.isActive) {
|
|
654332
|
-
statusBar.beginContentWrite();
|
|
654333
|
-
renderInfo(msg);
|
|
654334
|
-
statusBar.endContentWrite();
|
|
654335
|
-
}
|
|
654336
|
-
},
|
|
654337
|
-
() => new Promise((resolve52) => {
|
|
654338
|
-
depSudoPromptPending = true;
|
|
654339
|
-
if (process.stdout.isTTY) {
|
|
654340
|
-
process.stdout.write("\x1B[?1000l\x1B[?1002l\x1B[?1006l");
|
|
654341
|
-
}
|
|
654342
|
-
const origProvider = statusBar.inputStateProvider;
|
|
654343
|
-
if (statusBar?.isActive) {
|
|
654344
|
-
statusBar.inputStateProvider = () => {
|
|
654345
|
-
const state = origProvider?.() ?? { line: "", cursor: 0 };
|
|
654346
|
-
return { line: "●".repeat(state.line.length), cursor: state.cursor };
|
|
654347
|
-
};
|
|
654348
|
-
}
|
|
654349
|
-
const footerPwPrompt = `\x1B[38;5;198m● password:\x1B[0m `;
|
|
654350
|
-
const prevPromptText = statusBar.promptText;
|
|
654351
|
-
const prevPromptWidth = statusBar.promptWidth;
|
|
654352
|
-
if (statusBar?.isActive) {
|
|
654353
|
-
statusBar.setPromptText(footerPwPrompt, 12);
|
|
654354
|
-
}
|
|
654355
|
-
depSudoResolver = (pw2) => {
|
|
654356
|
-
depSudoPromptPending = false;
|
|
654357
|
-
depSudoResolver = null;
|
|
654358
|
-
if (statusBar?.isActive) {
|
|
654359
|
-
statusBar.inputStateProvider = origProvider ?? (() => ({ line: rl.line ?? "", cursor: rl.cursor ?? 0 }));
|
|
654360
|
-
if (prevPromptText !== void 0 && prevPromptWidth !== void 0) {
|
|
654361
|
-
statusBar.setPromptText(prevPromptText, prevPromptWidth);
|
|
654362
|
-
}
|
|
654363
|
-
}
|
|
654364
|
-
if (process.stdout.isTTY) {
|
|
654365
|
-
process.stdout.write("\x1B[?1002h\x1B[?1006h");
|
|
654366
|
-
}
|
|
654367
|
-
if (pw2) sessionSudoPassword = pw2;
|
|
654368
|
-
resolve52(pw2);
|
|
654369
|
-
};
|
|
654370
|
-
const pwPrompt = `
|
|
654371
|
-
\x1B[5;38;5;198m⚠ Password needed for dependency install\x1B[0m
|
|
654372
|
-
${c3.dim("Type your sudo password below and press Enter. Input is hidden.")}
|
|
654373
|
-
|
|
654374
|
-
`;
|
|
654375
|
-
if (isNeovimActive()) {
|
|
654376
|
-
writeToNeovimOutput(pwPrompt);
|
|
654377
|
-
} else {
|
|
654378
|
-
if (statusBar?.isActive) statusBar.beginContentWrite();
|
|
654379
|
-
process.stdout.write(pwPrompt);
|
|
654380
|
-
if (statusBar?.isActive) statusBar.endContentWrite();
|
|
654381
|
-
if (statusBar?.isActive) statusBar.handleResize();
|
|
654382
|
-
}
|
|
654383
|
-
})
|
|
654384
|
-
).catch(() => {
|
|
654385
|
-
});
|
|
654386
|
-
setupTasks.push(visionDepsPromise.catch(() => {
|
|
654387
|
-
}));
|
|
654388
654579
|
let updateNotified = false;
|
|
654389
654580
|
checkForUpdate(version4).then((updateInfo) => {
|
|
654390
654581
|
if (updateInfo) {
|
|
@@ -658074,20 +658265,6 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
658074
658265
|
};
|
|
658075
658266
|
};
|
|
658076
658267
|
rl.on("line", (line) => {
|
|
658077
|
-
if (depSudoPromptPending && depSudoResolver) {
|
|
658078
|
-
const pw2 = line.trim();
|
|
658079
|
-
depSudoPromptPending = false;
|
|
658080
|
-
const resolver = depSudoResolver;
|
|
658081
|
-
depSudoResolver = null;
|
|
658082
|
-
if (pw2) sessionSudoPassword = pw2;
|
|
658083
|
-
if (statusBar?.isActive) {
|
|
658084
|
-
statusBar.beginContentWrite();
|
|
658085
|
-
renderInfo("🔑 Password received");
|
|
658086
|
-
statusBar.endContentWrite();
|
|
658087
|
-
}
|
|
658088
|
-
resolver(pw2 || null);
|
|
658089
|
-
return;
|
|
658090
|
-
}
|
|
658091
658268
|
if (!setupReady) return;
|
|
658092
658269
|
persistHistoryLine(line);
|
|
658093
658270
|
const input = line.trim();
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.127",
|
|
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.127",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED