open-agents-ai 0.27.0 → 0.28.0
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 +242 -45
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4019,7 +4019,7 @@ function ensureCommand(command) {
|
|
|
4019
4019
|
const result2 = {
|
|
4020
4020
|
available: false,
|
|
4021
4021
|
installed: false,
|
|
4022
|
-
error: `No supported package manager
|
|
4022
|
+
error: `No supported package manager detected \u2014 ${command} unavailable.`
|
|
4023
4023
|
};
|
|
4024
4024
|
_cache.set(command, result2);
|
|
4025
4025
|
return result2;
|
|
@@ -4029,7 +4029,7 @@ function ensureCommand(command) {
|
|
|
4029
4029
|
const result2 = {
|
|
4030
4030
|
available: false,
|
|
4031
4031
|
installed: false,
|
|
4032
|
-
error: `No package for ${command} on ${pm}
|
|
4032
|
+
error: `No package mapping for ${command} on ${pm} \u2014 cannot auto-install.`
|
|
4033
4033
|
};
|
|
4034
4034
|
_cache.set(command, result2);
|
|
4035
4035
|
return result2;
|
|
@@ -6474,6 +6474,17 @@ async function probeStation(endpoint) {
|
|
|
6474
6474
|
}
|
|
6475
6475
|
}
|
|
6476
6476
|
function findStationBinary() {
|
|
6477
|
+
const oaVenvPython = join15(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "python");
|
|
6478
|
+
if (existsSync11(oaVenvPython)) {
|
|
6479
|
+
try {
|
|
6480
|
+
execSync10(`${JSON.stringify(oaVenvPython)} -c "import moondream_station"`, { stdio: "pipe", timeout: 5e3 });
|
|
6481
|
+
return oaVenvPython;
|
|
6482
|
+
} catch {
|
|
6483
|
+
}
|
|
6484
|
+
}
|
|
6485
|
+
const oaVenvBin = join15(process.env["HOME"] || "/root", ".open-agents", "venv", "bin", "moondream-station");
|
|
6486
|
+
if (existsSync11(oaVenvBin))
|
|
6487
|
+
return oaVenvBin;
|
|
6477
6488
|
const thisDir = dirname4(fileURLToPath(import.meta.url));
|
|
6478
6489
|
const localVenvPaths = [
|
|
6479
6490
|
resolve15(thisDir, "../../../../.moondream-venv/bin/python"),
|
|
@@ -14761,62 +14772,220 @@ function isFirstRun() {
|
|
|
14761
14772
|
return true;
|
|
14762
14773
|
}
|
|
14763
14774
|
}
|
|
14764
|
-
|
|
14765
|
-
const log = onInfo ?? (() => {
|
|
14766
|
-
});
|
|
14775
|
+
function hasCmd(cmd) {
|
|
14767
14776
|
try {
|
|
14768
|
-
execSync13(
|
|
14777
|
+
execSync13(`which ${cmd}`, { stdio: "pipe", timeout: 3e3 });
|
|
14778
|
+
return true;
|
|
14769
14779
|
} catch {
|
|
14770
|
-
|
|
14771
|
-
|
|
14772
|
-
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
+
return false;
|
|
14781
|
+
}
|
|
14782
|
+
}
|
|
14783
|
+
function detectPkgManager() {
|
|
14784
|
+
if (hasCmd("apt-get"))
|
|
14785
|
+
return "apt";
|
|
14786
|
+
if (hasCmd("dnf"))
|
|
14787
|
+
return "dnf";
|
|
14788
|
+
if (hasCmd("pacman"))
|
|
14789
|
+
return "pacman";
|
|
14790
|
+
if (hasCmd("brew"))
|
|
14791
|
+
return "brew";
|
|
14792
|
+
return null;
|
|
14793
|
+
}
|
|
14794
|
+
function getVenvDir() {
|
|
14795
|
+
return join22(homedir8(), ".open-agents", "venv");
|
|
14796
|
+
}
|
|
14797
|
+
function hasVenvModule() {
|
|
14798
|
+
try {
|
|
14799
|
+
execSync13("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
|
|
14800
|
+
return true;
|
|
14801
|
+
} catch {
|
|
14802
|
+
return false;
|
|
14803
|
+
}
|
|
14804
|
+
}
|
|
14805
|
+
function ensureVenv(log) {
|
|
14806
|
+
const venvDir = getVenvDir();
|
|
14807
|
+
const venvPip = join22(venvDir, "bin", "pip");
|
|
14808
|
+
if (existsSync15(venvPip))
|
|
14809
|
+
return venvDir;
|
|
14810
|
+
log("Creating Python venv for vision deps...");
|
|
14811
|
+
if (!hasCmd("python3")) {
|
|
14812
|
+
log("python3 not found \u2014 cannot create venv.");
|
|
14813
|
+
return null;
|
|
14814
|
+
}
|
|
14815
|
+
if (!hasVenvModule()) {
|
|
14816
|
+
log("python3 venv module not available \u2014 venv creation skipped.");
|
|
14817
|
+
return null;
|
|
14818
|
+
}
|
|
14819
|
+
try {
|
|
14820
|
+
mkdirSync7(join22(homedir8(), ".open-agents"), { recursive: true });
|
|
14821
|
+
execSync13(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
|
|
14822
|
+
execSync13(`"${join22(venvDir, "bin", "pip")}" install --upgrade pip`, {
|
|
14823
|
+
stdio: "pipe",
|
|
14824
|
+
timeout: 6e4
|
|
14825
|
+
});
|
|
14826
|
+
log("Python venv created at ~/.open-agents/venv");
|
|
14827
|
+
return venvDir;
|
|
14828
|
+
} catch (err) {
|
|
14829
|
+
log(`Failed to create venv: ${err instanceof Error ? err.message : String(err)}`);
|
|
14830
|
+
return null;
|
|
14831
|
+
}
|
|
14832
|
+
}
|
|
14833
|
+
function trySudoPasswordless(cmd, timeoutMs = 12e4) {
|
|
14834
|
+
try {
|
|
14835
|
+
execSync13(`sudo -n ${cmd}`, {
|
|
14836
|
+
stdio: "pipe",
|
|
14837
|
+
timeout: timeoutMs,
|
|
14838
|
+
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
14839
|
+
});
|
|
14840
|
+
return true;
|
|
14841
|
+
} catch {
|
|
14842
|
+
return false;
|
|
14843
|
+
}
|
|
14844
|
+
}
|
|
14845
|
+
function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
14846
|
+
try {
|
|
14847
|
+
execSync13(`sudo -S ${cmd}`, {
|
|
14848
|
+
input: password + "\n",
|
|
14849
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
14850
|
+
timeout: timeoutMs,
|
|
14851
|
+
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
14852
|
+
});
|
|
14853
|
+
return true;
|
|
14854
|
+
} catch {
|
|
14855
|
+
return false;
|
|
14856
|
+
}
|
|
14857
|
+
}
|
|
14858
|
+
async function sudoInstall(cmd, getSudoPassword, log, cachedPasswordRef, timeoutMs = 12e4) {
|
|
14859
|
+
if (cachedPasswordRef.value) {
|
|
14860
|
+
if (runWithSudo(cmd, cachedPasswordRef.value, timeoutMs))
|
|
14861
|
+
return true;
|
|
14862
|
+
}
|
|
14863
|
+
if (trySudoPasswordless(cmd, timeoutMs))
|
|
14864
|
+
return true;
|
|
14865
|
+
const pw = await getSudoPassword();
|
|
14866
|
+
if (pw) {
|
|
14867
|
+
cachedPasswordRef.value = pw;
|
|
14868
|
+
if (runWithSudo(cmd, pw, timeoutMs))
|
|
14869
|
+
return true;
|
|
14870
|
+
log("Authentication failed \u2014 please re-enter password.");
|
|
14871
|
+
const pw2 = await getSudoPassword();
|
|
14872
|
+
if (pw2) {
|
|
14873
|
+
cachedPasswordRef.value = pw2;
|
|
14874
|
+
if (runWithSudo(cmd, pw2, timeoutMs))
|
|
14875
|
+
return true;
|
|
14876
|
+
}
|
|
14877
|
+
}
|
|
14878
|
+
return false;
|
|
14879
|
+
}
|
|
14880
|
+
async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
14881
|
+
const log = onInfo ?? (() => {
|
|
14882
|
+
});
|
|
14883
|
+
const cachedPasswordRef = { value: null };
|
|
14884
|
+
const getPassword = getSudoPassword ?? (() => Promise.resolve(null));
|
|
14885
|
+
if (!hasCmd("tesseract")) {
|
|
14886
|
+
const pm2 = detectPkgManager();
|
|
14887
|
+
if (pm2) {
|
|
14888
|
+
const pkgMap = {
|
|
14889
|
+
apt: { cmd: "apt-get install -y tesseract-ocr", needsSudo: true },
|
|
14890
|
+
dnf: { cmd: "dnf install -y tesseract", needsSudo: true },
|
|
14891
|
+
pacman: { cmd: "pacman -S --noconfirm tesseract", needsSudo: true },
|
|
14892
|
+
brew: { cmd: "brew install tesseract", needsSudo: false }
|
|
14893
|
+
};
|
|
14894
|
+
const pkg = pkgMap[pm2];
|
|
14895
|
+
if (pkg.needsSudo) {
|
|
14896
|
+
log("Installing tesseract-ocr...");
|
|
14897
|
+
const ok = await sudoInstall(pkg.cmd, getPassword, log, cachedPasswordRef);
|
|
14898
|
+
if (ok && hasCmd("tesseract")) {
|
|
14899
|
+
log("tesseract-ocr installed successfully.");
|
|
14900
|
+
} else {
|
|
14901
|
+
log("tesseract-ocr could not be installed \u2014 OCR features will be limited.");
|
|
14902
|
+
}
|
|
14903
|
+
} else {
|
|
14904
|
+
log("Installing tesseract-ocr...");
|
|
14780
14905
|
try {
|
|
14781
|
-
execSync13(cmd, { stdio: "pipe", timeout:
|
|
14782
|
-
|
|
14783
|
-
|
|
14906
|
+
execSync13(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
|
|
14907
|
+
if (hasCmd("tesseract")) {
|
|
14908
|
+
log("tesseract-ocr installed successfully.");
|
|
14909
|
+
} else {
|
|
14910
|
+
log("tesseract-ocr install completed but binary not found \u2014 OCR features will be limited.");
|
|
14911
|
+
}
|
|
14784
14912
|
} catch {
|
|
14913
|
+
log("tesseract-ocr could not be installed \u2014 OCR features will be limited.");
|
|
14785
14914
|
}
|
|
14786
14915
|
}
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
else
|
|
14790
|
-
log("Could not auto-install tesseract (install manually: sudo apt install tesseract-ocr)");
|
|
14791
|
-
} catch {
|
|
14916
|
+
} else {
|
|
14917
|
+
log("No supported package manager detected \u2014 tesseract OCR unavailable.");
|
|
14792
14918
|
}
|
|
14793
14919
|
}
|
|
14794
|
-
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14798
|
-
|
|
14799
|
-
|
|
14800
|
-
|
|
14801
|
-
|
|
14802
|
-
|
|
14803
|
-
|
|
14804
|
-
|
|
14805
|
-
|
|
14920
|
+
const pm = detectPkgManager();
|
|
14921
|
+
if (!hasCmd("pip3") && !hasCmd("pip") && pm) {
|
|
14922
|
+
const pipCmds = {
|
|
14923
|
+
apt: "apt-get install -y python3-pip",
|
|
14924
|
+
dnf: "dnf install -y python3-pip"
|
|
14925
|
+
};
|
|
14926
|
+
const pipCmd = pipCmds[pm];
|
|
14927
|
+
if (pipCmd) {
|
|
14928
|
+
log("Installing python3-pip...");
|
|
14929
|
+
const ok = await sudoInstall(pipCmd, getPassword, log, cachedPasswordRef);
|
|
14930
|
+
if (!ok) {
|
|
14931
|
+
log("python3-pip could not be installed \u2014 moondream-station may be unavailable.");
|
|
14932
|
+
}
|
|
14933
|
+
}
|
|
14934
|
+
}
|
|
14935
|
+
if (hasCmd("python3") && !hasVenvModule() && pm) {
|
|
14936
|
+
const venvCmds = {
|
|
14937
|
+
apt: () => {
|
|
14806
14938
|
try {
|
|
14807
|
-
execSync13(
|
|
14808
|
-
|
|
14809
|
-
break;
|
|
14939
|
+
const pyVer = execSync13(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
14940
|
+
return `apt-get install -y python3-venv python${pyVer}-venv`;
|
|
14810
14941
|
} catch {
|
|
14942
|
+
return "apt-get install -y python3-venv";
|
|
14943
|
+
}
|
|
14944
|
+
},
|
|
14945
|
+
dnf: () => "dnf install -y python3-venv"
|
|
14946
|
+
};
|
|
14947
|
+
const cmdFn = venvCmds[pm];
|
|
14948
|
+
if (cmdFn) {
|
|
14949
|
+
const cmd = cmdFn();
|
|
14950
|
+
if (cmd) {
|
|
14951
|
+
log("Installing python3-venv...");
|
|
14952
|
+
const ok = await sudoInstall(cmd, getPassword, log, cachedPasswordRef);
|
|
14953
|
+
if (!ok) {
|
|
14954
|
+
log("python3-venv could not be installed \u2014 moondream-station may be unavailable.");
|
|
14811
14955
|
}
|
|
14812
14956
|
}
|
|
14813
|
-
if (installed)
|
|
14814
|
-
log("moondream-station installed.");
|
|
14815
|
-
else
|
|
14816
|
-
log("Could not auto-install moondream-station (install manually: pip install moondream-station)");
|
|
14817
|
-
} catch {
|
|
14818
14957
|
}
|
|
14819
14958
|
}
|
|
14959
|
+
const venvDir = getVenvDir();
|
|
14960
|
+
const venvBin = join22(venvDir, "bin");
|
|
14961
|
+
const venvMoondream = join22(venvBin, "moondream-station");
|
|
14962
|
+
if (hasCmd("moondream-station") || existsSync15(venvMoondream)) {
|
|
14963
|
+
return;
|
|
14964
|
+
}
|
|
14965
|
+
const venv = ensureVenv(log);
|
|
14966
|
+
if (!venv) {
|
|
14967
|
+
log("Python venv unavailable \u2014 moondream-station will not be installed.");
|
|
14968
|
+
return;
|
|
14969
|
+
}
|
|
14970
|
+
const venvPip = join22(venvBin, "pip");
|
|
14971
|
+
log("Installing moondream-station in ~/.open-agents/venv...");
|
|
14972
|
+
try {
|
|
14973
|
+
execSync13(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
|
|
14974
|
+
if (existsSync15(venvMoondream)) {
|
|
14975
|
+
log("moondream-station installed successfully.");
|
|
14976
|
+
} else {
|
|
14977
|
+
try {
|
|
14978
|
+
const check = execSync13(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
|
|
14979
|
+
if (check.includes("moondream")) {
|
|
14980
|
+
log("moondream-station package installed.");
|
|
14981
|
+
}
|
|
14982
|
+
} catch {
|
|
14983
|
+
log("moondream-station install completed.");
|
|
14984
|
+
}
|
|
14985
|
+
}
|
|
14986
|
+
} catch (err) {
|
|
14987
|
+
log(`moondream-station install failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
14988
|
+
}
|
|
14820
14989
|
}
|
|
14821
14990
|
function expandedModelName(baseModel) {
|
|
14822
14991
|
return `open-agents-${baseModel.replace(":", "-").replace(/\./g, "")}`;
|
|
@@ -19667,13 +19836,33 @@ async function startInteractive(config, repoPath) {
|
|
|
19667
19836
|
const sessionMetrics = new SessionMetrics();
|
|
19668
19837
|
const workEvaluator = new WorkEvaluator();
|
|
19669
19838
|
ensureTranscribeCliBackground();
|
|
19839
|
+
let depSudoResolver = null;
|
|
19840
|
+
let depSudoPromptPending = false;
|
|
19670
19841
|
ensureVisionDeps((msg) => {
|
|
19671
19842
|
if (statusBar?.isActive) {
|
|
19672
19843
|
statusBar.beginContentWrite();
|
|
19673
19844
|
renderInfo(msg);
|
|
19674
19845
|
statusBar.endContentWrite();
|
|
19675
19846
|
}
|
|
19676
|
-
})
|
|
19847
|
+
}, () => new Promise((resolve19) => {
|
|
19848
|
+
depSudoPromptPending = true;
|
|
19849
|
+
depSudoResolver = (pw) => {
|
|
19850
|
+
depSudoPromptPending = false;
|
|
19851
|
+
depSudoResolver = null;
|
|
19852
|
+
if (pw)
|
|
19853
|
+
sessionSudoPassword = pw;
|
|
19854
|
+
resolve19(pw);
|
|
19855
|
+
};
|
|
19856
|
+
if (statusBar?.isActive) {
|
|
19857
|
+
statusBar.beginContentWrite();
|
|
19858
|
+
}
|
|
19859
|
+
process.stdout.write(` ${c2.bold(c2.yellow("\u{1F511} Password needed for dependency install:"))}
|
|
19860
|
+
`);
|
|
19861
|
+
process.stdout.write(` ${c2.bold(c2.yellow("\u{1F511} Password:"))} `);
|
|
19862
|
+
if (statusBar?.isActive) {
|
|
19863
|
+
statusBar.endContentWrite();
|
|
19864
|
+
}
|
|
19865
|
+
})).catch(() => {
|
|
19677
19866
|
});
|
|
19678
19867
|
const voiceEngine = new VoiceEngine();
|
|
19679
19868
|
const streamRenderer = new StreamRenderer();
|
|
@@ -20070,6 +20259,14 @@ async function startInteractive(config, repoPath) {
|
|
|
20070
20259
|
}, 50);
|
|
20071
20260
|
});
|
|
20072
20261
|
async function processLine(input) {
|
|
20262
|
+
if (depSudoPromptPending && depSudoResolver) {
|
|
20263
|
+
const pw = input.trim();
|
|
20264
|
+
process.stdout.write(`\r\x1B[K ${c2.dim("\u{1F511} Password received")}
|
|
20265
|
+
`);
|
|
20266
|
+
depSudoResolver(pw || null);
|
|
20267
|
+
showPrompt();
|
|
20268
|
+
return;
|
|
20269
|
+
}
|
|
20073
20270
|
if (sudoPromptPending && activeTask) {
|
|
20074
20271
|
sudoPromptPending = false;
|
|
20075
20272
|
sessionSudoPassword = input;
|
package/package.json
CHANGED