open-agents-ai 0.187.523 → 0.187.524

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
@@ -526383,6 +526383,122 @@ Your hypotheses MUST address this specific error, not generic causes.
526383
526383
  return null;
526384
526384
  }
526385
526385
  }
526386
+ /**
526387
+ * REG-61 sliding-window first-edit / sustained-edit nudge.
526388
+ *
526389
+ * Fires when:
526390
+ * • turn ≥ 4 (give the agent a few turns to orient)
526391
+ * • EITHER this run has zero creative edits OR the last creative edit
526392
+ * was ≥ 5 turns ago (re-fires when agent slips back into read mode)
526393
+ * • there have been ≥ 3 read-class tool calls in the trailing window
526394
+ * (since the last creative edit)
526395
+ * • not in the 5-turn cooldown after a previous firing
526396
+ *
526397
+ * Why earlier than REG-44/REG-58: by turn 12 the read habit is locked in
526398
+ * and prompts get ignored. Re-fire-with-cooldown handles the batch524 stax
526399
+ * case where one early file_write satisfied the initial gate, then the
526400
+ * agent spent 22 turns re-reading source. Directive text names the 4 valid
526401
+ * creative-edit tools EXPLICITLY and lists todo_write as NOT counting
526402
+ * (batch524 osm responded to the original directive with todo_write
526403
+ * thinking it qualified). Generic across ecosystems — no manifest/file/
526404
+ * language keywords.
526405
+ *
526406
+ * BFC-61 (root-cause from batch527-midi-solo): refactored from inline
526407
+ * block in the main turn loop into this method so the brute-force
526408
+ * re-engagement inner loop can also invoke it. Without BFC-61, REG-61
526409
+ * stops checking once the runner enters brute-force cycles, allowing
526410
+ * 30+ minutes of read-paralysis (batch527 hit this — 804 consecutive
526411
+ * non-edit calls in brute-force, REG-61 fired 0× in that phase).
526412
+ *
526413
+ * Side effects when firing:
526414
+ * - bumps `this._reg61CooldownUntilTurn`
526415
+ * - pushes a system message with the directive into `messages`
526416
+ * - emits a `status` event with telemetry (turn, reads_in_window, gap)
526417
+ *
526418
+ * State (instance fields, persist across cycles — desired):
526419
+ * - `_lastFileWriteTurn`: bumped by tool dispatch on creative edits
526420
+ * - `_reg61CooldownUntilTurn`: bumped by this method when firing
526421
+ *
526422
+ * @param turn - Current turn counter from the enclosing loop. In
526423
+ * brute-force cycles this resets to 0 each cycle, but the
526424
+ * cooldown / lastFileWriteTurn state is retained across
526425
+ * cycles via instance fields, so behavior is consistent.
526426
+ * @param toolCallLog - Append-only ordered tool-call history.
526427
+ * @param messages - Conversation history to inject the system directive into.
526428
+ * @param cycleLabel - Optional label to disambiguate brute-force fires
526429
+ * from main-loop fires in the status emit (e.g. "bf-cycle 2").
526430
+ */
526431
+ _runReg61Check(turn, toolCallLog, messages2, cycleLabel) {
526432
+ const REG61_TURN_FLOOR = 4;
526433
+ const REG61_MIN_READS = 3;
526434
+ const REG61_NO_WRITE_GAP = 5;
526435
+ const REG61_COOLDOWN = 5;
526436
+ if (process.env["OA_DISABLE_REG61"] === "1")
526437
+ return;
526438
+ if (turn < REG61_TURN_FLOOR)
526439
+ return;
526440
+ if (turn <= this._reg61CooldownUntilTurn)
526441
+ return;
526442
+ const _writeGate = this._lastFileWriteTurn < 0 || turn - this._lastFileWriteTurn >= REG61_NO_WRITE_GAP;
526443
+ if (!_writeGate)
526444
+ return;
526445
+ const _readClassNames = /* @__PURE__ */ new Set([
526446
+ "file_read",
526447
+ "file_explore",
526448
+ "list_directory",
526449
+ "grep_search",
526450
+ "glob_find",
526451
+ "find_files",
526452
+ "code_neighbors",
526453
+ "repo_map",
526454
+ "codebase_map",
526455
+ "semantic_map",
526456
+ "symbol_search",
526457
+ "todo_read",
526458
+ "memory_read",
526459
+ "memory_search"
526460
+ ]);
526461
+ const _editClassNames = /* @__PURE__ */ new Set([
526462
+ "file_write",
526463
+ "file_edit",
526464
+ "batch_edit",
526465
+ "file_patch"
526466
+ ]);
526467
+ let _readsInWindow = 0;
526468
+ for (let k = toolCallLog.length - 1; k >= 0; k--) {
526469
+ const _name = toolCallLog[k].name;
526470
+ if (_editClassNames.has(_name))
526471
+ break;
526472
+ if (_readClassNames.has(_name))
526473
+ _readsInWindow++;
526474
+ }
526475
+ if (_readsInWindow < REG61_MIN_READS)
526476
+ return;
526477
+ this._reg61CooldownUntilTurn = turn + REG61_COOLDOWN;
526478
+ const _gapDesc = this._lastFileWriteTurn < 0 ? `no creative edits yet this run` : `${turn - this._lastFileWriteTurn} turns since last creative edit (turn ${this._lastFileWriteTurn})`;
526479
+ const reg61Msg = `[FIRST-EDIT NUDGE — REG-61]
526480
+ You have made ${_readsInWindow} read/exploration calls in the trailing window — ${_gapDesc}. Reading is preparation; writing is progress. Runs that stay in pure-read mode produce zero deliverables.
526481
+
526482
+ Your NEXT tool call MUST be EXACTLY ONE of:
526483
+ • file_write — create a new file
526484
+ • file_edit — modify an existing file (find/replace)
526485
+ • batch_edit — multiple find/replace edits in one call
526486
+ • file_patch — apply a unified diff
526487
+
526488
+ These are the ONLY four tools that count as creative edits. The following do NOT count and will NOT satisfy this directive:
526489
+ • todo_write (only updates the todo list, not the filesystem)
526490
+ • memory_write (writes to memory store, not the project)
526491
+ • list_directory / file_read / file_explore / grep_search / shell
526492
+
526493
+ Pick the SMALLEST concrete deliverable from the spec — typically the project entry point or the file most other modules depend on. Write a stub or skeleton if the full implementation is too large; you can iterate later. Do NOT issue another read or todo update before producing the next file_write/file_edit/batch_edit/file_patch.`;
526494
+ messages2.push({ role: "system", content: reg61Msg });
526495
+ const _cyclePart = cycleLabel ? ` (${cycleLabel})` : "";
526496
+ this.emit({
526497
+ type: "status",
526498
+ content: `REG-61 FIRST-EDIT NUDGE — fired at turn ${turn}${_cyclePart}; reads_in_window=${_readsInWindow}; ${_gapDesc}`,
526499
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
526500
+ });
526501
+ }
526386
526502
  readSessionTodos() {
526387
526503
  try {
526388
526504
  const sid = process.env["OA_SESSION_ID"] || this._sessionId || "default";
@@ -528620,70 +528736,7 @@ TASK: ${task}` : task;
528620
528736
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
528621
528737
  });
528622
528738
  }
528623
- const REG61_TURN_FLOOR = 4;
528624
- const REG61_MIN_READS = 3;
528625
- const REG61_NO_WRITE_GAP = 5;
528626
- const REG61_COOLDOWN = 5;
528627
- if (turn >= REG61_TURN_FLOOR && turn > this._reg61CooldownUntilTurn && process.env["OA_DISABLE_REG61"] !== "1") {
528628
- const _writeGate = this._lastFileWriteTurn < 0 || turn - this._lastFileWriteTurn >= REG61_NO_WRITE_GAP;
528629
- if (_writeGate) {
528630
- const _readClassNames = /* @__PURE__ */ new Set([
528631
- "file_read",
528632
- "file_explore",
528633
- "list_directory",
528634
- "grep_search",
528635
- "glob_find",
528636
- "find_files",
528637
- "code_neighbors",
528638
- "repo_map",
528639
- "codebase_map",
528640
- "semantic_map",
528641
- "symbol_search",
528642
- "todo_read",
528643
- "memory_read",
528644
- "memory_search"
528645
- ]);
528646
- let _readsInWindow = 0;
528647
- const _editClassNames = /* @__PURE__ */ new Set([
528648
- "file_write",
528649
- "file_edit",
528650
- "batch_edit",
528651
- "file_patch"
528652
- ]);
528653
- for (let k = toolCallLog.length - 1; k >= 0; k--) {
528654
- const _name = toolCallLog[k].name;
528655
- if (_editClassNames.has(_name))
528656
- break;
528657
- if (_readClassNames.has(_name))
528658
- _readsInWindow++;
528659
- }
528660
- if (_readsInWindow >= REG61_MIN_READS) {
528661
- this._reg61CooldownUntilTurn = turn + REG61_COOLDOWN;
528662
- const _gapDesc = this._lastFileWriteTurn < 0 ? `no creative edits yet this run` : `${turn - this._lastFileWriteTurn} turns since last creative edit (turn ${this._lastFileWriteTurn})`;
528663
- const reg61Msg = `[FIRST-EDIT NUDGE — REG-61]
528664
- You have made ${_readsInWindow} read/exploration calls in the trailing window — ${_gapDesc}. Reading is preparation; writing is progress. Runs that stay in pure-read mode produce zero deliverables.
528665
-
528666
- Your NEXT tool call MUST be EXACTLY ONE of:
528667
- • file_write — create a new file
528668
- • file_edit — modify an existing file (find/replace)
528669
- • batch_edit — multiple find/replace edits in one call
528670
- • file_patch — apply a unified diff
528671
-
528672
- These are the ONLY four tools that count as creative edits. The following do NOT count and will NOT satisfy this directive:
528673
- • todo_write (only updates the todo list, not the filesystem)
528674
- • memory_write (writes to memory store, not the project)
528675
- • list_directory / file_read / file_explore / grep_search / shell
528676
-
528677
- Pick the SMALLEST concrete deliverable from the spec — typically the project entry point or the file most other modules depend on. Write a stub or skeleton if the full implementation is too large; you can iterate later. Do NOT issue another read or todo update before producing the next file_write/file_edit/batch_edit/file_patch.`;
528678
- messages2.push({ role: "system", content: reg61Msg });
528679
- this.emit({
528680
- type: "status",
528681
- content: `REG-61 FIRST-EDIT NUDGE — fired at turn ${turn}; reads_in_window=${_readsInWindow}; ${_gapDesc}`,
528682
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
528683
- });
528684
- }
528685
- }
528686
- }
528739
+ this._runReg61Check(turn, toolCallLog, messages2);
528687
528740
  const REG58_NO_WRITE_BUDGET = 30;
528688
528741
  if (turn > stagnationCooldownUntilTurn && this._lastFileWriteTurn >= 0 && turn - this._lastFileWriteTurn >= REG58_NO_WRITE_BUDGET && process.env["OA_DISABLE_REG58"] !== "1") {
528689
528742
  const gap = turn - this._lastFileWriteTurn;
@@ -532118,6 +532171,7 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
532118
532171
  content: `Re-engaging — cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} tool calls so far)`,
532119
532172
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
532120
532173
  });
532174
+ this._reg61CooldownUntilTurn = -1;
532121
532175
  messages2.push({
532122
532176
  role: "user",
532123
532177
  content: `[CONTINUATION — Cycle ${bruteForceCycle}]
@@ -532151,6 +532205,7 @@ You have ${this.options.maxTurns} more turns. Continue making progress. Call tas
532151
532205
  this.emit({ type: "error", content: "Task aborted by user", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
532152
532206
  break;
532153
532207
  }
532208
+ this._runReg61Check(turn, toolCallLog, messages2, `bf-cycle ${bruteForceCycle}`);
532154
532209
  const bfNow = Date.now();
532155
532210
  if (bfNow > nextSelfEval) {
532156
532211
  selfEvalCount++;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.523",
3
+ "version": "0.187.524",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.523",
9
+ "version": "0.187.524",
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.523",
3
+ "version": "0.187.524",
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",