open-agents-ai 0.101.0 → 0.101.2
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 +95 -114
- package/package.json +1 -1
- package/prompts/agentic/system-large.md +9 -0
- package/prompts/agentic/system-medium.md +9 -1
package/dist/index.js
CHANGED
|
@@ -29251,30 +29251,51 @@ function runWithSudo(cmd, password, timeoutMs = 12e4) {
|
|
|
29251
29251
|
timeout: timeoutMs,
|
|
29252
29252
|
env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
|
|
29253
29253
|
});
|
|
29254
|
-
return
|
|
29255
|
-
} catch {
|
|
29256
|
-
|
|
29254
|
+
return "ok";
|
|
29255
|
+
} catch (err) {
|
|
29256
|
+
const stderr = err?.stderr?.toString() ?? "";
|
|
29257
|
+
if (/incorrect password|authentication failure|Sorry, try again|not in the sudoers/i.test(stderr)) {
|
|
29258
|
+
return "auth_fail";
|
|
29259
|
+
}
|
|
29260
|
+
return "cmd_fail";
|
|
29257
29261
|
}
|
|
29258
29262
|
}
|
|
29259
|
-
|
|
29260
|
-
|
|
29261
|
-
|
|
29262
|
-
|
|
29263
|
+
function validateSudoPassword(password) {
|
|
29264
|
+
return runWithSudo("true", password, 1e4) === "ok";
|
|
29265
|
+
}
|
|
29266
|
+
async function acquireSudoPassword(getSudoPassword, log, cachedPasswordRef) {
|
|
29267
|
+
if (cachedPasswordRef.value && validateSudoPassword(cachedPasswordRef.value)) {
|
|
29268
|
+
return cachedPasswordRef.value;
|
|
29263
29269
|
}
|
|
29270
|
+
if (trySudoPasswordless("true", 1e4)) {
|
|
29271
|
+
return "";
|
|
29272
|
+
}
|
|
29273
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
29274
|
+
if (attempt > 0)
|
|
29275
|
+
log("Authentication failed \u2014 please re-enter password.");
|
|
29276
|
+
const pw = await getSudoPassword();
|
|
29277
|
+
if (!pw)
|
|
29278
|
+
return null;
|
|
29279
|
+
if (validateSudoPassword(pw)) {
|
|
29280
|
+
cachedPasswordRef.value = pw;
|
|
29281
|
+
return pw;
|
|
29282
|
+
}
|
|
29283
|
+
}
|
|
29284
|
+
return null;
|
|
29285
|
+
}
|
|
29286
|
+
async function sudoInstall(cmd, getSudoPassword, log, cachedPasswordRef, timeoutMs = 12e4) {
|
|
29264
29287
|
if (trySudoPasswordless(cmd, timeoutMs))
|
|
29265
29288
|
return true;
|
|
29266
|
-
const pw = await getSudoPassword
|
|
29267
|
-
if (pw)
|
|
29268
|
-
|
|
29269
|
-
|
|
29270
|
-
|
|
29271
|
-
|
|
29272
|
-
|
|
29273
|
-
|
|
29274
|
-
|
|
29275
|
-
|
|
29276
|
-
return true;
|
|
29277
|
-
}
|
|
29289
|
+
const pw = await acquireSudoPassword(getSudoPassword, log, cachedPasswordRef);
|
|
29290
|
+
if (pw === null)
|
|
29291
|
+
return false;
|
|
29292
|
+
if (pw === "")
|
|
29293
|
+
return false;
|
|
29294
|
+
const result = runWithSudo(cmd, pw, timeoutMs);
|
|
29295
|
+
if (result === "ok")
|
|
29296
|
+
return true;
|
|
29297
|
+
if (result === "cmd_fail") {
|
|
29298
|
+
log(`Install command failed (not an auth issue) \u2014 package may not be available for this OS.`);
|
|
29278
29299
|
}
|
|
29279
29300
|
return false;
|
|
29280
29301
|
}
|
|
@@ -29283,108 +29304,68 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
|
|
|
29283
29304
|
});
|
|
29284
29305
|
const cachedPasswordRef = { value: null };
|
|
29285
29306
|
const getPassword = getSudoPassword ?? (() => Promise.resolve(null));
|
|
29286
|
-
|
|
29287
|
-
|
|
29288
|
-
|
|
29289
|
-
|
|
29290
|
-
|
|
29291
|
-
dnf: { cmd: "dnf install -y tesseract", needsSudo: true },
|
|
29292
|
-
pacman: { cmd: "pacman -S --noconfirm tesseract", needsSudo: true },
|
|
29293
|
-
brew: { cmd: "brew install tesseract", needsSudo: false },
|
|
29294
|
-
choco: { cmd: "choco install -y tesseract", needsSudo: false }
|
|
29295
|
-
};
|
|
29296
|
-
const pkg = pkgMap[pm2];
|
|
29297
|
-
if (pkg.needsSudo) {
|
|
29298
|
-
log("Installing tesseract-ocr...");
|
|
29299
|
-
const ok = await sudoInstall(pkg.cmd, getPassword, log, cachedPasswordRef);
|
|
29300
|
-
if (ok && hasCmd("tesseract")) {
|
|
29301
|
-
log("tesseract-ocr installed successfully.");
|
|
29302
|
-
} else {
|
|
29303
|
-
log("tesseract-ocr could not be installed \u2014 OCR features will be limited.");
|
|
29304
|
-
}
|
|
29305
|
-
} else {
|
|
29306
|
-
log("Installing tesseract-ocr...");
|
|
29307
|
-
try {
|
|
29308
|
-
execSync25(pkg.cmd, { stdio: "pipe", timeout: 12e4 });
|
|
29309
|
-
if (hasCmd("tesseract")) {
|
|
29310
|
-
log("tesseract-ocr installed successfully.");
|
|
29311
|
-
} else {
|
|
29312
|
-
log("tesseract-ocr install completed but binary not found \u2014 OCR features will be limited.");
|
|
29313
|
-
}
|
|
29314
|
-
} catch {
|
|
29315
|
-
log("tesseract-ocr could not be installed \u2014 OCR features will be limited.");
|
|
29316
|
-
}
|
|
29317
|
-
}
|
|
29318
|
-
} else {
|
|
29319
|
-
log("No supported package manager detected \u2014 tesseract OCR unavailable.");
|
|
29320
|
-
}
|
|
29321
|
-
}
|
|
29322
|
-
const pdfDeps = [
|
|
29323
|
-
{
|
|
29324
|
-
binary: "pdftotext",
|
|
29325
|
-
label: "poppler-utils (pdftotext)",
|
|
29326
|
-
pkgMap: {
|
|
29327
|
-
apt: { cmd: "apt-get install -y poppler-utils", needsSudo: true },
|
|
29328
|
-
dnf: { cmd: "dnf install -y poppler-utils", needsSudo: true },
|
|
29329
|
-
pacman: { cmd: "pacman -S --noconfirm poppler", needsSudo: true },
|
|
29330
|
-
brew: { cmd: "brew install poppler", needsSudo: false },
|
|
29331
|
-
choco: { cmd: "choco install -y poppler", needsSudo: false }
|
|
29332
|
-
}
|
|
29333
|
-
},
|
|
29334
|
-
{
|
|
29335
|
-
binary: "gs",
|
|
29336
|
-
label: "ghostscript",
|
|
29337
|
-
pkgMap: {
|
|
29338
|
-
apt: { cmd: "apt-get install -y ghostscript", needsSudo: true },
|
|
29339
|
-
dnf: { cmd: "dnf install -y ghostscript", needsSudo: true },
|
|
29340
|
-
pacman: { cmd: "pacman -S --noconfirm ghostscript", needsSudo: true },
|
|
29341
|
-
brew: { cmd: "brew install ghostscript", needsSudo: false },
|
|
29342
|
-
choco: { cmd: "choco install -y ghostscript", needsSudo: false }
|
|
29343
|
-
}
|
|
29344
|
-
},
|
|
29345
|
-
{
|
|
29346
|
-
binary: "ocrmypdf",
|
|
29347
|
-
label: "ocrmypdf",
|
|
29348
|
-
pkgMap: {
|
|
29349
|
-
apt: { cmd: "apt-get install -y ocrmypdf", needsSudo: true },
|
|
29350
|
-
dnf: { cmd: "dnf install -y ocrmypdf", needsSudo: true },
|
|
29351
|
-
pacman: { cmd: "pacman -S --noconfirm ocrmypdf", needsSudo: true },
|
|
29352
|
-
brew: { cmd: "brew install ocrmypdf", needsSudo: false },
|
|
29353
|
-
choco: { cmd: "choco install -y ocrmypdf", needsSudo: false }
|
|
29354
|
-
}
|
|
29355
|
-
}
|
|
29307
|
+
const allDeps = [
|
|
29308
|
+
{ binary: "tesseract", label: "tesseract-ocr", pkgs: { apt: "tesseract-ocr", dnf: "tesseract", pacman: "tesseract", brew: "tesseract", choco: "tesseract" } },
|
|
29309
|
+
{ binary: "pdftotext", label: "poppler-utils", pkgs: { apt: "poppler-utils", dnf: "poppler-utils", pacman: "poppler", brew: "poppler", choco: "poppler" } },
|
|
29310
|
+
{ binary: "gs", label: "ghostscript", pkgs: { apt: "ghostscript", dnf: "ghostscript", pacman: "ghostscript", brew: "ghostscript", choco: "ghostscript" } },
|
|
29311
|
+
{ binary: "ocrmypdf", label: "ocrmypdf", pkgs: { apt: "ocrmypdf", dnf: "ocrmypdf", pacman: "ocrmypdf", brew: "ocrmypdf", choco: "ocrmypdf" } }
|
|
29356
29312
|
];
|
|
29357
29313
|
{
|
|
29358
29314
|
const pm2 = detectPkgManager();
|
|
29359
|
-
|
|
29360
|
-
|
|
29361
|
-
|
|
29362
|
-
|
|
29363
|
-
log(`No supported package manager
|
|
29364
|
-
|
|
29365
|
-
|
|
29366
|
-
|
|
29367
|
-
|
|
29368
|
-
|
|
29369
|
-
|
|
29370
|
-
|
|
29371
|
-
|
|
29372
|
-
|
|
29373
|
-
|
|
29315
|
+
const missing = allDeps.filter((d) => !hasCmd(d.binary));
|
|
29316
|
+
if (missing.length === 0) {
|
|
29317
|
+
} else if (!pm2) {
|
|
29318
|
+
for (const d of missing)
|
|
29319
|
+
log(`No supported package manager \u2014 ${d.label} unavailable.`);
|
|
29320
|
+
} else {
|
|
29321
|
+
const pkgNames = missing.map((d) => d.pkgs[pm2]).filter(Boolean);
|
|
29322
|
+
if (pkgNames.length === 0) {
|
|
29323
|
+
for (const d of missing)
|
|
29324
|
+
log(`${d.label} not available for ${pm2}.`);
|
|
29325
|
+
} else {
|
|
29326
|
+
const labels = missing.map((d) => d.label).join(", ");
|
|
29327
|
+
log(`Installing ${labels}...`);
|
|
29328
|
+
const needsSudo = pm2 !== "brew" && pm2 !== "choco";
|
|
29329
|
+
let batchCmd;
|
|
29330
|
+
switch (pm2) {
|
|
29331
|
+
case "apt":
|
|
29332
|
+
batchCmd = `apt-get update -qq && apt-get install -y -qq ${pkgNames.join(" ")}`;
|
|
29333
|
+
break;
|
|
29334
|
+
case "dnf":
|
|
29335
|
+
batchCmd = `dnf install -y -q ${pkgNames.join(" ")}`;
|
|
29336
|
+
break;
|
|
29337
|
+
case "pacman":
|
|
29338
|
+
batchCmd = `pacman -S --noconfirm ${pkgNames.join(" ")}`;
|
|
29339
|
+
break;
|
|
29340
|
+
case "brew":
|
|
29341
|
+
batchCmd = `brew install ${pkgNames.join(" ")}`;
|
|
29342
|
+
break;
|
|
29343
|
+
case "choco":
|
|
29344
|
+
batchCmd = `choco install -y ${pkgNames.join(" ")}`;
|
|
29345
|
+
break;
|
|
29346
|
+
default:
|
|
29347
|
+
batchCmd = `echo "unsupported pm: ${pm2}" && exit 1`;
|
|
29348
|
+
break;
|
|
29349
|
+
}
|
|
29350
|
+
let ok = false;
|
|
29351
|
+
if (needsSudo) {
|
|
29352
|
+
ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
|
|
29374
29353
|
} else {
|
|
29375
|
-
|
|
29354
|
+
try {
|
|
29355
|
+
execSync25(batchCmd, { stdio: "pipe", timeout: 18e4 });
|
|
29356
|
+
ok = true;
|
|
29357
|
+
} catch {
|
|
29358
|
+
ok = false;
|
|
29359
|
+
}
|
|
29376
29360
|
}
|
|
29377
|
-
|
|
29378
|
-
|
|
29379
|
-
|
|
29380
|
-
|
|
29381
|
-
|
|
29382
|
-
log(`${dep.label} installed successfully.`);
|
|
29361
|
+
for (const d of missing) {
|
|
29362
|
+
if (hasCmd(d.binary)) {
|
|
29363
|
+
log(`${d.label} installed.`);
|
|
29364
|
+
} else if (!ok) {
|
|
29365
|
+
log(`${d.label} could not be installed \u2014 features will be limited.`);
|
|
29383
29366
|
} else {
|
|
29384
|
-
log(`${
|
|
29367
|
+
log(`${d.label} install completed but binary not found.`);
|
|
29385
29368
|
}
|
|
29386
|
-
} catch {
|
|
29387
|
-
log(`${dep.label} could not be installed \u2014 PDF OCR features will be limited.`);
|
|
29388
29369
|
}
|
|
29389
29370
|
}
|
|
29390
29371
|
}
|
package/package.json
CHANGED
|
@@ -56,6 +56,15 @@ PARALLEL SUB-AGENT PATTERN (preferred for independent tasks):
|
|
|
56
56
|
2. Both sub-agents run simultaneously against the backend
|
|
57
57
|
3. Use task_status() to poll, then task_output() to read results
|
|
58
58
|
|
|
59
|
+
WHEN TO DECOMPOSE — assess before starting complex work:
|
|
60
|
+
- Task touches 3+ independent files/modules? → sub-agents can work on each in parallel
|
|
61
|
+
- Need to research AND implement? → sub-agent explores while you start coding
|
|
62
|
+
- Multiple test suites to validate? → background_run each suite concurrently
|
|
63
|
+
- Task has clearly separable phases (e.g. frontend + backend, or docs + code)? → parallel sub-agents
|
|
64
|
+
- Simple single-file edit or sequential dependency chain? → do it yourself, no sub-agents needed
|
|
65
|
+
|
|
66
|
+
You don't need to be asked to parallelize. If you recognize independent subtasks, delegate them.
|
|
67
|
+
|
|
59
68
|
## Skills (AIWG)
|
|
60
69
|
|
|
61
70
|
- skill_list: Discover available skills — shows descriptions and trigger patterns. Use filter param to search.
|
|
@@ -24,12 +24,20 @@ NEVER say "I can't do that". ALWAYS attempt the task using your tools. If a tool
|
|
|
24
24
|
- nexus: P2P agent networking (connect, join_room, send_message, discover_peers, invoke_capability, register_capability, block_peer, metering_status, room_members, wallet, etc.)
|
|
25
25
|
- task_complete: Signal completion with a summary
|
|
26
26
|
- background_run / task_status / task_output / task_stop: Background tasks
|
|
27
|
+
- sub_agent: Delegate a subtask to an independent agent (use background=true for parallel work)
|
|
27
28
|
- batch_edit: Multiple edits across files in one call
|
|
28
29
|
- skill_list / skill_execute / skill_build: Discover, load, and generate skills (use on-demand)
|
|
29
30
|
|
|
31
|
+
Parallelism: Multiple read-only tool calls in ONE response run in parallel automatically.
|
|
32
|
+
For complex tasks touching 3+ independent files/modules, delegate each to a sub_agent:
|
|
33
|
+
sub_agent({task: "Fix module-a — read test.js for expected behavior", background: true})
|
|
34
|
+
sub_agent({task: "Fix module-b — read test.js for expected behavior", background: true})
|
|
35
|
+
Launch ALL sub_agent calls in ONE response. This saves your context window for other work.
|
|
36
|
+
|
|
30
37
|
## Workflow
|
|
31
38
|
|
|
32
|
-
1.
|
|
39
|
+
1. If task mentions 3+ independent modules/files: delegate each to a sub_agent (saves context)
|
|
40
|
+
2. EXPLORE: Use find_files, grep_search, file_read to understand the codebase
|
|
33
41
|
2. IMPLEMENT: Make changes with file_edit (preferred) or file_write
|
|
34
42
|
3. VALIDATE: Run tests/build with shell. Read FULL output.
|
|
35
43
|
4. FIX: If validation fails, fix the specific issue and re-validate
|