natureco-cli 2.17.8 → 2.17.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/commands/chat.js +116 -213
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.17.8",
3
+ "version": "2.17.10",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -1,40 +1,63 @@
1
1
  const path = require('path');
2
2
  const os = require('os');
3
3
  const fs = require('fs');
4
+ const readline = require('readline');
4
5
  const inquirer = require('inquirer');
5
6
  const chalk = require('chalk');
6
7
  const { getApiKey, getConfig } = require('../utils/config');
7
8
  const { getBots, sendMessage, _sendMessage } = require('../utils/api');
8
9
  const { getSkillPrompts, getSkills } = require('../utils/skills');
9
10
  const { getAgentsPrompt } = require('../utils/agents');
10
- const { addToHistory, getCommandHistory } = require('../utils/history');
11
+ const { addToHistory } = require('../utils/history');
11
12
  const { getMemoryPrompt, extractMemoryFromMessage, loadMemory, clearMemory, addMemoryEntry } = require('../utils/memory');
12
13
  const { getCommands, getCommandContent } = require('../utils/commands');
13
14
  const { runHooks } = require('../utils/hooks');
14
15
  const { createSession, loadSession, getLatestSession, addMessageToSession } = require('../utils/sessions');
15
- const { addBackgroundTask, updateBackgroundTask } = require('../utils/background');
16
16
  const { getToolDefinitions, executeToolCalls } = require('../utils/tool-runner');
17
17
  const { extractToolCalls } = require('../utils/tool-adapter');
18
18
 
19
19
  // ── ASCII Logo ────────────────────────────────────────────────────────────────
20
20
  const ASCII_LOGO = [
21
- '{green-fg}███╗ ██╗ █████╗ ████████╗██╗ ██╗██████╗ ███████╗ ██████╗ ██████╗{/}',
22
- '{green-fg}████╗ ██║██╔══██╗╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔════╝ ██╔═══██╗{/}',
23
- '{green-fg}██╔██╗ ██║███████║ ██║ ██║ ██║██████╔╝█████╗ ██║ ██║ ██║{/}',
24
- '{green-fg}██║╚██╗██║██╔══██║ ██║ ██║ ██║██╔══██╗██╔══╝ ██║ ██║ ██║{/}',
25
- '{green-fg}██║ ╚████║██║ ██║ ██║ ╚██████╔╝██║ ██║███████╗╚██████╗ ╚██████╔╝{/}',
26
- '{gray-fg}╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝{/}',
27
- ].join('\n');
21
+ '███╗ ██╗ █████╗ ████████╗██╗ ██╗██████╗ ███████╗ ██████╗ ██████╗',
22
+ '████╗ ██║██╔══██╗╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔════╝ ██╔═══██╗',
23
+ '██╔██╗ ██║███████║ ██║ ██║ ██║██████╔╝█████╗ ██║ ██║ ██║',
24
+ '██║╚██╗██║██╔══██║ ██║ ██║ ██║██╔══██╗██╔══╝ ██║ ██║ ██║',
25
+ '██║ ╚████║██║ ██║ ██║ ╚██████╔╝██║ ██║███████╗╚██████╗ ╚██████╔╝',
26
+ '╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝',
27
+ ];
28
+
29
+ // ── Tips ─────────────────────────────────────────────────────────────────────
30
+ const TIPS = [
31
+ "🌿 Nature.co'da canlı yayın yapabilir, sesli odalarda buluşabilirsin — natureco.me",
32
+ '🤖 NatureBot AI ile içerik üret, topluluğunu yönet, trendi yakala — natureco.me/robot-house',
33
+ '📡 Geliştirici API ile platformu entegre et — natureco.me/developer',
34
+ '🏆 Günlük görevler tamamla, XP kazan, liderlik tablosuna gir — natureco.me',
35
+ "📺 Nature TV'de doğa belgeselleri ve oyun yayınları tek platformda!",
36
+ '👥 Kendi sunucunu kur, özel kanallar ve roller oluştur — natureco.me',
37
+ '🔌 WordPress sitene tek tıkla NatureBot ekle — natureco SDK ile entegre et',
38
+ "📱 Nature.co masaüstü uygulaması — Mac, Windows ve Android TV'de mevcut!",
39
+ '🌍 Forum, blog ve etkinlikler — topluluğa katıl, doğa projelerinde yer al',
40
+ ];
28
41
 
29
42
  // ── What's New ────────────────────────────────────────────────────────────────
30
43
  const CHANGELOG = [
31
- 'Eklendi: Blessed TUI — 4 bölgeli tam ekran arayüz',
44
+ 'Eklendi: Chalk TUI — saf readline tabanlı arayüz',
32
45
  'Eklendi: agents, plugins, pairing, uninstall komutları',
33
46
  'Eklendi: channels, models, memory, logs, status, security, reset',
34
- 'Düzeltildi: Telegram/WhatsApp cevap vermeme sorunu',
47
+ 'Düzeltildi: Çift karakter ve input sorunu giderildi',
35
48
  'Düzeltildi: Token optimizasyonu — sistem prompt sıkıştırıldı',
36
49
  ];
37
50
 
51
+ const sep = () => chalk.gray('─'.repeat(process.stdout.columns || 80));
52
+
53
+ function centerText(text) {
54
+ const width = process.stdout.columns || 120;
55
+ return text.split('\n').map(line => {
56
+ const padding = Math.max(0, Math.floor((width - line.length) / 2));
57
+ return ' '.repeat(padding) + line;
58
+ }).join('\n');
59
+ }
60
+
38
61
  async function chat(botName, options = {}) {
39
62
  const apiKey = getApiKey();
40
63
  const config = getConfig();
@@ -111,118 +134,60 @@ async function chat(botName, options = {}) {
111
134
  try { lastVersion = fs.readFileSync(lastVersionFile, 'utf8').trim(); } catch {}
112
135
  const isNewVersion = lastVersion !== version;
113
136
 
114
- // ── Blessed TUI ─────────────────────────────────────────────────────────────
115
- let blessed;
116
- try {
117
- blessed = require('blessed');
118
- } catch {
119
- // blessed yüklü değilse fallback
120
- return chatFallback(bot, botList, displayBotName, userName, shortModel, apiKey, config, systemPrompt, session, conversationId, options);
121
- }
122
-
123
- const screen = blessed.screen({
124
- smartCSR: true,
125
- title: `NatureCo · ${displayBotName}`,
126
- terminal: 'xterm-256color',
127
- fullUnicode: true,
128
- grabKeys: false, // readline'ın keypress almasına izin ver
129
- ignoreLocked: ['C-c'],
130
- });
131
-
132
- // ── Logo kutusu (üst %30) ───────────────────────────────────────────────────
133
- const rabbitLine = `{cyan-fg}(\\_{/}{cyan-fg}/) {/}{white-fg}Hoş geldin, ${userName}{/} {gray-fg}·{/} {cyan-fg}${displayBotName} hazır{/} {gray-fg}·{/} {gray-fg}v${version}{/}`;
134
- const logoContent = ASCII_LOGO + '\n\n' + rabbitLine;
135
-
136
- const logoBox = blessed.box({
137
- top: 0,
138
- left: 0,
139
- width: '100%',
140
- height: '28%',
141
- content: logoContent,
142
- align: 'center',
143
- valign: 'middle',
144
- tags: true,
145
- style: { fg: 'green', bg: 'default' },
146
- });
147
-
148
- // ── Mesaj alanı ─────────────────────────────────────────────────────────────
149
- const messageBox = blessed.log({
150
- top: '28%',
151
- left: 0,
152
- width: '100%',
153
- bottom: 5, // separator(1) + status(1) + input alanı(3) = 5
154
- scrollable: true,
155
- alwaysScroll: true,
156
- tags: true,
157
- padding: { left: 2, right: 2, top: 1 },
158
- scrollbar: { ch: '│', style: { fg: 'gray' } },
159
- style: { bg: 'default' },
160
- });
161
-
162
- // ── Input separator çizgisi ─────────────────────────────────────────────────
163
- const inputSeparator = blessed.line({
164
- bottom: 4,
165
- left: 0,
166
- width: '100%',
167
- orientation: 'horizontal',
168
- style: { fg: 'gray' },
169
- });
170
-
171
- // ── Status bar (en alt 1 satır) ─────────────────────────────────────────────
172
- const cwd = process.cwd().replace(os.homedir(), '~');
173
- const statusBar = blessed.box({
174
- bottom: 0,
175
- left: 0,
176
- width: '100%',
177
- height: 1,
178
- content: ` {cyan-fg}${displayBotName}{/} {gray-fg}·{/} {gray-fg}${shortModel}{/}{|}${cwd} `,
179
- tags: true,
180
- style: { bg: 'default', fg: 'gray' },
181
- });
182
-
183
- screen.append(logoBox);
184
- screen.append(messageBox);
185
- screen.append(inputSeparator);
186
- screen.append(statusBar);
187
-
188
- screen.render();
137
+ // ── Header ──────────────────────────────────────────────────────────────────
138
+ console.clear();
139
+ console.log(centerText(ASCII_LOGO.map((line, i) => i < 5 ? chalk.green(line) : chalk.gray(line)).join('\n')));
140
+ console.log();
141
+ console.log(centerText(chalk.cyan(`(\\_/) `) + chalk.white(`Hoş geldin, ${userName}`) + chalk.gray(' · ') + chalk.cyan(`${displayBotName} hazır`) + chalk.gray(` · v${version}`)));
142
+ console.log(sep());
143
+ console.log();
189
144
 
190
145
  // ── What's New ──────────────────────────────────────────────────────────────
191
146
  if (isNewVersion) {
192
- messageBox.log(`{yellow-fg}─── v${version} yenilikleri ───{/}`);
193
- CHANGELOG.forEach(c => messageBox.log(` {gray-fg}·{/} ${c}`));
194
- messageBox.log('');
147
+ console.log(chalk.yellow(`── v${version} yenilikleri ──`));
148
+ CHANGELOG.forEach(c => console.log(chalk.gray(` · ${c}`)));
149
+ console.log();
195
150
  try { fs.writeFileSync(lastVersionFile, version); } catch {}
151
+ } else {
152
+ // Yeni versiyon yoksa günlük tip göster
153
+ const dayIndex = Math.floor(Date.now() / (1000 * 60 * 60 * 24)) % TIPS.length;
154
+ console.log(sep());
155
+ console.log(' ' + chalk.yellow(TIPS[dayIndex]));
156
+ console.log(sep());
157
+ console.log();
196
158
  }
197
159
 
198
- // Önceki session mesajlarını göster
160
+ // ── Önceki session mesajları ─────────────────────────────────────────────────
199
161
  if (options.resume && session.messages?.length) {
200
162
  const last = session.messages.slice(-5);
201
163
  last.forEach(msg => {
202
- messageBox.log(`{white-fg}You{/} ${msg.user}`);
203
- messageBox.log(`{cyan-fg}${displayBotName}{/} ${msg.bot}`);
204
- messageBox.log('');
164
+ console.log(chalk.white('You ') + msg.user);
165
+ console.log(chalk.cyan(`${displayBotName} `) + msg.bot);
166
+ console.log();
205
167
  });
206
168
  }
207
169
 
170
+ console.log(chalk.gray(` ${shortModel} · /help için yardım · Ctrl+C çıkış`));
171
+ console.log(sep());
172
+ console.log();
173
+
208
174
  // ── Yükleme animasyonu ──────────────────────────────────────────────────────
209
175
  let loadingTimer = null;
210
- let loadingFrame = 0;
211
176
  const loadingFrames = ['●○○', '○●○', '○○●'];
177
+ let loadingFrame = 0;
212
178
 
213
179
  function startLoading() {
214
180
  loadingFrame = 0;
181
+ process.stdout.write(chalk.gray(' ' + loadingFrames[0]));
215
182
  loadingTimer = setInterval(() => {
216
- statusBar.setContent(` {cyan-fg}${displayBotName}{/} {gray-fg}·{/} {gray-fg}${loadingFrames[loadingFrame]}{/}{|}${cwd} `);
183
+ process.stdout.write('\r' + chalk.gray(' ' + loadingFrames[loadingFrame]));
217
184
  loadingFrame = (loadingFrame + 1) % loadingFrames.length;
218
- screen.render();
219
185
  }, 300);
220
186
  }
221
187
 
222
188
  function stopLoading() {
223
189
  if (loadingTimer) { clearInterval(loadingTimer); loadingTimer = null; }
224
- statusBar.setContent(` {cyan-fg}${displayBotName}{/} {gray-fg}·{/} {gray-fg}${shortModel}{/}{|}${cwd} `);
225
- screen.render();
190
+ process.stdout.write('\r\x1b[2K');
226
191
  }
227
192
 
228
193
  // ── Mesaj gönderme ──────────────────────────────────────────────────────────
@@ -235,15 +200,14 @@ async function chat(botName, options = {}) {
235
200
  const [cmd, ...args] = userMessage.slice(1).split(' ');
236
201
  switch (cmd.toLowerCase()) {
237
202
  case 'clear':
238
- messageBox.setContent('');
239
- screen.render();
203
+ console.clear();
240
204
  return;
241
205
  case 'bot':
242
206
  if (!args.length) {
243
- messageBox.log(`{yellow-fg}Aktif bot:{/} ${bot.name}`);
207
+ console.log(chalk.yellow('Aktif bot: ') + bot.name);
244
208
  botList.bots.forEach(b => {
245
- const mark = b.id === bot.id ? '{green-fg}{/} ' : ' ';
246
- messageBox.log(`${mark}{cyan-fg}${b.name}{/}`);
209
+ const mark = b.id === bot.id ? chalk.green('✓ ') : ' ';
210
+ console.log(mark + chalk.cyan(b.name));
247
211
  });
248
212
  } else {
249
213
  const newName = args.join(' ');
@@ -252,76 +216,74 @@ async function chat(botName, options = {}) {
252
216
  bot = newBot;
253
217
  conversationId = null;
254
218
  session = createSession(bot.id, bot.name);
255
- messageBox.log(`{green-fg}Bot değişti: ${newBot.name}{/}`);
219
+ console.log(chalk.green(`Bot değişti: ${newBot.name}`));
256
220
  } else {
257
- messageBox.log(`{red-fg}Bot bulunamadı: ${newName}{/}`);
221
+ console.log(chalk.red(`Bot bulunamadı: ${newName}`));
258
222
  }
259
223
  }
260
- screen.render();
224
+ console.log();
261
225
  return;
262
226
  case 'skills':
263
227
  const skills = getSkills();
264
- if (!skills.length) { messageBox.log('{gray-fg}Yüklü skill yok.{/}'); }
265
- else skills.forEach(s => messageBox.log(`{cyan-fg}· ${s.name}{/} {gray-fg}${s.description}{/}`));
266
- screen.render();
228
+ if (!skills.length) console.log(chalk.gray('Yüklü skill yok.'));
229
+ else skills.forEach(s => console.log(chalk.cyan(`· ${s.name}`) + chalk.gray(` ${s.description}`)));
230
+ console.log();
267
231
  return;
268
232
  case 'memory':
269
233
  if (args[0] === 'clear') {
270
234
  clearMemory(bot.id);
271
- messageBox.log('{green-fg}✓ Hafıza temizlendi{/}');
235
+ console.log(chalk.green('✓ Hafıza temizlendi'));
272
236
  } else {
273
237
  const m = loadMemory(bot.id);
274
- if (m.botName) messageBox.log(`{cyan-fg}Bot:{/} ${m.botName}`);
275
- if (m.name) messageBox.log(`{cyan-fg}İsim:{/} ${m.name}`);
238
+ if (m.botName) console.log(chalk.cyan('Bot: ') + m.botName);
239
+ if (m.name) console.log(chalk.cyan('İsim: ') + m.name);
276
240
  (m.facts || []).slice(0, 8).forEach(f => {
277
241
  const v = typeof f === 'string' ? f : f.value;
278
- messageBox.log(`{gray-fg}· ${v}{/}`);
242
+ console.log(chalk.gray(`· ${v}`));
279
243
  });
280
244
  }
281
- screen.render();
245
+ console.log();
282
246
  return;
283
247
  case 'help':
248
+ console.log(chalk.yellow('Chat Komutları:'));
284
249
  [
285
- '{yellow-fg}Chat Komutları:{/}',
286
- '{cyan-fg}/clear{/} Ekranı temizle',
287
- '{cyan-fg}/bot [ad]{/} Bot değiştir',
288
- '{cyan-fg}/skills{/} Skill listesi',
289
- '{cyan-fg}/memory{/} Hafızayı göster',
290
- '{cyan-fg}/memory clear{/} Hafızayı temizle',
291
- '{cyan-fg}/commands{/} Özel komutlar',
292
- '{cyan-fg}/help{/} Bu yardım',
293
- '{gray-fg}Ctrl+C Çıkış{/}',
294
- ].forEach(l => messageBox.log(l));
295
- screen.render();
250
+ ['/clear', 'Ekranı temizle'],
251
+ ['/bot [ad]', 'Bot değiştir'],
252
+ ['/skills', 'Skill listesi'],
253
+ ['/memory', 'Hafızayı göster'],
254
+ ['/memory clear', 'Hafızayı temizle'],
255
+ ['/commands', 'Özel komutlar'],
256
+ ['/help', 'Bu yardım'],
257
+ ].forEach(([c, d]) => console.log(' ' + chalk.cyan(c.padEnd(16)) + chalk.gray(d)));
258
+ console.log(chalk.gray(' Ctrl+C'.padEnd(18) + 'Çıkış'));
259
+ console.log();
296
260
  return;
297
261
  case 'commands':
298
262
  const cmds = getCommands();
299
- if (!cmds.length) messageBox.log('{gray-fg}Özel komut yok.{/}');
300
- else cmds.forEach(c => messageBox.log(`{cyan-fg}/${c.name}{/}`));
301
- screen.render();
263
+ if (!cmds.length) console.log(chalk.gray('Özel komut yok.'));
264
+ else cmds.forEach(c => console.log(chalk.cyan(`/${c.name}`)));
265
+ console.log();
302
266
  return;
303
267
  default:
304
268
  const customCmd = getCommandContent(cmd);
305
269
  if (customCmd) {
306
270
  const customPrompt = systemPrompt + '\n\n## Custom Command\n' + customCmd;
307
271
  const msg = args.length ? args.join(' ') : 'Execute the custom command instruction';
308
- messageBox.log(`{white-fg}You{/} ${userMessage}`);
272
+ console.log(chalk.white('You ') + userMessage);
309
273
  startLoading();
310
274
  try {
311
275
  const res = await sendMessage(apiKey || config.providerApiKey, bot.id, msg, conversationId, customPrompt);
312
276
  stopLoading();
313
277
  if (res.conversation_id) conversationId = res.conversation_id;
314
278
  const reply = res.reply || res.message || '';
315
- messageBox.log(`{cyan-fg}${displayBotName}{/} ${reply}`);
316
- messageBox.log('');
279
+ console.log(chalk.cyan(`${displayBotName} `) + reply);
280
+ console.log();
317
281
  addToHistory(bot.id, userMessage, reply, conversationId);
318
282
  addMessageToSession(bot.id, session.id, userMessage, reply);
319
- } catch (e) { stopLoading(); messageBox.log(`{red-fg}Error: ${e.message}{/}`); }
320
- messageBox.setScrollPerc(100);
321
- screen.render();
283
+ } catch (e) { stopLoading(); console.log(chalk.red(`Error: ${e.message}`)); console.log(); }
322
284
  } else {
323
- messageBox.log(`{red-fg}Bilinmeyen komut: /${cmd}{/}`);
324
- screen.render();
285
+ console.log(chalk.red(`Bilinmeyen komut: /${cmd}`));
286
+ console.log();
325
287
  }
326
288
  return;
327
289
  }
@@ -330,15 +292,13 @@ async function chat(botName, options = {}) {
330
292
  // exit/quit
331
293
  if (userMessage === 'exit' || userMessage === 'quit') {
332
294
  await runHooks('on-exit', null, { botId: bot.id, botName: bot.name });
333
- screen.destroy();
295
+ console.log(chalk.gray('\n👋 Goodbye!\n'));
334
296
  process.exit(0);
335
297
  }
336
298
 
337
299
  // Normal mesaj
338
300
  userMessage = await runHooks('pre-message', userMessage, { botId: bot.id, botName: bot.name });
339
- messageBox.log(`{white-fg}You{/} ${userMessage}`);
340
- messageBox.setScrollPerc(100);
341
- screen.render();
301
+ console.log(chalk.white('You ') + userMessage);
342
302
 
343
303
  startLoading();
344
304
 
@@ -354,8 +314,7 @@ async function chat(botName, options = {}) {
354
314
  while (iter < 5) {
355
315
  const toolCalls = extractToolCalls(response);
356
316
  if (!toolCalls?.length) break;
357
- messageBox.log(`{yellow-fg}🔧 ${toolCalls.length} tool çalıştırılıyor...{/}`);
358
- screen.render();
317
+ console.log(chalk.yellow(`🔧 ${toolCalls.length} tool çalıştırılıyor...`));
359
318
  const toolResults = await executeToolCalls(toolCalls);
360
319
  const toolMsg = toolResults.map(tr => `Tool: ${tr.name}\nResult: ${tr.result.success ? (tr.result.output || '') : tr.result.error}`).join('\n\n');
361
320
  startLoading();
@@ -368,10 +327,8 @@ async function chat(botName, options = {}) {
368
327
  let botReply = response.reply || response.message || 'No response';
369
328
  botReply = await runHooks('post-message', botReply, { botId: bot.id, botName: bot.name });
370
329
 
371
- messageBox.log(`{cyan-fg}${displayBotName}{/} ${botReply}`);
372
- messageBox.log('');
373
- messageBox.setScrollPerc(100);
374
- screen.render();
330
+ console.log(chalk.cyan(`${displayBotName} `) + botReply);
331
+ console.log();
375
332
 
376
333
  addToHistory(bot.id, userMessage, botReply, conversationId);
377
334
  addMessageToSession(bot.id, session.id, userMessage, botReply);
@@ -382,35 +339,18 @@ async function chat(botName, options = {}) {
382
339
  } catch (err) {
383
340
  stopLoading();
384
341
  const errMsg = err.message.split('"message":"')[1]?.split('"')[0] || err.message;
385
- messageBox.log(`{red-fg}Error: ${errMsg}{/}`);
386
- messageBox.setScrollPerc(100);
387
- screen.render();
342
+ console.log(chalk.red(`Error: ${errMsg}`));
343
+ console.log();
388
344
  }
389
345
  }
390
346
 
391
- // ── Readline ile native input loop ──────────────────────────────────────────
392
- const readline = require('readline');
347
+ // ── Input loop ───────────────────────────────────────────────────────────────
393
348
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
394
349
 
395
- // Blessed cursor'ı gizlemesin, readline yazsın
396
- screen.program.showCursor();
397
- screen.program.on('render', () => screen.program.showCursor());
398
-
399
- async function promptLoop() {
400
- rl.question('', async (msg) => {
401
- // Readline'ın yazdığı satırı temizle
402
- process.stdout.write('\x1b[1A\x1b[2K');
403
- await handleMessage(msg);
404
- screen.render();
405
- promptLoop();
406
- });
407
- }
408
-
409
- // ── Ctrl+C çıkış ────────────────────────────────────────────────────────────
410
- screen.key(['C-c'], async () => {
350
+ process.on('SIGINT', async () => {
411
351
  await runHooks('on-exit', null, { botId: bot.id, botName: bot.name });
412
352
  rl.close();
413
- screen.destroy();
353
+ console.log(chalk.gray('\n👋 Goodbye!\n'));
414
354
  process.exit(0);
415
355
  });
416
356
 
@@ -419,52 +359,15 @@ async function chat(botName, options = {}) {
419
359
  // ── on-start hooks ──────────────────────────────────────────────────────────
420
360
  await runHooks('on-start', null, { botId: bot.id, botName: bot.name });
421
361
 
422
- screen.render();
423
- promptLoop();
424
- }
425
-
426
- // ── Fallback: blessed yoksa eski readline tabanlı chat ────────────────────────
427
- async function chatFallback(bot, botList, displayBotName, userName, shortModel, apiKey, config, systemPrompt, session, conversationId, options) {
428
- const readline = require('readline');
429
- const chalk = require('chalk');
430
-
431
- console.clear();
432
- console.log(chalk.green.bold(' (\\_/)'));
433
- console.log(chalk.green.bold(' (•ᴥ•)'));
434
- console.log(chalk.green(' />🌿'));
435
- console.log('');
436
- const sep = chalk.gray('─'.repeat(process.stdout.columns || 80));
437
- console.log(sep);
438
- console.log(chalk.white.bold('NatureCo') + chalk.gray(' · ') + chalk.cyan(displayBotName) + chalk.gray(' · ') + chalk.gray(shortModel));
439
- console.log(sep);
440
- console.log('');
441
-
442
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: chalk.gray('You ') });
443
- rl.prompt();
444
-
445
- rl.on('line', async (line) => {
446
- const msg = line.trim();
447
- if (!msg) { rl.prompt(); return; }
448
- if (msg === 'exit' || msg === 'quit') { console.log(chalk.gray('\n👋 Goodbye!\n')); process.exit(0); }
449
-
450
- process.stdout.write(chalk.cyan('... '));
451
- try {
452
- const toolDefinitions = getToolDefinitions();
453
- const response = await _sendMessage(apiKey || config.providerApiKey, bot.id, msg, conversationId, systemPrompt, toolDefinitions);
454
- process.stdout.write('\r');
455
- if (response.conversation_id) conversationId = response.conversation_id;
456
- const reply = response.reply || response.message || '';
457
- console.log(chalk.cyan(`${displayBotName} `) + reply + '\n');
458
- addToHistory(bot.id, msg, reply, conversationId);
459
- addMessageToSession(bot.id, session.id, msg, reply);
460
- } catch (e) {
461
- process.stdout.write('\r');
462
- console.log(chalk.red(`Error: ${e.message}\n`));
463
- }
464
- rl.prompt();
465
- });
362
+ async function promptLoop() {
363
+ rl.question('', async (msg) => {
364
+ process.stdout.write('\x1b[1A\x1b[2K');
365
+ await handleMessage(msg);
366
+ promptLoop();
367
+ });
368
+ }
466
369
 
467
- rl.on('close', () => process.exit(0));
370
+ promptLoop();
468
371
  }
469
372
 
470
373
  module.exports = chat;