open-agents-ai 0.187.462 → 0.187.464

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 CHANGED
@@ -517722,6 +517722,11 @@ var init_agenticRunner = __esm({
517722
517722
  // Observer world-model and cohort stats
517723
517723
  _observerMode = "both";
517724
517724
  _worldFacts = { files: /* @__PURE__ */ new Map(), lastTest: {}, lastLists: /* @__PURE__ */ new Map() };
517725
+ // REG-5: Rolling buffer of recent tool failures with their error output.
517726
+ // Surfaced before every LLM call so the agent can't ignore "I just ran this
517727
+ // and it errored". Detects same-fingerprint failure repetition and escalates
517728
+ // the warning. Keeps last 8 to bound memory + prompt cost.
517729
+ _recentFailures = [];
517725
517730
  _argCohorts = /* @__PURE__ */ new Map();
517726
517731
  // ── WO-NC-07: Error pattern learning → pre-action guidance injection ──
517727
517732
  // Records error patterns (tool + error signature → learned guidance).
@@ -518414,6 +518419,53 @@ ${body}`;
518414
518419
  * Returns null when the disable knob is set or the backend is missing the
518415
518420
  * chatCompletion method.
518416
518421
  */
518422
+ /**
518423
+ * REG-5: Render the recent-failures block so the agent SEES its own error
518424
+ * output before deciding what to do next. Detects same-fingerprint failure
518425
+ * repetition and escalates the warning. Without this, the agent runs
518426
+ * `npx next build`, gets a 200-line TypeScript error, ignores the specific
518427
+ * error and blindly retries with `npm install --force`. Caching the failure
518428
+ * + injecting it pre-LLM forces the model to confront what actually broke.
518429
+ */
518430
+ _renderRecentFailuresBlock(turn) {
518431
+ const fails = this._recentFailures;
518432
+ if (!fails || fails.length === 0)
518433
+ return null;
518434
+ const fresh = fails.filter((f2) => turn - f2.turn <= 10);
518435
+ if (fresh.length === 0)
518436
+ return null;
518437
+ const fpCount = /* @__PURE__ */ new Map();
518438
+ for (const f2 of fresh) {
518439
+ if (turn - f2.turn <= 5)
518440
+ fpCount.set(f2.fingerprint, (fpCount.get(f2.fingerprint) ?? 0) + 1);
518441
+ }
518442
+ const repeating = [...fpCount.entries()].filter(([, n2]) => n2 >= 2);
518443
+ const lines = [];
518444
+ if (repeating.length > 0) {
518445
+ lines.push("[STOP — RETRY LOOP DETECTED]");
518446
+ lines.push("You are re-issuing the SAME failing tool call(s) without changing anything that would fix the underlying error. If you cannot diagnose the error from the messages below, mark the current todo phase as `blocked` (with the blocker text) and either move to a different phase or call task_complete with what you have. DO NOT just retry the same command again — the error will not magically disappear.");
518447
+ } else {
518448
+ lines.push("[RECENT TOOL FAILURES — read these errors carefully BEFORE deciding your next action]");
518449
+ }
518450
+ const shown = fresh.slice(-5).reverse();
518451
+ for (const f2 of shown) {
518452
+ const argsRepr = JSON.stringify(f2.args).slice(0, 120);
518453
+ const errFirst = (f2.error || f2.output || "").split(/\n/)[0]?.slice(0, 200) || "(no error message)";
518454
+ const errFull = (f2.error || f2.output || "").slice(0, 600);
518455
+ lines.push(`• turn ${f2.turn} — ${f2.tool}(${argsRepr})`);
518456
+ lines.push(` first line: ${errFirst}`);
518457
+ if (errFull && errFull !== errFirst) {
518458
+ const indented = errFull.split(/\n/).slice(0, 6).map((l2) => ` ${l2}`).join("\n");
518459
+ lines.push(indented);
518460
+ }
518461
+ }
518462
+ if (repeating.length > 0) {
518463
+ const repeatingDesc = repeating.map(([fp, n2]) => `${n2}× ${fp.slice(0, 80)}`).join("; ");
518464
+ lines.push(`Repeating fingerprints: ${repeatingDesc}`);
518465
+ }
518466
+ lines.push(`(turn ${turn} — failures auto-expire after 10 turns; cleared on success or successful retry)`);
518467
+ return lines.join("\n");
518468
+ }
518417
518469
  /**
518418
518470
  * REG-3: Render the current todo list as a compact transient block so the
518419
518471
  * agent can read its own plan without calling todo_read or re-emitting
@@ -519597,6 +519649,9 @@ ${memoryLines.join("\n")}`
519597
519649
  const todoBlock = this._renderTodoStateBlock(turn);
519598
519650
  if (todoBlock)
519599
519651
  _injections.push(todoBlock);
519652
+ const failBlock = this._renderRecentFailuresBlock(turn);
519653
+ if (failBlock)
519654
+ _injections.push(failBlock);
519600
519655
  if (_injections.length > 0) {
519601
519656
  const reqMsgs = chatRequest.messages;
519602
519657
  if (Array.isArray(reqMsgs)) {
@@ -520385,6 +520440,22 @@ ${cachedEntry2.result.slice(0, 500)}` : `[BLOCKED — the observer confirmed thi
520385
520440
  recentToolResults.delete(firstKey);
520386
520441
  }
520387
520442
  }
520443
+ if (result.success) {
520444
+ this._recentFailures = this._recentFailures.filter((f2) => f2.fingerprint !== toolFingerprint);
520445
+ }
520446
+ if (!result.success) {
520447
+ this._recentFailures.push({
520448
+ tool: tc.name,
520449
+ fingerprint: toolFingerprint,
520450
+ args: tc.arguments,
520451
+ error: (result.error ?? "").slice(0, 600),
520452
+ output: (result.output ?? "").slice(0, 1500),
520453
+ turn
520454
+ });
520455
+ if (this._recentFailures.length > 8) {
520456
+ this._recentFailures = this._recentFailures.slice(-8);
520457
+ }
520458
+ }
520388
520459
  if (!result.success && tc.name === "shell" && /\[PERMISSION_ERROR\]/.test(result.error ?? "")) {
520389
520460
  this.emit({
520390
520461
  type: "sudo_request",
@@ -595283,7 +595354,22 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
595283
595354
  const input = line.trim();
595284
595355
  if (!input) {
595285
595356
  if (pasteBuffer.length > 0) {
595286
- flushPasteBuffer();
595357
+ if (pasteIndicatorShown) {
595358
+ flushPasteBuffer();
595359
+ return;
595360
+ }
595361
+ pasteBuffer.push("");
595362
+ if (pasteTimer) clearTimeout(pasteTimer);
595363
+ pasteTimer = setTimeout(() => {
595364
+ pasteTimer = null;
595365
+ if (pasteBuffer.length === 1) {
595366
+ const solo = pasteBuffer.shift();
595367
+ pasteIndicatorShown = false;
595368
+ processLine(solo);
595369
+ } else {
595370
+ showPasteIndicator();
595371
+ }
595372
+ }, 50);
595287
595373
  return;
595288
595374
  }
595289
595375
  showPrompt();
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.462",
3
+ "version": "0.187.464",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.462",
9
+ "version": "0.187.464",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.462",
3
+ "version": "0.187.464",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",