natureco-cli 2.3.2 → 2.4.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/package.json +1 -1
- package/src/commands/dashboard.js +2 -2
- package/src/utils/api.js +63 -11
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.
|
|
214
|
+
<div class="version-badge" id="version-badge">v2.4.0</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.
|
|
344
|
+
version: 'v2.4.0',
|
|
345
345
|
bots: cfg.bots || [],
|
|
346
346
|
telegramToken: cfg.telegramToken || null,
|
|
347
347
|
whatsappConnected: cfg.whatsappConnected || false,
|
package/src/utils/api.js
CHANGED
|
@@ -1,13 +1,48 @@
|
|
|
1
|
-
// NatureCo CLI v2.
|
|
1
|
+
// NatureCo CLI v2.4.0 - Universal LLM Provider Support
|
|
2
2
|
// Supports: OpenAI, Groq, Together, Fireworks, Perplexity, Mistral, DeepSeek, OpenRouter, Ollama, LM Studio, Anthropic
|
|
3
3
|
|
|
4
|
+
const fs = require('fs');
|
|
4
5
|
const os = require('os');
|
|
6
|
+
const path = require('path');
|
|
5
7
|
const { getConfig } = require('./config');
|
|
6
8
|
const { getToolDefinitions, executeToolCalls } = require('./tool-runner');
|
|
7
9
|
|
|
8
|
-
//
|
|
10
|
+
// Persistent conversation directory
|
|
11
|
+
const CONV_DIR = path.join(os.homedir(), '.natureco', 'conversations');
|
|
12
|
+
|
|
13
|
+
// Conversation history for multi-turn chat (deprecated - now using disk storage)
|
|
9
14
|
const conversationHistory = new Map();
|
|
10
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Load conversation from disk
|
|
18
|
+
*/
|
|
19
|
+
function loadConversation(convId) {
|
|
20
|
+
const file = path.join(CONV_DIR, `${convId.replace(/[^a-z0-9]/gi, '_')}.json`);
|
|
21
|
+
try {
|
|
22
|
+
fs.mkdirSync(CONV_DIR, { recursive: true });
|
|
23
|
+
if (fs.existsSync(file)) {
|
|
24
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
} catch (e) {
|
|
27
|
+
// Silently fail
|
|
28
|
+
}
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Save conversation to disk
|
|
34
|
+
*/
|
|
35
|
+
function saveConversation(convId, messages) {
|
|
36
|
+
const file = path.join(CONV_DIR, `${convId.replace(/[^a-z0-9]/gi, '_')}.json`);
|
|
37
|
+
try {
|
|
38
|
+
fs.mkdirSync(CONV_DIR, { recursive: true });
|
|
39
|
+
// Keep only last 20 messages
|
|
40
|
+
fs.writeFileSync(file, JSON.stringify(messages.slice(-20), null, 2));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
// Silently fail
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
11
46
|
/**
|
|
12
47
|
* Check if debug mode is enabled
|
|
13
48
|
*/
|
|
@@ -182,12 +217,9 @@ async function sendMessageToProvider(apiKey, message, conversationId = null, sys
|
|
|
182
217
|
);
|
|
183
218
|
}
|
|
184
219
|
|
|
185
|
-
// Get or create conversation history
|
|
220
|
+
// Get or create conversation history (load from disk)
|
|
186
221
|
const convId = conversationId || `conv_${Date.now()}`;
|
|
187
|
-
|
|
188
|
-
conversationHistory.set(convId, []);
|
|
189
|
-
}
|
|
190
|
-
const history = conversationHistory.get(convId);
|
|
222
|
+
const history = loadConversation(convId);
|
|
191
223
|
|
|
192
224
|
// Build messages
|
|
193
225
|
const messages = [];
|
|
@@ -276,10 +308,8 @@ async function sendMessageToProvider(apiKey, message, conversationId = null, sys
|
|
|
276
308
|
history.push({ role: 'user', content: message });
|
|
277
309
|
history.push({ role: 'assistant', content: finalResponse });
|
|
278
310
|
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
conversationHistory.set(convId, history.slice(-20));
|
|
282
|
-
}
|
|
311
|
+
// Save to disk (automatically keeps last 20 messages)
|
|
312
|
+
saveConversation(convId, history);
|
|
283
313
|
|
|
284
314
|
return {
|
|
285
315
|
reply: finalResponse,
|
|
@@ -294,8 +324,30 @@ async function sendMessageToProvider(apiKey, message, conversationId = null, sys
|
|
|
294
324
|
*/
|
|
295
325
|
function clearConversation(conversationId) {
|
|
296
326
|
if (conversationId) {
|
|
327
|
+
// Delete from disk
|
|
328
|
+
const file = path.join(CONV_DIR, `${conversationId.replace(/[^a-z0-9]/gi, '_')}.json`);
|
|
329
|
+
try {
|
|
330
|
+
if (fs.existsSync(file)) {
|
|
331
|
+
fs.unlinkSync(file);
|
|
332
|
+
}
|
|
333
|
+
} catch (e) {
|
|
334
|
+
// Silently fail
|
|
335
|
+
}
|
|
336
|
+
// Also clear from memory (legacy)
|
|
297
337
|
conversationHistory.delete(conversationId);
|
|
298
338
|
} else {
|
|
339
|
+
// Clear all conversations from disk
|
|
340
|
+
try {
|
|
341
|
+
if (fs.existsSync(CONV_DIR)) {
|
|
342
|
+
const files = fs.readdirSync(CONV_DIR);
|
|
343
|
+
files.forEach(file => {
|
|
344
|
+
fs.unlinkSync(path.join(CONV_DIR, file));
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
} catch (e) {
|
|
348
|
+
// Silently fail
|
|
349
|
+
}
|
|
350
|
+
// Also clear from memory (legacy)
|
|
299
351
|
conversationHistory.clear();
|
|
300
352
|
}
|
|
301
353
|
}
|