natureco-cli 5.4.8 → 5.4.9
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 +34 -11
- package/src/tools/memory_write.js +56 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.9",
|
|
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
|
@@ -728,6 +728,17 @@ async function startRepl(args) {
|
|
|
728
728
|
// User mesajı
|
|
729
729
|
messages.push({ role: 'user', content: line });
|
|
730
730
|
|
|
731
|
+
// v5.4.9: Hard-coded fallback — "sen kimsin?" gibi sorular icin model cevabindan once prefix
|
|
732
|
+
const trimmed = (line || '').toLowerCase();
|
|
733
|
+
const isIdentityQuestion = /(sen\s+kim|adin\s+ne|kendini\s+tan|kendin\s+tanit|kimsin|ne\s+adindasin)/.test(trimmed);
|
|
734
|
+
if (isIdentityQuestion) {
|
|
735
|
+
// Hard-coded "Ben İchigo" — model cevap verse bile onemli degil, bu gorunur
|
|
736
|
+
process.stdout.write(tui.styled('\n AI ', { color: tui.PALETTE.secondary, bold: true }));
|
|
737
|
+
process.stdout.write('Ben İchigo, NatureCo CLI\'nin Türkçe yapay zeka asistanıyım. ');
|
|
738
|
+
// Modelin devam etmesini beklemiyoruz, normal akis devam etsin
|
|
739
|
+
console.log('\n');
|
|
740
|
+
}
|
|
741
|
+
|
|
731
742
|
// AI cevabı
|
|
732
743
|
process.stdout.write(tui.styled('\n AI ', { color: tui.PALETTE.secondary, bold: true }));
|
|
733
744
|
try {
|
|
@@ -737,19 +748,31 @@ async function startRepl(args) {
|
|
|
737
748
|
providerApiKey,
|
|
738
749
|
apiMessages,
|
|
739
750
|
model,
|
|
740
|
-
// Text chunk callback — v5.4.
|
|
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.
|
|
741
754
|
(chunk) => {
|
|
742
755
|
try {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
756
|
+
let c = String(chunk || '');
|
|
757
|
+
// Eger fixBuffer global'de yoksa olustur
|
|
758
|
+
if (!global._fixBuffer) global._fixBuffer = '';
|
|
759
|
+
global._fixBuffer += c;
|
|
760
|
+
|
|
761
|
+
// Son karakterle karar ver
|
|
762
|
+
const lastChar = global._fixBuffer.slice(-1);
|
|
763
|
+
// Noktalama veya newline varsa, buffer'i isle ve temizle
|
|
764
|
+
if (/[.!?\n]/.test(lastChar)) {
|
|
765
|
+
let toProcess = global._fixBuffer;
|
|
766
|
+
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');
|
|
773
|
+
process.stdout.write(toProcess);
|
|
774
|
+
}
|
|
775
|
+
// Noktalama yoksa, sadece bekle (sonraki chunk'ta tamamlanir)
|
|
753
776
|
} catch (e) {
|
|
754
777
|
process.stdout.write(chunk);
|
|
755
778
|
}
|
|
@@ -58,16 +58,54 @@ function decayFacts(memory) {
|
|
|
58
58
|
return memory;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* v5.4.9: Memory yazma sonrasi verification — geri oku ve gercekten yazildigini dogrula
|
|
64
|
+
* Self-validation mekanizmasi: tool cagirip "success" demesine ragmen dosya bos olabilir
|
|
65
|
+
*/
|
|
66
|
+
function verifyMemoryWrite(username, expectedFact, expectedBotName) {
|
|
67
|
+
try {
|
|
68
|
+
const memFile = getMemoryFile(username);
|
|
69
|
+
if (!fs.existsSync(memFile)) {
|
|
70
|
+
return { success: false, error: "Memory dosyasi olusturulamadi: " + memFile };
|
|
71
|
+
}
|
|
72
|
+
const mem = JSON.parse(fs.readFileSync(memFile, "utf8"));
|
|
73
|
+
|
|
74
|
+
// Fact verification
|
|
75
|
+
if (expectedFact) {
|
|
76
|
+
const found = (mem.facts || []).some(f => f.value === expectedFact);
|
|
77
|
+
if (!found) {
|
|
78
|
+
return { success: false, error: "Fact memory'de bulunamadi: " + expectedFact };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// BotName verification
|
|
83
|
+
if (expectedBotName && mem.botName !== expectedBotName) {
|
|
84
|
+
return { success: false, error: "BotName guncellenmedi: " + mem.botName };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { success: true, message: "Memory dogrulandi" };
|
|
88
|
+
} catch (e) {
|
|
89
|
+
return { success: false, error: e.message };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
61
94
|
function addMemory({ username, fact, score = 5, category = "general", botName, nickname, name }) {
|
|
62
|
-
|
|
95
|
+
// Username yoksa ve 'name' parametresi varsa, onu username olarak kullan
|
|
96
|
+
// (Parton'un "patron" diye hitap etmesi durumu icin)
|
|
97
|
+
const effectiveUsername = username || (name && name.toLowerCase()) || 'default';
|
|
98
|
+
if (!effectiveUsername || effectiveUsername === 'default') {
|
|
99
|
+
// Hicbir username yok, default.json'a yaz
|
|
100
|
+
}
|
|
63
101
|
|
|
64
|
-
let memory = loadMemory(
|
|
102
|
+
let memory = loadMemory(effectiveUsername);
|
|
65
103
|
memory = decayFacts(memory);
|
|
66
104
|
|
|
67
|
-
// identity updates (botName, nickname, name)
|
|
105
|
+
// identity updates (botName, nickname, name) — name sadece memory.name, username degil
|
|
68
106
|
if (botName) memory.botName = botName;
|
|
69
107
|
if (nickname !== undefined) memory.nickname = nickname;
|
|
70
|
-
if (name) memory.name = name;
|
|
108
|
+
if (name) memory.name = name; // Bu memory.name (kullanici gercek adi), username degil
|
|
71
109
|
|
|
72
110
|
if (fact) {
|
|
73
111
|
// duplicate kontrol
|
|
@@ -87,12 +125,23 @@ function addMemory({ username, fact, score = 5, category = "general", botName, n
|
|
|
87
125
|
}
|
|
88
126
|
|
|
89
127
|
if (!memory.preferences) memory.preferences = [];
|
|
90
|
-
memory = saveMemory(
|
|
128
|
+
memory = saveMemory(effectiveUsername, memory);
|
|
129
|
+
|
|
130
|
+
// v5.4.9: Verification - geri oku ve dogrula
|
|
131
|
+
const verifyResult = verifyMemoryWrite(effectiveUsername, fact, botName);
|
|
132
|
+
if (!verifyResult.success) {
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
error: "Memory yazildi ama dogrulanamadi: " + verifyResult.error,
|
|
136
|
+
username: effectiveUsername,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
91
139
|
|
|
92
140
|
return {
|
|
93
141
|
success: true,
|
|
94
|
-
message: "Memory guncellendi",
|
|
95
|
-
username,
|
|
142
|
+
message: "Memory guncellendi ve dogrulandi",
|
|
143
|
+
username: effectiveUsername,
|
|
144
|
+
verified: true,
|
|
96
145
|
totalFacts: memory.facts.length,
|
|
97
146
|
facts: memory.facts.map(f => ({ value: f.value, score: f.score, category: f.category })),
|
|
98
147
|
botName: memory.botName,
|