natureco-cli 2.13.16 → 2.13.18
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/dashboard.js +2 -2
- package/src/commands/migrate.js +26 -0
- package/src/utils/api.js +0 -49
- package/src/utils/memory.js +17 -9
package/package.json
CHANGED
|
@@ -211,7 +211,7 @@ body::before{
|
|
|
211
211
|
<div class="header-bot-name" id="header-bot-name">Nature Bot</div>
|
|
212
212
|
<div class="header-bot-model" id="header-bot-model">NatureCo</div>
|
|
213
213
|
</div>
|
|
214
|
-
<div class="version-badge" id="version-badge">v2.13.
|
|
214
|
+
<div class="version-badge" id="version-badge">v2.13.18</div>
|
|
215
215
|
</div>
|
|
216
216
|
<div class="messages" id="messages"></div>
|
|
217
217
|
<div class="input-area">
|
|
@@ -341,7 +341,7 @@ function dashboard(action) {
|
|
|
341
341
|
apiKey: cfg.apiKey,
|
|
342
342
|
defaultBot: cfg.defaultBot,
|
|
343
343
|
defaultBotId: cfg.defaultBotId,
|
|
344
|
-
version: 'v2.13.
|
|
344
|
+
version: 'v2.13.18',
|
|
345
345
|
bots: cfg.bots || [],
|
|
346
346
|
telegramToken: cfg.telegramToken || null,
|
|
347
347
|
whatsappConnected: cfg.whatsappConnected || false,
|
package/src/commands/migrate.js
CHANGED
|
@@ -74,9 +74,12 @@ async function migrate(options) {
|
|
|
74
74
|
const nameMatch = userMd.match(/Name:\s*(.+)/i);
|
|
75
75
|
const timezoneMatch = userMd.match(/Timezone:\s*(.+)/i);
|
|
76
76
|
const notesMatch = userMd.match(/Notes:\s*(.+)/i);
|
|
77
|
+
const nicknameMatch = userMd.match(/What to call them:\s*\*\*(.+?)\*\*/i);
|
|
77
78
|
|
|
78
79
|
const memory = {
|
|
79
80
|
name: nameMatch ? nameMatch[1].trim() : null,
|
|
81
|
+
nickname: nicknameMatch ? nicknameMatch[1].trim() : null,
|
|
82
|
+
botName: null, // Will be extracted from MEMORY.md
|
|
80
83
|
facts: []
|
|
81
84
|
};
|
|
82
85
|
|
|
@@ -85,6 +88,10 @@ async function migrate(options) {
|
|
|
85
88
|
memory.name = memory.name.replace(/\*\*/g, '').trim();
|
|
86
89
|
}
|
|
87
90
|
|
|
91
|
+
if (memory.nickname) {
|
|
92
|
+
memory.nickname = memory.nickname.replace(/\*\*/g, '').trim();
|
|
93
|
+
}
|
|
94
|
+
|
|
88
95
|
if (timezoneMatch) {
|
|
89
96
|
let timezone = timezoneMatch[1].trim().replace(/\*\*/g, '').trim();
|
|
90
97
|
addUniqueFact(memory.facts, {
|
|
@@ -137,6 +144,25 @@ async function migrate(options) {
|
|
|
137
144
|
try {
|
|
138
145
|
const content = fs.readFileSync(file, 'utf8');
|
|
139
146
|
|
|
147
|
+
// Extract bot name from MEMORY.md (first file only)
|
|
148
|
+
if (!memory.botName && file === mainMemoryPath) {
|
|
149
|
+
// Try multiple patterns for bot name
|
|
150
|
+
const botNamePatterns = [
|
|
151
|
+
/[İI]sim:\s*([^\n]+)/, // İsim: İchigo
|
|
152
|
+
/Ben[,\s]+([A-ZÇĞİÖŞÜ][a-zçğıöşü]+)/, // Ben, İchigo
|
|
153
|
+
/Adım[,\s]+([A-ZÇĞİÖŞÜ][a-zçğıöşü]+)/, // Adım İchigo
|
|
154
|
+
/Ben\s+([A-ZÇĞİÖŞÜ][a-zçğıöşü]+)['']?[ıi]m/ // Ben İchigo'yum
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
for (const pattern of botNamePatterns) {
|
|
158
|
+
const match = content.match(pattern);
|
|
159
|
+
if (match) {
|
|
160
|
+
memory.botName = match[1].trim().replace(/\*\*/g, '').trim();
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
140
166
|
// Extract meaningful lines (skip headers, empty lines, useless patterns)
|
|
141
167
|
const lines = content.split('\n')
|
|
142
168
|
.filter(l => l.trim() && !l.startsWith('#'))
|
package/src/utils/api.js
CHANGED
|
@@ -207,14 +207,6 @@ function coerceMcpParams(tool, params) {
|
|
|
207
207
|
tool.parameters?.properties || // fallback
|
|
208
208
|
{};
|
|
209
209
|
|
|
210
|
-
// Debug: Show which schema format was found
|
|
211
|
-
console.log('[DEBUG] COERCE TOOL:', tool.name);
|
|
212
|
-
console.log('[DEBUG] COERCE SCHEMA SOURCE:',
|
|
213
|
-
tool.inputSchema?.properties ? 'inputSchema.properties' :
|
|
214
|
-
tool.input_schema?.properties ? 'input_schema.properties' :
|
|
215
|
-
tool.parameters?.properties ? 'parameters.properties' : 'NONE');
|
|
216
|
-
console.log('[DEBUG] COERCE SCHEMA:', JSON.stringify(schema).slice(0, 200));
|
|
217
|
-
|
|
218
210
|
const coerced = { ...params };
|
|
219
211
|
|
|
220
212
|
for (const [key, def] of Object.entries(schema)) {
|
|
@@ -225,14 +217,12 @@ function coerceMcpParams(tool, params) {
|
|
|
225
217
|
const num = Number(coerced[key]);
|
|
226
218
|
if (!isNaN(num)) {
|
|
227
219
|
coerced[key] = num;
|
|
228
|
-
console.log('[DEBUG] COERCED', key, 'from string to number:', coerced[key]);
|
|
229
220
|
}
|
|
230
221
|
}
|
|
231
222
|
|
|
232
223
|
// Coerce boolean
|
|
233
224
|
if (def.type === 'boolean' && typeof coerced[key] === 'string') {
|
|
234
225
|
coerced[key] = coerced[key] === 'true' || coerced[key] === '1';
|
|
235
|
-
console.log('[DEBUG] COERCED', key, 'from string to boolean:', coerced[key]);
|
|
236
226
|
}
|
|
237
227
|
}
|
|
238
228
|
|
|
@@ -243,8 +233,6 @@ function coerceMcpParams(tool, params) {
|
|
|
243
233
|
* Execute MCP tool call
|
|
244
234
|
*/
|
|
245
235
|
async function executeMcpTool(toolName, toolArgs) {
|
|
246
|
-
console.log('[DEBUG] EXECUTING MCP TOOL:', toolName, 'Args:', JSON.stringify(toolArgs).slice(0, 100));
|
|
247
|
-
|
|
248
236
|
// Find which server has this tool
|
|
249
237
|
for (const [serverName, { client, tools }] of Object.entries(mcpClients)) {
|
|
250
238
|
const tool = tools.find(t => t.name === toolName);
|
|
@@ -255,12 +243,9 @@ async function executeMcpTool(toolName, toolArgs) {
|
|
|
255
243
|
try {
|
|
256
244
|
// Coerce parameters to match schema types
|
|
257
245
|
const coercedArgs = coerceMcpParams(tool, toolArgs);
|
|
258
|
-
console.log('[DEBUG] MCP COERCED ARGS:', JSON.stringify(coercedArgs).slice(0, 100));
|
|
259
246
|
|
|
260
247
|
const result = await client.callTool(toolName, coercedArgs);
|
|
261
248
|
|
|
262
|
-
console.log('[DEBUG] MCP RAW RESULT:', JSON.stringify(result).slice(0, 200));
|
|
263
|
-
|
|
264
249
|
// MCP returns { content: [{ type: 'text', text: '...' }] }
|
|
265
250
|
if (result.content && result.content.length > 0) {
|
|
266
251
|
// Extract all text content and join with newlines
|
|
@@ -274,10 +259,8 @@ async function executeMcpTool(toolName, toolArgs) {
|
|
|
274
259
|
// Truncate MCP result to max 1500 characters
|
|
275
260
|
if (output.length > 1500) {
|
|
276
261
|
output = output.slice(0, 1500) + '... (truncated)';
|
|
277
|
-
console.log('[DEBUG] MCP OUTPUT TRUNCATED from', textContents.join('\n').length, 'to 1500 chars');
|
|
278
262
|
}
|
|
279
263
|
|
|
280
|
-
console.log('[DEBUG] MCP FORMATTED OUTPUT:', output.slice(0, 100));
|
|
281
264
|
return {
|
|
282
265
|
success: true,
|
|
283
266
|
output: output
|
|
@@ -291,17 +274,14 @@ async function executeMcpTool(toolName, toolArgs) {
|
|
|
291
274
|
// Truncate fallback output too
|
|
292
275
|
if (fallbackOutput.length > 1500) {
|
|
293
276
|
fallbackOutput = fallbackOutput.slice(0, 1500) + '... (truncated)';
|
|
294
|
-
console.log('[DEBUG] MCP FALLBACK OUTPUT TRUNCATED');
|
|
295
277
|
}
|
|
296
278
|
|
|
297
|
-
console.log('[DEBUG] MCP FALLBACK OUTPUT:', fallbackOutput.slice(0, 100));
|
|
298
279
|
return {
|
|
299
280
|
success: true,
|
|
300
281
|
output: fallbackOutput
|
|
301
282
|
};
|
|
302
283
|
|
|
303
284
|
} catch (err) {
|
|
304
|
-
console.log('[DEBUG] MCP ERROR:', err.message);
|
|
305
285
|
return {
|
|
306
286
|
success: false,
|
|
307
287
|
error: `MCP tool error: ${err.message}`
|
|
@@ -310,7 +290,6 @@ async function executeMcpTool(toolName, toolArgs) {
|
|
|
310
290
|
}
|
|
311
291
|
}
|
|
312
292
|
|
|
313
|
-
console.log('[DEBUG] MCP TOOL NOT FOUND:', toolName);
|
|
314
293
|
return {
|
|
315
294
|
success: false,
|
|
316
295
|
error: `MCP tool not found: ${toolName}`
|
|
@@ -449,10 +428,6 @@ async function sendMessageOpenAICompatible(providerConfig, messages, tools) {
|
|
|
449
428
|
};
|
|
450
429
|
|
|
451
430
|
const bodyStr = JSON.stringify(requestBody);
|
|
452
|
-
console.log('[API] Request size:', bodyStr.length, 'chars, ~', Math.round(bodyStr.length / 4), 'tokens');
|
|
453
|
-
console.log('[API] Messages count:', messages.length);
|
|
454
|
-
console.log('[API] Tools count:', tools?.length || 0);
|
|
455
|
-
console.log('[API] System prompt length:', messages[0]?.content?.length || 0);
|
|
456
431
|
|
|
457
432
|
const response = await fetch(endpoint, {
|
|
458
433
|
method: 'POST',
|
|
@@ -529,16 +504,6 @@ async function sendMessageAnthropic(providerConfig, messages, tools) {
|
|
|
529
504
|
* Send message with tool support (universal)
|
|
530
505
|
*/
|
|
531
506
|
async function sendMessageToProvider(apiKey, message, conversationId = null, systemPrompt = null) {
|
|
532
|
-
// DEBUG: Write system prompt to file for inspection
|
|
533
|
-
try {
|
|
534
|
-
const debugPath = path.join(os.homedir(), '.natureco', 'debug-system-prompt.txt');
|
|
535
|
-
fs.writeFileSync(debugPath, systemPrompt || 'EMPTY');
|
|
536
|
-
console.log('[DEBUG] System prompt written to ~/.natureco/debug-system-prompt.txt');
|
|
537
|
-
console.log('[DEBUG] System prompt length:', (systemPrompt || '').length, 'chars');
|
|
538
|
-
} catch (err) {
|
|
539
|
-
// Silently fail if can't write debug file
|
|
540
|
-
}
|
|
541
|
-
|
|
542
507
|
const providerConfig = getProviderConfig();
|
|
543
508
|
|
|
544
509
|
if (!providerConfig) {
|
|
@@ -617,13 +582,10 @@ async function sendMessageToProvider(apiKey, message, conversationId = null, sys
|
|
|
617
582
|
const mcpTools = getMcpTools();
|
|
618
583
|
const isMcpTool = mcpTools.find(t => t.name === toolCall.name);
|
|
619
584
|
|
|
620
|
-
console.log('[DEBUG] Tool call:', toolCall.name, 'Is MCP?', !!isMcpTool);
|
|
621
|
-
|
|
622
585
|
if (isMcpTool) {
|
|
623
586
|
// Execute MCP tool
|
|
624
587
|
debugLog(`[MCP] Executing tool: ${toolCall.name}`);
|
|
625
588
|
const result = await executeMcpTool(toolCall.name, toolCall.input);
|
|
626
|
-
console.log('[DEBUG] MCP result:', JSON.stringify(result).slice(0, 200));
|
|
627
589
|
toolResults.push({
|
|
628
590
|
id: toolCall.id,
|
|
629
591
|
name: toolCall.name,
|
|
@@ -633,20 +595,15 @@ async function sendMessageToProvider(apiKey, message, conversationId = null, sys
|
|
|
633
595
|
// Execute local tool
|
|
634
596
|
debugLog(`[Local] Executing tool: ${toolCall.name}`);
|
|
635
597
|
const localResults = await executeToolCalls([toolCall]);
|
|
636
|
-
console.log('[DEBUG] Local result:', JSON.stringify(localResults[0]).slice(0, 200));
|
|
637
598
|
toolResults.push(...localResults);
|
|
638
599
|
}
|
|
639
600
|
}
|
|
640
601
|
|
|
641
602
|
// Add tool results to messages (base64 encoded for safety)
|
|
642
603
|
for (const result of toolResults) {
|
|
643
|
-
console.log('[ENCODE]', result.name, 'Result type:', typeof result.result);
|
|
644
|
-
|
|
645
604
|
// Encode tool result (works for both MCP and local tools)
|
|
646
605
|
const encodedContent = encodeToolResult(result.result);
|
|
647
606
|
|
|
648
|
-
console.log('[ENCODE]', result.name, 'Encoded preview:', encodedContent.slice(0, 50));
|
|
649
|
-
|
|
650
607
|
messages.push({
|
|
651
608
|
role: 'tool',
|
|
652
609
|
tool_call_id: result.id,
|
|
@@ -818,12 +775,6 @@ TOOL SELECTION GUIDE:
|
|
|
818
775
|
}
|
|
819
776
|
}
|
|
820
777
|
|
|
821
|
-
// Log system prompt components
|
|
822
|
-
console.log('[API] Base system prompt:', baseSystemPrompt.length, 'chars');
|
|
823
|
-
console.log('[API] MCP prompt:', mcpPrompt.length, 'chars');
|
|
824
|
-
console.log('[API] Skills prompt:', skillsPrompt.length, 'chars');
|
|
825
|
-
console.log('[API] Total system prompt:', systemPrompt.length, 'chars, ~', Math.round(systemPrompt.length / 4), 'tokens');
|
|
826
|
-
|
|
827
778
|
return sendMessageToProvider(apiKey, message, conversationId, systemPrompt);
|
|
828
779
|
}
|
|
829
780
|
|
package/src/utils/memory.js
CHANGED
|
@@ -24,6 +24,7 @@ function loadMemory(botId) {
|
|
|
24
24
|
if (!fs.existsSync(filePath)) {
|
|
25
25
|
return {
|
|
26
26
|
name: '',
|
|
27
|
+
nickname: '',
|
|
27
28
|
botName: '',
|
|
28
29
|
preferences: [],
|
|
29
30
|
facts: [],
|
|
@@ -38,6 +39,7 @@ function loadMemory(botId) {
|
|
|
38
39
|
// Return with safe defaults for all fields
|
|
39
40
|
const memory = {
|
|
40
41
|
name: data.name || '',
|
|
42
|
+
nickname: data.nickname || '',
|
|
41
43
|
botName: data.botName || '',
|
|
42
44
|
preferences: data.preferences || [],
|
|
43
45
|
facts: data.facts || [],
|
|
@@ -56,6 +58,7 @@ function loadMemory(botId) {
|
|
|
56
58
|
} catch {
|
|
57
59
|
return {
|
|
58
60
|
name: '',
|
|
61
|
+
nickname: '',
|
|
59
62
|
botName: '',
|
|
60
63
|
preferences: [],
|
|
61
64
|
facts: [],
|
|
@@ -83,6 +86,8 @@ function addMemoryEntry(botId, key, value) {
|
|
|
83
86
|
|
|
84
87
|
if (key === 'name') {
|
|
85
88
|
memory.name = value;
|
|
89
|
+
} else if (key === 'nickname') {
|
|
90
|
+
memory.nickname = value;
|
|
86
91
|
} else if (key === 'botName') {
|
|
87
92
|
memory.botName = value;
|
|
88
93
|
} else if (key === 'preference') {
|
|
@@ -202,29 +207,35 @@ function getMemoryPrompt(botId) {
|
|
|
202
207
|
|
|
203
208
|
// Safe defaults for all fields
|
|
204
209
|
const name = memory.name || '';
|
|
210
|
+
const nickname = memory.nickname || '';
|
|
205
211
|
const botName = memory.botName || '';
|
|
206
212
|
const preferences = memory.preferences || [];
|
|
207
213
|
const facts = memory.facts || [];
|
|
208
214
|
|
|
209
|
-
if (!name && !botName && preferences.length === 0 && facts.length === 0) {
|
|
210
|
-
return '';
|
|
211
|
-
}
|
|
212
|
-
|
|
213
215
|
const parts = [];
|
|
214
216
|
|
|
215
|
-
// Add bot name if set
|
|
217
|
+
// Add bot name if set (MUST be before empty check)
|
|
216
218
|
if (botName) {
|
|
217
219
|
parts.push(`Your name is ${botName}.`);
|
|
218
220
|
}
|
|
219
221
|
|
|
222
|
+
// Check if there's any content to add
|
|
223
|
+
if (!name && !nickname && !botName && preferences.length === 0 && facts.length === 0) {
|
|
224
|
+
return '';
|
|
225
|
+
}
|
|
226
|
+
|
|
220
227
|
// Add user memory section
|
|
221
|
-
if (name || preferences.length > 0 || facts.length > 0) {
|
|
228
|
+
if (name || nickname || preferences.length > 0 || facts.length > 0) {
|
|
222
229
|
parts.push('## Kullanıcı Hafızası');
|
|
223
230
|
|
|
224
231
|
if (name) {
|
|
225
232
|
parts.push(`İsim: ${name}`);
|
|
226
233
|
}
|
|
227
234
|
|
|
235
|
+
if (nickname) {
|
|
236
|
+
parts.push(`Lakap: ${nickname}`);
|
|
237
|
+
}
|
|
238
|
+
|
|
228
239
|
if (preferences.length > 0) {
|
|
229
240
|
const sorted = preferences.sort((a, b) => b.score - a.score);
|
|
230
241
|
parts.push(`Tercihler: ${sorted.map(p => p.value).join(', ')}`);
|
|
@@ -235,8 +246,6 @@ function getMemoryPrompt(botId) {
|
|
|
235
246
|
const sorted = facts.sort((a, b) => b.score - a.score);
|
|
236
247
|
const topFacts = sorted.slice(0, 15);
|
|
237
248
|
|
|
238
|
-
console.log('[MEMORY] Facts count:', facts.length, '→ showing:', topFacts.length);
|
|
239
|
-
|
|
240
249
|
parts.push(`Bilgiler: ${topFacts.map(f => f.value).join(', ')}`);
|
|
241
250
|
|
|
242
251
|
if (facts.length > 15) {
|
|
@@ -246,7 +255,6 @@ function getMemoryPrompt(botId) {
|
|
|
246
255
|
}
|
|
247
256
|
|
|
248
257
|
const prompt = parts.join('\n');
|
|
249
|
-
console.log('[MEMORY] Prompt length:', prompt.length, 'chars, ~', Math.round(prompt.length / 4), 'tokens');
|
|
250
258
|
|
|
251
259
|
return prompt;
|
|
252
260
|
}
|