open-agents-ai 0.187.523 → 0.187.525
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 +190 -64
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -525987,6 +525987,20 @@ var init_agenticRunner = __esm({
|
|
|
525987
525987
|
// updated directive text names the 4 valid creative-edit tools and
|
|
525988
525988
|
// explicitly excludes todo_write/memory_write/list_directory.
|
|
525989
525989
|
_reg61CooldownUntilTurn = -1;
|
|
525990
|
+
// BFC-61.E (root-cause from batch528-midi-bfc61, 2026-05-03): REG-61
|
|
525991
|
+
// runtime coercion. Empirical: in batch528 the agent received 5 REG-61
|
|
525992
|
+
// firings in main loop and ignored ALL of them while in vitest-debug-loop
|
|
525993
|
+
// mode (0 edits in 65 tool calls). REG-61 is informational; the agent
|
|
525994
|
+
// rationally ignores it when it believes "I need to read more to debug".
|
|
525995
|
+
// This counter escalates REG-61 to runtime enforcement: when REG-61
|
|
525996
|
+
// fires, _reg61BlocksRemaining is set to 1. The dispatch site checks: if
|
|
525997
|
+
// blocks remain AND incoming tool is non-edit, BLOCK with a synthetic
|
|
525998
|
+
// [BLOCKED — REG-61 directive in effect] error and decrement. If the
|
|
525999
|
+
// incoming tool IS an edit, the counter clears (directive satisfied).
|
|
526000
|
+
// One block per fire — not a perpetual gate; the agent's NEXT call
|
|
526001
|
+
// after the block can be anything (until the NEXT REG-61 fire 5+ turns
|
|
526002
|
+
// later). Kill switch: OA_DISABLE_REG61_COERCE=1.
|
|
526003
|
+
_reg61BlocksRemaining = 0;
|
|
525990
526004
|
// MEM_PATH item #9: adaptive retrieval cache. When the (goalHash, recent-tool-sig)
|
|
525991
526005
|
// hasn't changed since last retrieval, skip the PPR call entirely and reuse
|
|
525992
526006
|
// the previous memoryLines.
|
|
@@ -526383,6 +526397,125 @@ Your hypotheses MUST address this specific error, not generic causes.
|
|
|
526383
526397
|
return null;
|
|
526384
526398
|
}
|
|
526385
526399
|
}
|
|
526400
|
+
/**
|
|
526401
|
+
* REG-61 sliding-window first-edit / sustained-edit nudge.
|
|
526402
|
+
*
|
|
526403
|
+
* Fires when:
|
|
526404
|
+
* • turn ≥ 4 (give the agent a few turns to orient)
|
|
526405
|
+
* • EITHER this run has zero creative edits OR the last creative edit
|
|
526406
|
+
* was ≥ 5 turns ago (re-fires when agent slips back into read mode)
|
|
526407
|
+
* • there have been ≥ 3 read-class tool calls in the trailing window
|
|
526408
|
+
* (since the last creative edit)
|
|
526409
|
+
* • not in the 5-turn cooldown after a previous firing
|
|
526410
|
+
*
|
|
526411
|
+
* Why earlier than REG-44/REG-58: by turn 12 the read habit is locked in
|
|
526412
|
+
* and prompts get ignored. Re-fire-with-cooldown handles the batch524 stax
|
|
526413
|
+
* case where one early file_write satisfied the initial gate, then the
|
|
526414
|
+
* agent spent 22 turns re-reading source. Directive text names the 4 valid
|
|
526415
|
+
* creative-edit tools EXPLICITLY and lists todo_write as NOT counting
|
|
526416
|
+
* (batch524 osm responded to the original directive with todo_write
|
|
526417
|
+
* thinking it qualified). Generic across ecosystems — no manifest/file/
|
|
526418
|
+
* language keywords.
|
|
526419
|
+
*
|
|
526420
|
+
* BFC-61 (root-cause from batch527-midi-solo): refactored from inline
|
|
526421
|
+
* block in the main turn loop into this method so the brute-force
|
|
526422
|
+
* re-engagement inner loop can also invoke it. Without BFC-61, REG-61
|
|
526423
|
+
* stops checking once the runner enters brute-force cycles, allowing
|
|
526424
|
+
* 30+ minutes of read-paralysis (batch527 hit this — 804 consecutive
|
|
526425
|
+
* non-edit calls in brute-force, REG-61 fired 0× in that phase).
|
|
526426
|
+
*
|
|
526427
|
+
* Side effects when firing:
|
|
526428
|
+
* - bumps `this._reg61CooldownUntilTurn`
|
|
526429
|
+
* - pushes a system message with the directive into `messages`
|
|
526430
|
+
* - emits a `status` event with telemetry (turn, reads_in_window, gap)
|
|
526431
|
+
*
|
|
526432
|
+
* State (instance fields, persist across cycles — desired):
|
|
526433
|
+
* - `_lastFileWriteTurn`: bumped by tool dispatch on creative edits
|
|
526434
|
+
* - `_reg61CooldownUntilTurn`: bumped by this method when firing
|
|
526435
|
+
*
|
|
526436
|
+
* @param turn - Current turn counter from the enclosing loop. In
|
|
526437
|
+
* brute-force cycles this resets to 0 each cycle, but the
|
|
526438
|
+
* cooldown / lastFileWriteTurn state is retained across
|
|
526439
|
+
* cycles via instance fields, so behavior is consistent.
|
|
526440
|
+
* @param toolCallLog - Append-only ordered tool-call history.
|
|
526441
|
+
* @param messages - Conversation history to inject the system directive into.
|
|
526442
|
+
* @param cycleLabel - Optional label to disambiguate brute-force fires
|
|
526443
|
+
* from main-loop fires in the status emit (e.g. "bf-cycle 2").
|
|
526444
|
+
*/
|
|
526445
|
+
_runReg61Check(turn, toolCallLog, messages2, cycleLabel) {
|
|
526446
|
+
const REG61_TURN_FLOOR = 4;
|
|
526447
|
+
const REG61_MIN_READS = 3;
|
|
526448
|
+
const REG61_NO_WRITE_GAP = 5;
|
|
526449
|
+
const REG61_COOLDOWN = 5;
|
|
526450
|
+
if (process.env["OA_DISABLE_REG61"] === "1")
|
|
526451
|
+
return;
|
|
526452
|
+
if (turn < REG61_TURN_FLOOR)
|
|
526453
|
+
return;
|
|
526454
|
+
if (turn <= this._reg61CooldownUntilTurn)
|
|
526455
|
+
return;
|
|
526456
|
+
const _writeGate = this._lastFileWriteTurn < 0 || turn - this._lastFileWriteTurn >= REG61_NO_WRITE_GAP;
|
|
526457
|
+
if (!_writeGate)
|
|
526458
|
+
return;
|
|
526459
|
+
const _readClassNames = /* @__PURE__ */ new Set([
|
|
526460
|
+
"file_read",
|
|
526461
|
+
"file_explore",
|
|
526462
|
+
"list_directory",
|
|
526463
|
+
"grep_search",
|
|
526464
|
+
"glob_find",
|
|
526465
|
+
"find_files",
|
|
526466
|
+
"code_neighbors",
|
|
526467
|
+
"repo_map",
|
|
526468
|
+
"codebase_map",
|
|
526469
|
+
"semantic_map",
|
|
526470
|
+
"symbol_search",
|
|
526471
|
+
"todo_read",
|
|
526472
|
+
"memory_read",
|
|
526473
|
+
"memory_search"
|
|
526474
|
+
]);
|
|
526475
|
+
const _editClassNames = /* @__PURE__ */ new Set([
|
|
526476
|
+
"file_write",
|
|
526477
|
+
"file_edit",
|
|
526478
|
+
"batch_edit",
|
|
526479
|
+
"file_patch"
|
|
526480
|
+
]);
|
|
526481
|
+
let _readsInWindow = 0;
|
|
526482
|
+
for (let k = toolCallLog.length - 1; k >= 0; k--) {
|
|
526483
|
+
const _name = toolCallLog[k].name;
|
|
526484
|
+
if (_editClassNames.has(_name))
|
|
526485
|
+
break;
|
|
526486
|
+
if (_readClassNames.has(_name))
|
|
526487
|
+
_readsInWindow++;
|
|
526488
|
+
}
|
|
526489
|
+
if (_readsInWindow < REG61_MIN_READS)
|
|
526490
|
+
return;
|
|
526491
|
+
this._reg61CooldownUntilTurn = turn + REG61_COOLDOWN;
|
|
526492
|
+
if (process.env["OA_DISABLE_REG61_COERCE"] !== "1") {
|
|
526493
|
+
this._reg61BlocksRemaining = 1;
|
|
526494
|
+
}
|
|
526495
|
+
const _gapDesc = this._lastFileWriteTurn < 0 ? `no creative edits yet this run` : `${turn - this._lastFileWriteTurn} turns since last creative edit (turn ${this._lastFileWriteTurn})`;
|
|
526496
|
+
const reg61Msg = `[FIRST-EDIT NUDGE — REG-61]
|
|
526497
|
+
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.
|
|
526498
|
+
|
|
526499
|
+
Your NEXT tool call MUST be EXACTLY ONE of:
|
|
526500
|
+
• file_write — create a new file
|
|
526501
|
+
• file_edit — modify an existing file (find/replace)
|
|
526502
|
+
• batch_edit — multiple find/replace edits in one call
|
|
526503
|
+
• file_patch — apply a unified diff
|
|
526504
|
+
|
|
526505
|
+
These are the ONLY four tools that count as creative edits. The following do NOT count and will NOT satisfy this directive:
|
|
526506
|
+
• todo_write (only updates the todo list, not the filesystem)
|
|
526507
|
+
• memory_write (writes to memory store, not the project)
|
|
526508
|
+
• list_directory / file_read / file_explore / grep_search / shell
|
|
526509
|
+
|
|
526510
|
+
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.`;
|
|
526511
|
+
messages2.push({ role: "system", content: reg61Msg });
|
|
526512
|
+
const _cyclePart = cycleLabel ? ` (${cycleLabel})` : "";
|
|
526513
|
+
this.emit({
|
|
526514
|
+
type: "status",
|
|
526515
|
+
content: `REG-61 FIRST-EDIT NUDGE — fired at turn ${turn}${_cyclePart}; reads_in_window=${_readsInWindow}; ${_gapDesc}`,
|
|
526516
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
526517
|
+
});
|
|
526518
|
+
}
|
|
526386
526519
|
readSessionTodos() {
|
|
526387
526520
|
try {
|
|
526388
526521
|
const sid = process.env["OA_SESSION_ID"] || this._sessionId || "default";
|
|
@@ -528197,6 +528330,7 @@ Respond with your assessment, then take action.`;
|
|
|
528197
528330
|
this._fileWriteTimestamps = [];
|
|
528198
528331
|
this._aborting = false;
|
|
528199
528332
|
this._reg61CooldownUntilTurn = -1;
|
|
528333
|
+
this._reg61BlocksRemaining = 0;
|
|
528200
528334
|
if (!globalThis.__oa_rca1_sigterm_installed) {
|
|
528201
528335
|
globalThis.__oa_rca1_sigterm_installed = true;
|
|
528202
528336
|
const _sigtermHandler = () => {
|
|
@@ -528620,70 +528754,7 @@ TASK: ${task}` : task;
|
|
|
528620
528754
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
528621
528755
|
});
|
|
528622
528756
|
}
|
|
528623
|
-
|
|
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
|
-
}
|
|
528757
|
+
this._runReg61Check(turn, toolCallLog, messages2);
|
|
528687
528758
|
const REG58_NO_WRITE_BUDGET = 30;
|
|
528688
528759
|
if (turn > stagnationCooldownUntilTurn && this._lastFileWriteTurn >= 0 && turn - this._lastFileWriteTurn >= REG58_NO_WRITE_BUDGET && process.env["OA_DISABLE_REG58"] !== "1") {
|
|
528689
528760
|
const gap = turn - this._lastFileWriteTurn;
|
|
@@ -530288,6 +530359,59 @@ ${memoryLines.join("\n")}`
|
|
|
530288
530359
|
});
|
|
530289
530360
|
}
|
|
530290
530361
|
}
|
|
530362
|
+
const REG61_EDIT_TOOLS = /* @__PURE__ */ new Set([
|
|
530363
|
+
"file_write",
|
|
530364
|
+
"file_edit",
|
|
530365
|
+
"batch_edit",
|
|
530366
|
+
"file_patch"
|
|
530367
|
+
]);
|
|
530368
|
+
if (this._reg61BlocksRemaining > 0 && process.env["OA_DISABLE_REG61_COERCE"] !== "1") {
|
|
530369
|
+
if (REG61_EDIT_TOOLS.has(tc.name)) {
|
|
530370
|
+
this._reg61BlocksRemaining = 0;
|
|
530371
|
+
} else {
|
|
530372
|
+
this._reg61BlocksRemaining--;
|
|
530373
|
+
this.emit({
|
|
530374
|
+
type: "tool_call",
|
|
530375
|
+
toolName: tc.name,
|
|
530376
|
+
toolArgs: tc.arguments,
|
|
530377
|
+
turn,
|
|
530378
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
530379
|
+
});
|
|
530380
|
+
const reg61BlockMsg = [
|
|
530381
|
+
`[BLOCKED — REG-61 directive in effect]`,
|
|
530382
|
+
``,
|
|
530383
|
+
`Your previous turn received a REG-61 FIRST-EDIT NUDGE telling you the next tool call MUST be a creative edit. You issued '${tc.name}' instead, which is a read/explore/shell call. This call has been BLOCKED.`,
|
|
530384
|
+
``,
|
|
530385
|
+
`Issue EXACTLY ONE of these on your next turn:`,
|
|
530386
|
+
` • file_write — create a new file`,
|
|
530387
|
+
` • file_edit — modify an existing file (find/replace)`,
|
|
530388
|
+
` • batch_edit — multiple find/replace edits in one call`,
|
|
530389
|
+
` • file_patch — apply a unified diff`,
|
|
530390
|
+
``,
|
|
530391
|
+
`Pick the smallest concrete change that moves work forward — even a partial stub or a single-line edit counts. Reading more without writing has been demonstrated (in your trailing window) to produce zero deliverables.`,
|
|
530392
|
+
``,
|
|
530393
|
+
`If you genuinely cannot make ANY change without more information (e.g., truly unknown API), call web_search with the specific question. todo_write, list_directory, file_read, file_explore, grep_search, and shell will all be blocked again until an edit lands.`
|
|
530394
|
+
].join("\n");
|
|
530395
|
+
this.emit({
|
|
530396
|
+
type: "tool_result",
|
|
530397
|
+
toolName: tc.name,
|
|
530398
|
+
success: false,
|
|
530399
|
+
content: reg61BlockMsg.slice(0, 120),
|
|
530400
|
+
turn,
|
|
530401
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
530402
|
+
});
|
|
530403
|
+
this.emit({
|
|
530404
|
+
type: "status",
|
|
530405
|
+
content: `REG-61 COERCION BLOCK — rejected '${tc.name}' at turn ${turn}; agent must issue file_write/file_edit/batch_edit/file_patch next`,
|
|
530406
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
530407
|
+
});
|
|
530408
|
+
this._tagSyntheticFailure({
|
|
530409
|
+
mode: "step_repetition",
|
|
530410
|
+
rationale: `REG-61 coercion block on '${tc.name}' — agent ignored FIRST-EDIT NUDGE`
|
|
530411
|
+
});
|
|
530412
|
+
return { tc, output: reg61BlockMsg };
|
|
530413
|
+
}
|
|
530414
|
+
}
|
|
530291
530415
|
const PROGRESS_GATE_BYPASS_TOOLS = /* @__PURE__ */ new Set([
|
|
530292
530416
|
"todo_write",
|
|
530293
530417
|
"todo_read",
|
|
@@ -532118,6 +532242,7 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
|
|
|
532118
532242
|
content: `Re-engaging — cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} tool calls so far)`,
|
|
532119
532243
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
532120
532244
|
});
|
|
532245
|
+
this._reg61CooldownUntilTurn = -1;
|
|
532121
532246
|
messages2.push({
|
|
532122
532247
|
role: "user",
|
|
532123
532248
|
content: `[CONTINUATION — Cycle ${bruteForceCycle}]
|
|
@@ -532151,6 +532276,7 @@ You have ${this.options.maxTurns} more turns. Continue making progress. Call tas
|
|
|
532151
532276
|
this.emit({ type: "error", content: "Task aborted by user", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
532152
532277
|
break;
|
|
532153
532278
|
}
|
|
532279
|
+
this._runReg61Check(turn, toolCallLog, messages2, `bf-cycle ${bruteForceCycle}`);
|
|
532154
532280
|
const bfNow = Date.now();
|
|
532155
532281
|
if (bfNow > nextSelfEval) {
|
|
532156
532282
|
selfEvalCount++;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
3
|
+
"version": "0.187.525",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "open-agents-ai",
|
|
9
|
-
"version": "0.187.
|
|
9
|
+
"version": "0.187.525",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED