open-agents-ai 0.187.472 → 0.187.474

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
@@ -520540,6 +520540,8 @@ TASK: ${task}` : task;
520540
520540
  let sameToolFailStreak = 0;
520541
520541
  let sameToolFailName = null;
520542
520542
  const recentToolResults = /* @__PURE__ */ new Map();
520543
+ const dedupHitCount = /* @__PURE__ */ new Map();
520544
+ const DEDUP_ESCALATION_THRESHOLD = 3;
520543
520545
  const toolCallBudget = /* @__PURE__ */ new Map();
520544
520546
  const loopTier = this.options.modelTier ?? "large";
520545
520547
  const toolBudgets = loopTier === "small" ? { web_search: 6, web_fetch: 4, list_directory: 12, find_files: 10, grep_search: 12 } : loopTier === "medium" ? { web_search: 10, web_fetch: 8, list_directory: 18, find_files: 14, grep_search: 18 } : { web_search: 20, web_fetch: 15, list_directory: 30, find_files: 20, grep_search: 30 };
@@ -521417,9 +521419,32 @@ ${cachedEntry2.result.slice(0, 500)}` : `[BLOCKED — the observer confirmed thi
521417
521419
  turn,
521418
521420
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
521419
521421
  });
521422
+ const hits = (dedupHitCount.get(toolFingerprint) ?? 0) + 1;
521423
+ dedupHitCount.set(toolFingerprint, hits);
521424
+ const threshold = tc.name === "shell" ? 2 : DEDUP_ESCALATION_THRESHOLD;
521425
+ if (hits >= threshold) {
521426
+ const argPreview = JSON.stringify(tc.arguments ?? {}).slice(0, 200);
521427
+ const blockMsg = `[FORCED PROGRESS BLOCK — you have called ${tc.name}(${argPreview}) ${hits} times with identical arguments and received the cached result each time. The data is not changing. You are stuck in a read-only loop instead of advancing the plan.
521428
+
521429
+ REQUIRED before this tool will run again with these arguments:
521430
+ • file_write or file_edit, OR
521431
+ • todo_write that advances the plan, OR
521432
+ • task_complete (if all phases are done).
521433
+
521434
+ If you genuinely need this same data again, call a DIFFERENT tool first (one of the three above). Until then, refer to your conversation history — the result of this exact call is already there.]`;
521435
+ this.emit({
521436
+ type: "tool_result",
521437
+ toolName: tc.name,
521438
+ success: false,
521439
+ content: blockMsg.slice(0, 120),
521440
+ turn,
521441
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
521442
+ });
521443
+ return { tc, output: blockMsg };
521444
+ }
521420
521445
  const header = cachedEntry.compacted ? `[RE-SERVED FROM CACHE — the original result was compacted from context. Here is the data again. No need to call this tool again.]
521421
521446
 
521422
- ` : `[DUPLICATE CALL — you already called ${tc.name} with these exact arguments. The result is identical. Do NOT call this again. Use the data you already have to make progress.]
521447
+ ` : `[DUPLICATE CALL #${hits} — you already called ${tc.name} with these exact arguments. The result is identical. Do NOT call this again. Use the data you already have to make progress. One more identical call will trigger a hard progress block.]
521423
521448
 
521424
521449
  `;
521425
521450
  const truncatedCache = cachedEntry.result.length > 500 ? cachedEntry.result.slice(0, 500) + `
@@ -521821,12 +521846,18 @@ ${cachedEntry2.result.slice(0, 500)}` : `[BLOCKED — the observer confirmed thi
521821
521846
  }
521822
521847
  if (isReadLike && result.success) {
521823
521848
  recentToolResults.set(toolFingerprint, { result: (result.output ?? "").slice(0, 2e3), compacted: false });
521824
- if (recentToolResults.size > 50) {
521849
+ if (recentToolResults.size > 500) {
521825
521850
  const firstKey = recentToolResults.keys().next().value;
521826
- if (firstKey !== void 0)
521851
+ if (firstKey !== void 0) {
521827
521852
  recentToolResults.delete(firstKey);
521853
+ dedupHitCount.delete(firstKey);
521854
+ }
521828
521855
  }
521829
521856
  }
521857
+ const isFileMutation = ["file_write", "file_edit", "batch_edit", "file_patch"].includes(tc.name);
521858
+ if (isFileMutation && result.success && dedupHitCount.size > 0) {
521859
+ dedupHitCount.clear();
521860
+ }
521830
521861
  if (result.success) {
521831
521862
  this._recentFailures = this._recentFailures.filter((f2) => f2.fingerprint !== toolFingerprint);
521832
521863
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.472",
3
+ "version": "0.187.474",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.472",
9
+ "version": "0.187.474",
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.472",
3
+ "version": "0.187.474",
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",