open-agents-ai 0.89.0 → 0.91.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 +84 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -321,13 +321,20 @@ async function checkForUpdate(currentVersion, forceCheck = false) {
|
|
|
321
321
|
};
|
|
322
322
|
}
|
|
323
323
|
function performSilentUpdate() {
|
|
324
|
+
const installCmd = `npm install -g ${PACKAGE_NAME}@latest --prefer-online`;
|
|
324
325
|
try {
|
|
325
|
-
execSync(
|
|
326
|
-
stdio: "pipe",
|
|
327
|
-
timeout: 12e4
|
|
328
|
-
});
|
|
326
|
+
execSync(installCmd, { stdio: "pipe", timeout: 12e4 });
|
|
329
327
|
return true;
|
|
330
|
-
} catch {
|
|
328
|
+
} catch (err) {
|
|
329
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
330
|
+
if (/EACCES|permission denied/i.test(msg)) {
|
|
331
|
+
try {
|
|
332
|
+
execSync(`sudo -n ${installCmd}`, { stdio: "pipe", timeout: 12e4 });
|
|
333
|
+
return true;
|
|
334
|
+
} catch {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
331
338
|
return false;
|
|
332
339
|
}
|
|
333
340
|
}
|
|
@@ -16487,6 +16494,8 @@ TASK: ${task}` : task }
|
|
|
16487
16494
|
let completed = false;
|
|
16488
16495
|
let summary = "";
|
|
16489
16496
|
let bruteForceCycle = 0;
|
|
16497
|
+
let consecutiveTextOnly = 0;
|
|
16498
|
+
const MAX_CONSECUTIVE_TEXT_ONLY = 3;
|
|
16490
16499
|
for (let turn = 0; turn < this.options.maxTurns; turn++) {
|
|
16491
16500
|
if (this._paused) {
|
|
16492
16501
|
const shouldContinue = await this.waitIfPaused();
|
|
@@ -16600,6 +16609,7 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
16600
16609
|
break;
|
|
16601
16610
|
const msg = choice.message;
|
|
16602
16611
|
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
16612
|
+
consecutiveTextOnly = 0;
|
|
16603
16613
|
messages.push({
|
|
16604
16614
|
role: "assistant",
|
|
16605
16615
|
content: msg.content || null,
|
|
@@ -16775,6 +16785,7 @@ Do NOT continue walking up parent directories.`);
|
|
|
16775
16785
|
} else {
|
|
16776
16786
|
const content = msg.content || "";
|
|
16777
16787
|
messages.push({ role: "assistant", content });
|
|
16788
|
+
consecutiveTextOnly++;
|
|
16778
16789
|
this.emit({
|
|
16779
16790
|
type: "model_response",
|
|
16780
16791
|
content: content.slice(0, 200),
|
|
@@ -16786,15 +16797,34 @@ Do NOT continue walking up parent directories.`);
|
|
|
16786
16797
|
summary = content;
|
|
16787
16798
|
break;
|
|
16788
16799
|
}
|
|
16800
|
+
if (consecutiveTextOnly >= MAX_CONSECUTIVE_TEXT_ONLY) {
|
|
16801
|
+
this.emit({
|
|
16802
|
+
type: "status",
|
|
16803
|
+
content: `Model returned ${consecutiveTextOnly} consecutive text-only responses without using tools \u2014 breaking turn loop to avoid runaway`,
|
|
16804
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16805
|
+
});
|
|
16806
|
+
break;
|
|
16807
|
+
}
|
|
16789
16808
|
messages.push({
|
|
16790
16809
|
role: "user",
|
|
16791
16810
|
content: "Continue working. Use tools to read files, make changes, and run validation. Call task_complete when done."
|
|
16792
16811
|
});
|
|
16793
16812
|
}
|
|
16794
16813
|
}
|
|
16814
|
+
let prevCycleToolCalls = toolCallCount;
|
|
16795
16815
|
while (!completed && !this.aborted && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles) {
|
|
16796
16816
|
bruteForceCycle++;
|
|
16797
16817
|
const totalTurns = messages.filter((m) => m.role === "assistant").length;
|
|
16818
|
+
if (bruteForceCycle > 1 && toolCallCount === prevCycleToolCalls) {
|
|
16819
|
+
this.emit({
|
|
16820
|
+
type: "status",
|
|
16821
|
+
content: `Stopping re-engagement \u2014 no tool call progress in cycle ${bruteForceCycle - 1}. Model may not support tool calling for this task.`,
|
|
16822
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16823
|
+
});
|
|
16824
|
+
break;
|
|
16825
|
+
}
|
|
16826
|
+
prevCycleToolCalls = toolCallCount;
|
|
16827
|
+
consecutiveTextOnly = 0;
|
|
16798
16828
|
this.emit({
|
|
16799
16829
|
type: "status",
|
|
16800
16830
|
content: `Re-engaging \u2014 cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} tool calls so far)`,
|
|
@@ -16918,6 +16948,7 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
16918
16948
|
break;
|
|
16919
16949
|
const msg = choice.message;
|
|
16920
16950
|
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
16951
|
+
consecutiveTextOnly = 0;
|
|
16921
16952
|
messages.push({ role: "assistant", content: msg.content || null, tool_calls: msg.toolCalls.map((tc) => ({ id: tc.id, type: "function", function: { name: tc.name, arguments: JSON.stringify(tc.arguments) } })) });
|
|
16922
16953
|
for (const tc of msg.toolCalls) {
|
|
16923
16954
|
if (this.aborted)
|
|
@@ -16978,12 +17009,21 @@ Do NOT continue walking up parent directories.`);
|
|
|
16978
17009
|
} else {
|
|
16979
17010
|
const content = msg.content || "";
|
|
16980
17011
|
messages.push({ role: "assistant", content });
|
|
17012
|
+
consecutiveTextOnly++;
|
|
16981
17013
|
this.emit({ type: "model_response", content: content.slice(0, 200), turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
16982
17014
|
if (/task.?complete|all tests pass/i.test(content)) {
|
|
16983
17015
|
completed = true;
|
|
16984
17016
|
summary = content;
|
|
16985
17017
|
break;
|
|
16986
17018
|
}
|
|
17019
|
+
if (consecutiveTextOnly >= MAX_CONSECUTIVE_TEXT_ONLY) {
|
|
17020
|
+
this.emit({
|
|
17021
|
+
type: "status",
|
|
17022
|
+
content: `Model returned ${consecutiveTextOnly} consecutive text-only responses \u2014 breaking cycle ${bruteForceCycle}`,
|
|
17023
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
17024
|
+
});
|
|
17025
|
+
break;
|
|
17026
|
+
}
|
|
16987
17027
|
messages.push({ role: "user", content: "Continue working. Use tools to read files, make changes, and run validation. Call task_complete when done." });
|
|
16988
17028
|
}
|
|
16989
17029
|
}
|
|
@@ -29992,22 +30032,55 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
29992
30032
|
return;
|
|
29993
30033
|
}
|
|
29994
30034
|
checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
|
|
30035
|
+
const { exec, execSync: es2 } = await import("node:child_process");
|
|
30036
|
+
let needsSudo = false;
|
|
30037
|
+
try {
|
|
30038
|
+
const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
30039
|
+
const { accessSync, constants } = await import("node:fs");
|
|
30040
|
+
try {
|
|
30041
|
+
accessSync(prefix, constants.W_OK);
|
|
30042
|
+
} catch {
|
|
30043
|
+
needsSudo = true;
|
|
30044
|
+
}
|
|
30045
|
+
} catch {
|
|
30046
|
+
}
|
|
30047
|
+
if (needsSudo) {
|
|
30048
|
+
renderInfo("Global npm directory requires elevated permissions.");
|
|
30049
|
+
renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
|
|
30050
|
+
process.stdout.write("\n");
|
|
30051
|
+
try {
|
|
30052
|
+
es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
|
|
30053
|
+
} catch {
|
|
30054
|
+
renderWarning("Could not acquire sudo credentials. Try: sudo npm i -g open-agents-ai");
|
|
30055
|
+
return;
|
|
30056
|
+
}
|
|
30057
|
+
}
|
|
30058
|
+
const sudoPrefix = needsSudo ? "sudo " : "";
|
|
29995
30059
|
const installSpinner = startInlineSpinner("Installing update");
|
|
29996
|
-
const
|
|
29997
|
-
|
|
29998
|
-
|
|
30060
|
+
const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
|
|
30061
|
+
let installOk = false;
|
|
30062
|
+
let installError = "";
|
|
30063
|
+
installOk = await new Promise((resolve31) => {
|
|
30064
|
+
const child = exec(installCmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
|
|
30065
|
+
if (err)
|
|
30066
|
+
installError = (stderr || err.message || "").trim();
|
|
30067
|
+
resolve31(!err);
|
|
30068
|
+
});
|
|
29999
30069
|
child.stdout?.resume();
|
|
30000
|
-
child.stderr?.resume();
|
|
30001
30070
|
});
|
|
30002
30071
|
if (!installOk) {
|
|
30003
30072
|
installSpinner.stop("Update install failed.");
|
|
30004
|
-
|
|
30073
|
+
const errPreview = installError.split("\n").filter((l) => l.trim()).slice(-3).join("\n ");
|
|
30074
|
+
if (errPreview)
|
|
30075
|
+
renderWarning(`Error:
|
|
30076
|
+
${errPreview}`);
|
|
30077
|
+
renderWarning(`Try manually: ${sudoPrefix}npm i -g open-agents-ai`);
|
|
30005
30078
|
return;
|
|
30006
30079
|
}
|
|
30007
30080
|
installSpinner.stop(`Update installed (v${info.latestVersion}).`);
|
|
30008
30081
|
const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
|
|
30009
30082
|
const rebuildOk = await new Promise((resolve31) => {
|
|
30010
|
-
const child = exec(
|
|
30083
|
+
const child = exec(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve31(true));
|
|
30011
30084
|
child.stdout?.resume();
|
|
30012
30085
|
child.stderr?.resume();
|
|
30013
30086
|
});
|
package/package.json
CHANGED