natureco-cli 5.41.0 → 5.42.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to NatureCo CLI will be documented in this file.
4
4
 
5
+ ## [5.42.0] - 2026-07-08 — "TOKEN OPTIMİZASYONU: her istekte ~18K token israfı → ~4.5K (%76 azalma)"
6
+
7
+ Kullanıcı token maliyetini sordu; ölçüm yapıldı ve ciddi bir israf bulundu: basit bir "merhaba" bile **18,763 token** prompt gönderiyordu. Kök neden: `skill-index.js` her sysMsg'e YÜZLERCE skill'in TAM `description`'ını gömüyordu (satır 75 `- name: description`), her istekte tekrar.
8
+
9
+ ### ⚡ Token verimliliği (doğrudan maliyet + kullanıcı tercihi)
10
+ - **skill index kompaktlaştırıldı**: eskiden ~200 skill × ~350 char (tam açıklama) = ~75K char = ~18K token HER istekte. Bu progressive-disclosure'a da aykırıydı (skill_view zaten tam açıklama+içerik veriyor). Artık: çok skill (>60) → **kompakt isim-listesi** (kategorili, virgüllü); az skill → isim + kısa açıklama (88 char, kelime sınırı). Uzun "mandatory scan" yönergesi sadeleştirildi.
11
+ - **Yeni env kontrolü** `NATURECO_SKILL_INDEX`: `off` (index hiç gönderilmez, en düşük token) / `names` (sadece isimler) / `full` (kısa açıklamalı, çok skill'de bile).
12
+ - **Ölçülen etki** (gerçek MiniMax usage, monkeypatch ile): basit selam **18,763 → 4,456 token** (%76↓); tek-araç görevi 38,601 → 9,987 token. Çok-iterasyonlu görevlerde tasarruf katlanır (sysMsg her iterasyonda gider).
13
+
14
+ 538 test yeşil (skill-index token regresyonu +5: `_shorten`, off-mode, skill-başına-char sınırı), ESLint temiz. Provider-bağımsız (tüm sysMsg'ler `buildSkillIndex` kullanır).
15
+
5
16
  ## [5.41.0] - 2026-07-08 — "sub-agent orchestration + plan modu PHANTOM idi, açıldı"
6
17
 
7
18
  Kullanıcının "sub-agent orchestration ve plan modunda açık kalmasın" talebiyle: ikisi de mevcut+çalışır kod (`sub_agent.js`, `plan.js`) AMA agentic-runner `DEFAULT_ALLOWED`'da ve workflow sysMsg'inde YOKTU → agent bunları çağıramıyordu (klasik phantom-tool deseni).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "5.41.0",
3
+ "version": "5.42.0",
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"
@@ -58,25 +58,46 @@ function _discoverSkills() {
58
58
  return skills;
59
59
  }
60
60
 
61
+ /**
62
+ * v5.42 TOKEN OPTIMIZASYONU: eskiden her skill'in TAM `description`'i (frontmatter,
63
+ * ~200-500 char) sysMsg'e gomuluyordu → yuzlerce skill'de ~18K token HER istekte
64
+ * (basit "merhaba" bile). Progressive-disclosure'a da aykiri: skill_view zaten tam
65
+ * aciklama+icerik veriyor. Artik index'te KISA aciklama (cok skill varsa daha da kisa);
66
+ * ajan ismi+ozeti gorur, ilgiliyse skill_view(name) ile tam detayi ceker.
67
+ * NATURECO_SKILL_INDEX=names → sadece isimler (en dusuk token); =off → index yok.
68
+ */
69
+ function _shorten(d, max) {
70
+ if (!d) return '';
71
+ const clean = d.replace(/\s+/g, ' ').trim();
72
+ if (clean.length <= max) return clean;
73
+ return clean.slice(0, max).replace(/\s+\S*$/, '') + '…';
74
+ }
75
+
61
76
  function buildSkillIndex() {
77
+ const mode = String(process.env.NATURECO_SKILL_INDEX || '').toLowerCase();
78
+ if (mode === 'off') return '';
62
79
  const skills = _discoverSkills();
63
80
  if (skills.length === 0) return '';
81
+ // Cok skill (>60) → KOMPAKT isim-listesi (kategorili, virgullu): en dusuk token.
82
+ // Az skill → isim + kisa aciklama. Kullanici 'full'/'names' ile ezebilir.
83
+ const many = skills.length > 60;
84
+ const compact = mode === 'names' || (many && mode !== 'full');
64
85
  const byCategory = {};
65
86
  for (const s of skills) {
66
87
  if (!byCategory[s.category]) byCategory[s.category] = [];
67
88
  byCategory[s.category].push(s);
68
89
  }
69
- const lines = ['## Skills (mandatory)'];
70
- lines.push('Before replying, scan the skills below. If a skill matches or is even partially relevant to your task, you MUST load it with skill_view(name) and follow its instructions. Err on the side of loading — it is always better to have context you do not need than to miss critical steps, pitfalls, or established workflows.');
90
+ const lines = ['## Skills (görevinle ilgiliyse skill_view(name) ile yükle — tam açıklama/içerik oradadır)'];
71
91
  lines.push('<available_skills>');
72
92
  for (const [cat, catSkills] of Object.entries(byCategory)) {
73
- lines.push(` ${cat}:`);
74
- for (const s of catSkills) {
75
- lines.push(` - ${s.name}: ${s.description}`);
93
+ if (compact) {
94
+ lines.push(` ${cat}: ${catSkills.map(s => s.name).join(', ')}`);
95
+ } else {
96
+ lines.push(` ${cat}:`);
97
+ for (const s of catSkills) lines.push(` - ${s.name}: ${_shorten(s.description, 88)}`);
76
98
  }
77
99
  }
78
100
  lines.push('</available_skills>');
79
- lines.push('Only proceed without loading a skill if genuinely none are relevant.');
80
101
  return lines.join('\n');
81
102
  }
82
103
 
@@ -124,4 +145,4 @@ function skillsList(category) {
124
145
  });
125
146
  }
126
147
 
127
- module.exports = { buildSkillIndex, skillLookup, skillView, skillsList };
148
+ module.exports = { buildSkillIndex, skillLookup, skillView, skillsList, _shorten, _discoverSkills };