open-agents-ai 0.187.467 → 0.187.468
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 +76 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -517859,6 +517859,15 @@ var init_agenticRunner = __esm({
|
|
|
517859
517859
|
// a phase's worth of work without recording progress — and on the next
|
|
517860
517860
|
// turn will replay the same plan. Surface a nudge before that happens.
|
|
517861
517861
|
_writesSinceLastTodoWrite = 0;
|
|
517862
|
+
// REG-12: Progress gate (root-cause enforcement). When ≥6 file writes
|
|
517863
|
+
// have happened without a todo_write call, this latch flips ON. While
|
|
517864
|
+
// the latch is on, every tool call EXCEPT todo_write/todo_read/
|
|
517865
|
+
// task_complete/ask_user is intercepted with a synthetic '[PROGRESS GATE]'
|
|
517866
|
+
// result that forces the agent to update its plan before continuing.
|
|
517867
|
+
// Released when todo_write fires successfully. Without this, the agent
|
|
517868
|
+
// can re-emit the same plan a second time (plan-replay) and execute
|
|
517869
|
+
// duplicate work because PROGRESS NUDGE alone is informational.
|
|
517870
|
+
_progressGateActive = false;
|
|
517862
517871
|
// REG-5: Rolling buffer of recent tool failures with their error output.
|
|
517863
517872
|
// Surfaced before every LLM call so the agent can't ignore "I just ran this
|
|
517864
517873
|
// and it errored". Detects same-fingerprint failure repetition and escalates
|
|
@@ -520429,6 +520438,8 @@ ${memoryLines.join("\n")}`
|
|
|
520429
520438
|
for (const [tool2, budget] of Object.entries(toolBudgets)) {
|
|
520430
520439
|
toolCallBudget.set(tool2, budget);
|
|
520431
520440
|
}
|
|
520441
|
+
this._writesSinceLastTodoWrite = 0;
|
|
520442
|
+
this._progressGateActive = false;
|
|
520432
520443
|
this.emit({
|
|
520433
520444
|
type: "status",
|
|
520434
520445
|
content: `Tool budgets reset for new phase (${Object.keys(toolBudgets).length} tools)`,
|
|
@@ -520436,6 +520447,55 @@ ${memoryLines.join("\n")}`
|
|
|
520436
520447
|
});
|
|
520437
520448
|
}
|
|
520438
520449
|
}
|
|
520450
|
+
const PROGRESS_GATE_BYPASS_TOOLS = /* @__PURE__ */ new Set([
|
|
520451
|
+
"todo_write",
|
|
520452
|
+
"todo_read",
|
|
520453
|
+
"task_complete",
|
|
520454
|
+
"ask_user",
|
|
520455
|
+
"phase_recall"
|
|
520456
|
+
// useful for the agent to consult prior phase state before updating
|
|
520457
|
+
]);
|
|
520458
|
+
if (this._progressGateActive && !PROGRESS_GATE_BYPASS_TOOLS.has(tc.name)) {
|
|
520459
|
+
this.emit({
|
|
520460
|
+
type: "tool_call",
|
|
520461
|
+
toolName: tc.name,
|
|
520462
|
+
toolArgs: tc.arguments,
|
|
520463
|
+
turn,
|
|
520464
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520465
|
+
});
|
|
520466
|
+
const recentWrites = [];
|
|
520467
|
+
for (const [path8, info] of this._worldFacts.files) {
|
|
520468
|
+
if ((info.writeCount ?? 0) > 0 && (info.lastWriteTurn ?? -1) >= 0 && turn - (info.lastWriteTurn ?? 0) <= 8) {
|
|
520469
|
+
recentWrites.push({ path: path8, turn: info.lastWriteTurn ?? 0 });
|
|
520470
|
+
}
|
|
520471
|
+
}
|
|
520472
|
+
recentWrites.sort((a2, b) => b.turn - a2.turn);
|
|
520473
|
+
const showWrites = recentWrites.slice(0, 16);
|
|
520474
|
+
const gateMsg = [
|
|
520475
|
+
`[PROGRESS GATE — call todo_write FIRST before any other tool]`,
|
|
520476
|
+
``,
|
|
520477
|
+
`You have completed ${this._writesSinceLastTodoWrite} file modification${this._writesSinceLastTodoWrite === 1 ? "" : "s"} since your last todo_write call.`,
|
|
520478
|
+
`The next tool call MUST be todo_write to mark progress. This is enforced — non-todo tool calls are intercepted until plan state is updated.`,
|
|
520479
|
+
``,
|
|
520480
|
+
`Recent file modifications (use these to decide what's done):`,
|
|
520481
|
+
...showWrites.map((w) => ` • ${w.path} (turn ${w.turn})`),
|
|
520482
|
+
recentWrites.length > showWrites.length ? ` • ... +${recentWrites.length - showWrites.length} more` : "",
|
|
520483
|
+
``,
|
|
520484
|
+
`Required action: call todo_write with the updated todo array — mark anything completed that these writes satisfy, advance the next item to in_progress, keep the rest pending.`,
|
|
520485
|
+
`After todo_write succeeds, this gate releases and you can continue normal work.`,
|
|
520486
|
+
``,
|
|
520487
|
+
`Why this exists: without the explicit progress update, your next turn will see the same in_progress todo, re-plan the same work, and re-emit identical tool calls (the "plan replay" failure mode that causes byte-identical writes to appear twice).`
|
|
520488
|
+
].filter(Boolean).join("\n");
|
|
520489
|
+
this.emit({
|
|
520490
|
+
type: "tool_result",
|
|
520491
|
+
toolName: tc.name,
|
|
520492
|
+
success: false,
|
|
520493
|
+
content: gateMsg.slice(0, 120),
|
|
520494
|
+
turn,
|
|
520495
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520496
|
+
});
|
|
520497
|
+
return { tc, output: gateMsg };
|
|
520498
|
+
}
|
|
520439
520499
|
const _argsKeyForBudget = `${tc.name}:${argsKey}`;
|
|
520440
520500
|
const _isCachedHit = recentToolResults.has(_argsKeyForBudget);
|
|
520441
520501
|
const budgetRemaining = toolCallBudget.get(tc.name);
|
|
@@ -520654,10 +520714,26 @@ ${cachedEntry2.result.slice(0, 500)}` : `[BLOCKED — the observer confirmed thi
|
|
|
520654
520714
|
writeCount: (prev?.writeCount ?? 0) + 1
|
|
520655
520715
|
});
|
|
520656
520716
|
this._writesSinceLastTodoWrite++;
|
|
520717
|
+
if (this._writesSinceLastTodoWrite >= 6 && !this._progressGateActive) {
|
|
520718
|
+
this._progressGateActive = true;
|
|
520719
|
+
this.emit({
|
|
520720
|
+
type: "status",
|
|
520721
|
+
content: `Progress gate engaged at ${this._writesSinceLastTodoWrite} writes without todo_write — non-todo tools will be blocked until plan is updated`,
|
|
520722
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520723
|
+
});
|
|
520724
|
+
}
|
|
520657
520725
|
}
|
|
520658
520726
|
}
|
|
520659
520727
|
if (tc.name === "todo_write" && result.success) {
|
|
520728
|
+
if (this._progressGateActive) {
|
|
520729
|
+
this.emit({
|
|
520730
|
+
type: "status",
|
|
520731
|
+
content: "Progress gate released — todo_write acknowledged",
|
|
520732
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520733
|
+
});
|
|
520734
|
+
}
|
|
520660
520735
|
this._writesSinceLastTodoWrite = 0;
|
|
520736
|
+
this._progressGateActive = false;
|
|
520661
520737
|
}
|
|
520662
520738
|
if (tc.name === "file_read") {
|
|
520663
520739
|
const p2 = String(tc.arguments?.["path"] ?? tc.arguments?.["file"] ?? "");
|
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.468",
|
|
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.468",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED