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 +1 -1
- package/src/commands/repl.js +99 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "5.4.
|
|
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"
|
package/src/commands/repl.js
CHANGED
|
@@ -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.
|
|
752
|
-
//
|
|
753
|
-
//
|
|
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
|
-
//
|
|
768
|
-
toProcess = toProcess.replace(
|
|
769
|
-
toProcess = toProcess.replace(
|
|
770
|
-
toProcess = toProcess.replace(
|
|
771
|
-
|
|
772
|
-
toProcess = toProcess.replace(
|
|
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
|
}
|