natureco-cli 5.9.0 → 5.9.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "5.9.0",
3
+ "version": "5.9.1",
4
4
  "description": "OpenClaw'dan daha güvenli, daha hızlı, daha ucuz AI agent CLI. Multi-agent, self-evolving skills, audit log, maliyet optimizasyonu ve NatureCo platform-native.",
5
5
  "bin": {
6
6
  "natureco": "bin/natureco.js"
@@ -279,7 +279,7 @@ async function sendStreaming(providerUrl, providerApiKey, messages, model, onChu
279
279
  let currentMessages = messages;
280
280
  let fullText = '';
281
281
  let iterations = 0;
282
- const MAX_TOOL_ITERATIONS = 5;
282
+ const MAX_TOOL_ITERATIONS = isMM ? 12 : 8;
283
283
  const MAX_CONTEXT_TOKENS = 32000; // safety limit before compression
284
284
 
285
285
  // v5.7.18: Preflight compression — if context too long, compress middle messages
@@ -497,6 +497,25 @@ async function processToolCalls(toolCalls, onToolCall) {
497
497
  if (onToolCall) onToolCall({ name: '_no_progress', args: null, status: 'done', result: { error: 'All tools failed this iteration' } });
498
498
  }
499
499
 
500
+ // Same-tool loop detection: if same tool called >3x this iteration (regardless of success)
501
+ const toolCallCounts = {};
502
+ for (const { name } of results) {
503
+ toolCallCounts[name] = (toolCallCounts[name] || 0) + 1;
504
+ }
505
+ for (const [name, count] of Object.entries(toolCallCounts)) {
506
+ if (count > 3) {
507
+ const loopResult = results.find(r => r.name === name);
508
+ if (loopResult && !loopResult.result?.error) {
509
+ const warnContent = JSON.stringify({
510
+ _loop_warning: true,
511
+ message: `${name} called ${count}x this turn. If you're not making progress, try a different approach or report the result.`,
512
+ tool: name, call_count: count,
513
+ });
514
+ results.push({ name: '_loop_warning', id: `loop_${Date.now()}`, result: { result: warnContent } });
515
+ }
516
+ }
517
+ }
518
+
500
519
  // Notify UI done + build messages
501
520
  const messages = [];
502
521
  for (const { name, id, result } of results) {
@@ -14,6 +14,7 @@ const IDEMPOTENT_TOOLS = new Set([
14
14
  'web_search', 'web_readability', 'duckduckgo_search',
15
15
  'exa_search', 'searxng_search', 'firecrawl',
16
16
  'memory_search', 'memory', 'list_dir',
17
+ 'browser', // browser snapshots are idempotent
17
18
  ]);
18
19
 
19
20
  const MUTATING_TOOLS = new Set([