natureco-cli 5.4.9 → 5.4.10

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.4.9",
3
+ "version": "5.4.10",
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"
@@ -582,23 +582,97 @@ async function startRepl(args) {
582
582
 
583
583
  const cleanup = async (exitCode = 0) => {
584
584
  if (messages.length > 1) {
585
+ // v5.4.10: Once oturumdaki butun conversation'i memory'ye persist et
586
+ // Bu, Parton'un "oturum sonunda konusmalar kaydedilmiyor" sikayetini cözüyor
587
+ const persistResult = await persistSessionToMemory(messages, memory, cfg);
588
+ if (persistResult && persistResult.factsAdded > 0) {
589
+ console.log(chalk.gray(`\n 🧠 ${persistResult.factsAdded} yeni fact memory'ye kaydedildi`));
590
+ }
591
+ if (persistResult && persistResult.preferencesAdded > 0) {
592
+ console.log(chalk.gray(` 🎯 ${persistResult.preferencesAdded} yeni tercih kaydedildi`));
593
+ }
594
+
585
595
  const sessId = saveSession(messages, {
586
596
  provider: providerUrl, model, user: cfg.userName,
587
597
  bot: memory.botName, factCount: memory.facts?.length || 0,
588
598
  });
589
- // Fact extraction (konuşmadan öğren)
590
- const newFacts = extractFacts(messages, memory.facts || []);
591
- if (newFacts.length > 0) {
592
- memory.facts = [...(memory.facts || []), ...newFacts];
593
- saveMemory(cfg.userName, memory);
594
- console.log(chalk.gray(`\n 🧠 ${newFacts.length} yeni fact öğrenildi ve memory'ye eklendi`));
595
- }
596
599
  console.log(chalk.gray(`\n 💾 Oturum kaydedildi: ${sessId}`));
597
600
  }
601
+ // Global buffer temizle
602
+ if (global._fixBuffer) global._fixBuffer = '';
598
603
  console.log(chalk.gray('\n 👋 Görüşürüz!\n'));
599
604
  process.exit(exitCode);
600
605
  };
601
606
 
607
+ /**
608
+ * v5.4.10: Oturum sonunda conversation'dan otomatik fact/preference extraction
609
+ * Bu, kullanıcının "her çıkışta konuşmalar kaydedilmiyor" sikayetini çözer
610
+ */
611
+ async function persistSessionToMemory(messages, memory, cfg) {
612
+ let factsAdded = 0;
613
+ let preferencesAdded = 0;
614
+
615
+ try {
616
+ // Pattern-based extraction (zaten extractFacts var)
617
+ const newFacts = extractFacts(messages, memory.facts || []);
618
+
619
+ // Bazi user message'lari da tara - 'Parton', 'Ichigo', 'patron', 'CEO' gecerse ekle
620
+ const userMessages = messages.filter(m => m.role === 'user' && !m._internal);
621
+ for (const msg of userMessages) {
622
+ const text = (msg.content || '').toLowerCase();
623
+
624
+ // BotName hatirlatmasi
625
+ if (text.includes('ichigo') && text.includes('ad')) {
626
+ if (memory.botName !== 'İchigo') {
627
+ memory.botName = 'İchigo';
628
+ }
629
+ }
630
+
631
+ // Patron/partnership
632
+ if ((text.includes('patron') || text.includes('patronum')) && text.length < 100) {
633
+ const fact = 'Kullanici benim patronum, ona patron diye hitap etmeliyim';
634
+ if (!(memory.facts || []).some(f => f.value === fact)) {
635
+ newFacts.push({ value: fact, score: 8, category: 'personal', createdAt: new Date().toISOString() });
636
+ }
637
+ }
638
+
639
+ // NatureCo CEO
640
+ if (text.includes('natureco') && text.includes('ceo')) {
641
+ const fact = "Kullanici NatureCo CEO'sudur";
642
+ if (!(memory.facts || []).some(f => f.value === fact)) {
643
+ newFacts.push({ value: fact, score: 9, category: 'work', createdAt: new Date().toISOString() });
644
+ }
645
+ }
646
+ }
647
+
648
+ // Deduplicate
649
+ const existingValues = new Set((memory.facts || []).map(f => (f.value || f).toLowerCase()));
650
+ const uniqueFacts = newFacts.filter(f => !existingValues.has((f.value || f).toLowerCase()));
651
+
652
+ if (uniqueFacts.length > 0) {
653
+ memory.facts = [...(memory.facts || []), ...uniqueFacts];
654
+ // v5.4.10: Verification ile kaydet
655
+ const memFile = path.join(MEMORY_DIR, (cfg.userName || 'default').toLowerCase() + '.json');
656
+ memory.lastUpdated = new Date().toISOString();
657
+ fs.writeFileSync(memFile, JSON.stringify(memory, null, 2), 'utf8');
658
+ // Verification: geri oku
659
+ const verify = JSON.parse(fs.readFileSync(memFile, 'utf8'));
660
+ factsAdded = uniqueFacts.length;
661
+ }
662
+
663
+ // Decay (eski fact'leri dusuk skora dusur)
664
+ if (memory.facts && memory.facts.length > 15) {
665
+ // Max 15 fact tut, en dusuk skorlu olanlari sil
666
+ memory.facts.sort((a, b) => (b.score || 5) - (a.score || 5));
667
+ memory.facts = memory.facts.slice(0, 15);
668
+ }
669
+ } catch (e) {
670
+ // Sessizce devam et, kritik degil
671
+ }
672
+
673
+ return { factsAdded, preferencesAdded };
674
+ }
675
+
602
676
  rl.on('SIGINT', () => cleanup(0));
603
677
  process.on('SIGINT', () => cleanup(0));
604
678
  process.on('SIGTERM', () => cleanup(0));
@@ -748,31 +822,36 @@ async function startRepl(args) {
748
822
  providerApiKey,
749
823
  apiMessages,
750
824
  model,
751
- // Text chunk callback — v5.4.9: streaming buffer + fix
752
- // Streaming'de cümleler chunk'lar arasinda bolunur ("Ben " + "NatureCo " + "CLI").
753
- // Buffer biriktir, cumle tamamlaninca (. ! ? veya newline) fix uygula.
825
+ // Text chunk callback — v5.4.10: streaming buffer + akıllı fix
826
+ // v5.4.10 FIX: "MiniMax" pattern'inde "[\s\-\w\.]*" İchigo kelimesinin sonuna
827
+ // rakam eklemiş (örn "İchigo5"). Simdi daha spesifik pattern kullan.
754
828
  (chunk) => {
755
829
  try {
756
830
  let c = String(chunk || '');
757
- // Eger fixBuffer global'de yoksa olustur
758
831
  if (!global._fixBuffer) global._fixBuffer = '';
759
832
  global._fixBuffer += c;
760
833
 
761
- // Son karakterle karar ver
762
834
  const lastChar = global._fixBuffer.slice(-1);
763
- // Noktalama veya newline varsa, buffer'i isle ve temizle
764
835
  if (/[.!?\n]/.test(lastChar)) {
765
836
  let toProcess = global._fixBuffer;
766
837
  global._fixBuffer = '';
767
- // Tum model adlarini İchigo ile degistir
768
- toProcess = toProcess.replace(/MiniMax[\s\-\w\.]*/g, 'İchigo');
769
- toProcess = toProcess.replace(/Claude[\s\-\w\.]*/g, 'İchigo');
770
- toProcess = toProcess.replace(/GPT[\s\-\w\.]*/g, 'İchigo');
771
- toProcess = toProcess.replace(/ChatGPT/g, 'İchigo');
772
- toProcess = toProcess.replace(/Ben\s+(?:MiniMax|Claude|GPT|NatureCo\s+CLI|bir\s+AI)[^\n.!?]*/gi, 'Ben İchigo');
838
+ // v5.4.10: Daha spesifik pattern - sadece tam model adlari
839
+ toProcess = toProcess.replace(/\bMiniMax-M[\d.]+\b/gi, 'İchigo');
840
+ toProcess = toProcess.replace(/\bMiniMaxM[\d.]+\b/gi, 'İchigo');
841
+ toProcess = toProcess.replace(/\bMiniMax M[\d.]+\b/gi, 'İchigo');
842
+ // "NatureCo CLI" tam ifadesi
843
+ toProcess = toProcess.replace(/\bNatureCo\s+CLI\b/g, 'İchigo');
844
+ toProcess = toProcess.replace(/\bClaude-[\d.]+\b/gi, 'İchigo');
845
+ toProcess = toProcess.replace(/\bGPT-[\d.]+\b/gi, 'İchigo');
846
+ toProcess = toProcess.replace(/\bChatGPT\b/g, 'İchigo');
847
+ // "Ben X" pattern — sadece belirli kelimeler
848
+ toProcess = toProcess.replace(/Ben\s+MiniMax[-M][\w\.]*/gi, 'Ben İchigo');
849
+ toProcess = toProcess.replace(/Ben\s+Claude[-]?[\d\w\.]*/gi, 'Ben İchigo');
850
+ toProcess = toProcess.replace(/Ben\s+GPT[-]?[\d\w\.]*/gi, 'Ben İchigo');
851
+ toProcess = toProcess.replace(/Ben\s+bir\s+yapay\s+zeka/gi, 'Ben İchigo');
852
+ toProcess = toProcess.replace(/Ben\s+İchigo\d+/g, 'Ben İchigo'); // İchigo5 → İchigo
773
853
  process.stdout.write(toProcess);
774
854
  }
775
- // Noktalama yoksa, sadece bekle (sonraki chunk'ta tamamlanir)
776
855
  } catch (e) {
777
856
  process.stdout.write(chunk);
778
857
  }