npm-noxyai 1.0.11 → 1.0.13
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/index-noxyai.js +94 -162
- package/package.json +1 -1
package/index-noxyai.js
CHANGED
|
@@ -17,16 +17,14 @@ function loadConfig() {
|
|
|
17
17
|
if (fs.existsSync(CONFIG_FILE)) {
|
|
18
18
|
try {
|
|
19
19
|
const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
20
|
-
if (config.agentMode === undefined) config.agentMode =
|
|
21
|
-
if (config.autoDeduct === undefined) config.autoDeduct = false;
|
|
20
|
+
if (config.agentMode === undefined) config.agentMode = false; // Default OFF
|
|
22
21
|
return config;
|
|
23
22
|
} catch(e) {}
|
|
24
23
|
}
|
|
25
24
|
return {
|
|
26
25
|
token: null,
|
|
27
26
|
model: 'auto',
|
|
28
|
-
agentMode:
|
|
29
|
-
autoDeduct: false
|
|
27
|
+
agentMode: false // Default to Chat mode
|
|
30
28
|
};
|
|
31
29
|
}
|
|
32
30
|
|
|
@@ -46,41 +44,13 @@ function printLogo() {
|
|
|
46
44
|
` + '\x1b[0m');
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
function printFunnyArt() {
|
|
50
|
-
const art = `
|
|
51
|
-
▓▓ ▓▓
|
|
52
|
-
▓▓ ▓▓ ▓▓
|
|
53
|
-
▓▓▓▓ ▓▓
|
|
54
|
-
▓▓ ██ ▓▓
|
|
55
|
-
▓▓░░░░ ▓▓
|
|
56
|
-
▓▓▓▓░░ ▓▓
|
|
57
|
-
▓▓ ▓▓
|
|
58
|
-
▓▓ ▓▓ ▓▓
|
|
59
|
-
▓▓ ▓▓ ▓▓ ▓▓
|
|
60
|
-
▓▓ ▓▓ ▓▓ ▓▓
|
|
61
|
-
▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░░▓▓
|
|
62
|
-
▓▓ ▓▓
|
|
63
|
-
▓▓░░ ▓▓
|
|
64
|
-
▓▓░░ ░░▓▓
|
|
65
|
-
▓▓░░ ░░▓▓
|
|
66
|
-
▓▓░░░░ ░░░░░░░░░░ ▓▓
|
|
67
|
-
▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓
|
|
68
|
-
▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓
|
|
69
|
-
▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓
|
|
70
|
-
▓▓░░▓▓░░▓▓ ▓▓░░▓▓░░▓▓
|
|
71
|
-
▓▓░░▓▓░░▓▓ ▓▓░░▓▓░░▓▓
|
|
72
|
-
▓▓░░▓▓░░▓▓ ▓▓░░▓▓░░▓▓
|
|
73
|
-
▓▓ ▓▓ ▓▓ ▓▓`;
|
|
74
|
-
console.log('\x1b[35m' + art + '\x1b[0m');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
47
|
let spinnerInterval;
|
|
78
48
|
function startSpinner(text) {
|
|
79
49
|
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
80
50
|
let i = 0;
|
|
81
51
|
process.stdout.write('\x1b[?25l');
|
|
82
52
|
spinnerInterval = setInterval(() => {
|
|
83
|
-
process.stdout.write(
|
|
53
|
+
process.stdout.write(`\r\x1b[36m${frames[i]} ${text}\x1b[0m`);
|
|
84
54
|
i = (i + 1) % frames.length;
|
|
85
55
|
}, 80);
|
|
86
56
|
}
|
|
@@ -105,11 +75,11 @@ function openBrowser(url) {
|
|
|
105
75
|
else spawn('xdg-open', [url], { stdio: 'ignore' });
|
|
106
76
|
}
|
|
107
77
|
|
|
108
|
-
// --- SEARCH FUNCTION
|
|
78
|
+
// --- SEARCH FUNCTION ---
|
|
109
79
|
async function searchWeb(query) {
|
|
110
80
|
try {
|
|
111
81
|
const config = loadConfig();
|
|
112
|
-
const res = await fetch(
|
|
82
|
+
const res = await fetch(`${BASE_URL}/api/io?action=search&q=${encodeURIComponent(query)}`, {
|
|
113
83
|
headers: { 'Authorization': 'Bearer ' + config.token }
|
|
114
84
|
});
|
|
115
85
|
const data = await res.json();
|
|
@@ -119,33 +89,6 @@ async function searchWeb(query) {
|
|
|
119
89
|
}
|
|
120
90
|
}
|
|
121
91
|
|
|
122
|
-
// --- CREDIT DEDUCTION WITH MANUAL APPROVAL ---
|
|
123
|
-
async function requestCreditDeduction(usage, model) {
|
|
124
|
-
const config = loadConfig();
|
|
125
|
-
|
|
126
|
-
if (config.autoDeduct) {
|
|
127
|
-
return { approved: true, cost: usage.estimatedCost };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
console.log('\n\x1b[33m💰 Credit Usage Summary:\x1b[0m');
|
|
131
|
-
console.log(' Prompt Tokens: ${usage.promptTokens}');
|
|
132
|
-
console.log(' Response Tokens: ${usage.responseTokens}');
|
|
133
|
-
if (usage.reasoningTokens) {
|
|
134
|
-
console.log(' \x1b[31mReasoning Tokens: ${usage.reasoningTokens}\x1b[0m');
|
|
135
|
-
}
|
|
136
|
-
console.log(' Total Tokens: ${usage.totalTokens}');
|
|
137
|
-
console.log(' \x1b[32mEstimated Cost: ${usage.estimatedCost} credits\x1b[0m');
|
|
138
|
-
|
|
139
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
140
|
-
|
|
141
|
-
return new Promise((resolve) => {
|
|
142
|
-
rl.question('\n\x1b[33mApprove credit deduction? (y/n): \x1b[0m', (answer) => {
|
|
143
|
-
rl.close();
|
|
144
|
-
resolve({ approved: answer.toLowerCase() === 'y', cost: usage.estimatedCost });
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
92
|
// --- CORE FUNCTIONS ---
|
|
150
93
|
async function login() {
|
|
151
94
|
printLogo();
|
|
@@ -155,7 +98,7 @@ async function login() {
|
|
|
155
98
|
const { deviceCode, verificationUrl, interval } = await initRes.json();
|
|
156
99
|
|
|
157
100
|
console.log('=============================================');
|
|
158
|
-
console.log(
|
|
101
|
+
console.log(`URL: ${verificationUrl}`);
|
|
159
102
|
console.log('=============================================\n');
|
|
160
103
|
|
|
161
104
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -203,18 +146,18 @@ async function login() {
|
|
|
203
146
|
|
|
204
147
|
function runTerminalCommand(cmd) {
|
|
205
148
|
return new Promise((resolve, reject) => {
|
|
206
|
-
console.log(
|
|
149
|
+
console.log(`\n\x1b[33m⚡ Running:\x1b[0m ${cmd}\n`);
|
|
207
150
|
const isServer = cmd.includes('dev') || cmd.includes('serve') || cmd.includes('host') || cmd.includes('start');
|
|
208
151
|
const child = spawn(cmd, { shell: true, stdio: 'inherit' });
|
|
209
152
|
|
|
210
153
|
if (isServer) {
|
|
211
|
-
console.log(
|
|
154
|
+
console.log(`\n\x1b[36m[i] Server detected. Running in foreground. Press Ctrl+C to stop.\x1b[0m`);
|
|
212
155
|
setTimeout(() => resolve(), 2500);
|
|
213
156
|
}
|
|
214
157
|
|
|
215
158
|
child.on('close', (code) => {
|
|
216
159
|
if (!isServer) {
|
|
217
|
-
if (code !== 0) reject(
|
|
160
|
+
if (code !== 0) reject(`Command failed with exit code ${code}`);
|
|
218
161
|
else resolve();
|
|
219
162
|
}
|
|
220
163
|
});
|
|
@@ -225,7 +168,7 @@ function runTerminalCommand(cmd) {
|
|
|
225
168
|
function getLocalContext() {
|
|
226
169
|
try {
|
|
227
170
|
const files = fs.readdirSync(process.cwd()).filter(f => !f.startsWith('node_modules') && !f.startsWith('.git')).slice(0, 30);
|
|
228
|
-
return
|
|
171
|
+
return `\n[SYSTEM: You are in ${process.cwd()}. Files here: ${files.join(', ')}]\n`;
|
|
229
172
|
} catch (e) { return ""; }
|
|
230
173
|
}
|
|
231
174
|
|
|
@@ -234,7 +177,8 @@ async function chat(prompt, depth = 0) {
|
|
|
234
177
|
if (!config.token) { console.error('❌ Unauthorized: Run "noxyai login"'); return; }
|
|
235
178
|
if (depth > 6) { console.error('\n❌ Reached max reasoning depth. Stopping.'); return; }
|
|
236
179
|
|
|
237
|
-
|
|
180
|
+
// Only add file context in Agent Mode
|
|
181
|
+
const enhancedPrompt = (depth === 0 && config.agentMode) ? getLocalContext() + prompt : prompt;
|
|
238
182
|
|
|
239
183
|
startSpinner(depth === 0 ? 'NoxyAI is thinking...' : 'NoxyAI is analyzing results...');
|
|
240
184
|
|
|
@@ -260,16 +204,16 @@ async function chat(prompt, depth = 0) {
|
|
|
260
204
|
return console.error('\n❌ API Error: ' + errorText);
|
|
261
205
|
}
|
|
262
206
|
|
|
263
|
-
const modelDisplay = config.model === 'auto' ? '
|
|
264
|
-
|
|
265
|
-
|
|
207
|
+
const modelDisplay = config.model === 'auto' ? 'Mamba-Codestral 7B' :
|
|
208
|
+
config.model === 'Qwen3' ? 'Qwen3 80B' : 'Mamba-Codestral 7B';
|
|
209
|
+
const agentStatus = config.agentMode ? '🤖 Agent' : '💬 Chat';
|
|
210
|
+
console.log(`\n${agentStatus} \x1b[36mNoxyAI (${modelDisplay}):\x1b[0m\n`);
|
|
266
211
|
|
|
267
212
|
const reader = res.body.getReader();
|
|
268
213
|
const decoder = new TextDecoder('utf-8');
|
|
269
214
|
let fullResponse = "";
|
|
270
|
-
let fullReasoning = "";
|
|
271
215
|
let usage = null;
|
|
272
|
-
let
|
|
216
|
+
let searchSources = [];
|
|
273
217
|
|
|
274
218
|
while (true) {
|
|
275
219
|
const { done, value } = await reader.read();
|
|
@@ -284,17 +228,12 @@ async function chat(prompt, depth = 0) {
|
|
|
284
228
|
try {
|
|
285
229
|
const parsed = JSON.parse(data);
|
|
286
230
|
|
|
287
|
-
|
|
288
|
-
isQwen = true;
|
|
289
|
-
}
|
|
290
|
-
|
|
231
|
+
// Reasoning in GREEN
|
|
291
232
|
if (parsed.reasoning) {
|
|
292
|
-
|
|
293
|
-
if (isQwen) {
|
|
294
|
-
process.stdout.write('\x1b[31m' + parsed.reasoning + '\x1b[0m');
|
|
295
|
-
}
|
|
233
|
+
process.stdout.write('\x1b[32m' + parsed.reasoning + '\x1b[0m');
|
|
296
234
|
}
|
|
297
235
|
|
|
236
|
+
// Normal response
|
|
298
237
|
if (parsed.text) {
|
|
299
238
|
fullResponse += parsed.text;
|
|
300
239
|
process.stdout.write(parsed.text);
|
|
@@ -308,78 +247,78 @@ async function chat(prompt, depth = 0) {
|
|
|
308
247
|
}
|
|
309
248
|
}
|
|
310
249
|
|
|
311
|
-
|
|
312
|
-
const approval = await requestCreditDeduction(usage, config.model);
|
|
313
|
-
|
|
314
|
-
if (approval.approved) {
|
|
315
|
-
const deductRes = await fetch(BASE_URL + '/api/io/deduct', {
|
|
316
|
-
method: 'POST',
|
|
317
|
-
headers: {
|
|
318
|
-
'Content-Type': 'application/json',
|
|
319
|
-
'Authorization': 'Bearer ' + config.token
|
|
320
|
-
},
|
|
321
|
-
body: JSON.stringify({
|
|
322
|
-
amount: approval.cost,
|
|
323
|
-
model: config.model,
|
|
324
|
-
tokens: usage.totalTokens
|
|
325
|
-
})
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
if (deductRes.ok) {
|
|
329
|
-
console.log('\n\x1b[32m✅ Credits deducted successfully!\x1b[0m');
|
|
330
|
-
} else {
|
|
331
|
-
console.log('\n\x1b[31m❌ Credit deduction failed\x1b[0m');
|
|
332
|
-
}
|
|
333
|
-
} else {
|
|
334
|
-
console.log('\n\x1b[33m⚠️ Credit deduction cancelled\x1b[0m');
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
250
|
+
console.log('\n');
|
|
338
251
|
|
|
252
|
+
// ONLY process agent actions if agent mode is ON AND there are action tags
|
|
339
253
|
if (!config.agentMode) {
|
|
340
|
-
console.log('\n');
|
|
341
254
|
return;
|
|
342
255
|
}
|
|
343
256
|
|
|
344
|
-
|
|
257
|
+
// Check if response contains action tags before processing
|
|
258
|
+
const hasActionTags = /<read>|<search>|<file path=|<execute>/.test(fullResponse);
|
|
259
|
+
if (!hasActionTags) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
console.log('\x1b[32m[Agent] Processing actions...\x1b[0m');
|
|
345
264
|
let agentFeedback = "";
|
|
346
265
|
|
|
266
|
+
// Tool: Read Files
|
|
347
267
|
const readRegex = /<read>([\s\S]*?)<\/read>/g;
|
|
348
268
|
let match;
|
|
349
269
|
while ((match = readRegex.exec(fullResponse)) !== null) {
|
|
350
270
|
const filePath = match[1].trim();
|
|
351
271
|
try {
|
|
352
272
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
353
|
-
console.log(
|
|
354
|
-
agentFeedback +=
|
|
273
|
+
console.log(`\x1b[34m📖 Read file:\x1b[0m ${filePath}`);
|
|
274
|
+
agentFeedback += `\n[FILE: ${filePath}]\n\`\`\`\n${content}\n\`\`\`\n`;
|
|
355
275
|
} catch (err) {
|
|
356
|
-
console.log(
|
|
357
|
-
agentFeedback +=
|
|
276
|
+
console.log(`\x1b[31m❌ Failed to read:\x1b[0m ${filePath}`);
|
|
277
|
+
agentFeedback += `\n[ERROR reading ${filePath}: ${err.message}]\n`;
|
|
358
278
|
}
|
|
359
279
|
}
|
|
360
280
|
|
|
281
|
+
// Tool: Search Web with sources
|
|
361
282
|
const searchRegex = /<search>([\s\S]*?)<\/search>/g;
|
|
362
283
|
while ((match = searchRegex.exec(fullResponse)) !== null) {
|
|
363
284
|
const query = match[1].trim();
|
|
364
|
-
console.log(
|
|
285
|
+
console.log(`\x1b[35m🔍 Searching Web:\x1b[0m ${query}`);
|
|
365
286
|
try {
|
|
366
287
|
const searchData = await searchWeb(query);
|
|
367
|
-
|
|
368
|
-
|
|
288
|
+
if (searchData.items) {
|
|
289
|
+
searchSources = searchData.items.slice(0, 5).map(i => ({
|
|
290
|
+
title: i.title,
|
|
291
|
+
link: i.link,
|
|
292
|
+
snippet: i.snippet
|
|
293
|
+
}));
|
|
294
|
+
|
|
295
|
+
console.log(`\x1b[35m📚 Sources found:\x1b[0m`);
|
|
296
|
+
searchSources.forEach((s, i) => {
|
|
297
|
+
console.log(` \x1b[36m${i+1}. ${s.title}\x1b[0m`);
|
|
298
|
+
console.log(` \x1b[90m${s.link}\x1b[0m`);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
const snippets = searchData.items.map(i => `- ${i.title}: ${i.snippet}\n Source: ${i.link}`).join('\n');
|
|
302
|
+
agentFeedback += `\n[SEARCH RESULTS FOR "${query}"]\n${snippets}\n`;
|
|
303
|
+
} else {
|
|
304
|
+
agentFeedback += `\n[SEARCH RESULTS FOR "${query}"]\nNo results found.\n`;
|
|
305
|
+
}
|
|
369
306
|
} catch (err) {
|
|
370
|
-
agentFeedback +=
|
|
307
|
+
agentFeedback += `\n[SEARCH FAILED: ${err.message}]\n`;
|
|
371
308
|
}
|
|
372
309
|
}
|
|
373
310
|
|
|
311
|
+
// Tool: Write Files
|
|
374
312
|
const fileRegex = /<file path="([^"]+)">([\s\S]*?)<\/file>/g;
|
|
375
313
|
while ((match = fileRegex.exec(fullResponse)) !== null) {
|
|
376
314
|
const filePath = match[1], content = match[2];
|
|
377
315
|
const dir = path.dirname(filePath);
|
|
378
316
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
379
317
|
fs.writeFileSync(filePath, content.trim());
|
|
380
|
-
console.log(
|
|
318
|
+
console.log(`\x1b[32m✔ Wrote file:\x1b[0m ${filePath}`);
|
|
381
319
|
}
|
|
382
320
|
|
|
321
|
+
// Tool: Execute Commands
|
|
383
322
|
const execRegex = /<execute>([\s\S]*?)<\/execute>/g;
|
|
384
323
|
const commands = [];
|
|
385
324
|
while ((match = execRegex.exec(fullResponse)) !== null) commands.push(match[1].trim());
|
|
@@ -388,20 +327,20 @@ async function chat(prompt, depth = 0) {
|
|
|
388
327
|
try {
|
|
389
328
|
await runTerminalCommand(cmd);
|
|
390
329
|
} catch (err) {
|
|
391
|
-
console.log(
|
|
392
|
-
agentFeedback +=
|
|
330
|
+
console.log(`\x1b[31m❌ Command Failed:\x1b[0m ${err}`);
|
|
331
|
+
agentFeedback += `\n[COMMAND ERROR running "${cmd}": ${err}]\n`;
|
|
393
332
|
}
|
|
394
333
|
}
|
|
395
334
|
|
|
396
335
|
if (agentFeedback) {
|
|
397
|
-
console.log(
|
|
398
|
-
await chat(
|
|
336
|
+
console.log(`\n\x1b[33m🔄 Sending data back to Agent...\x1b[0m`);
|
|
337
|
+
await chat(`Here are the results of your actions:\n${agentFeedback}\nWhat is the next step? Output <file> or <execute> if ready, or <read>/<search> if you need more info.`, depth + 1);
|
|
399
338
|
return;
|
|
400
339
|
}
|
|
401
340
|
|
|
402
341
|
console.log('\n\x1b[32m════════════════════════════════════════\x1b[0m');
|
|
403
|
-
console.log(
|
|
404
|
-
console.log('\
|
|
342
|
+
console.log(`\x1b[32m✨ Task Completed!\x1b[0m`);
|
|
343
|
+
console.log('\x1b[32m════════════════════════════════════════\x1b[0m\n');
|
|
405
344
|
|
|
406
345
|
} catch (error) {
|
|
407
346
|
stopSpinner();
|
|
@@ -413,20 +352,18 @@ function startInteractiveMode() {
|
|
|
413
352
|
const config = loadConfig();
|
|
414
353
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
415
354
|
printLogo();
|
|
416
|
-
printFunnyArt();
|
|
417
355
|
|
|
418
356
|
const agentStatus = config.agentMode ? '\x1b[32mON\x1b[0m' : '\x1b[31mOFF\x1b[0m';
|
|
419
|
-
const deductStatus = config.autoDeduct ? '\x1b[32mAUTO\x1b[0m' : '\x1b[33mMANUAL\x1b[0m';
|
|
420
357
|
|
|
421
|
-
console.log(
|
|
422
|
-
console.log(
|
|
423
|
-
console.log(
|
|
424
|
-
console.log(
|
|
425
|
-
console.log(
|
|
426
|
-
console.log(
|
|
427
|
-
console.log(
|
|
428
|
-
console.log(
|
|
429
|
-
console.log(
|
|
358
|
+
console.log(`\x1b[33mWelcome to NoxyAI Interactive Mode!\x1b[0m`);
|
|
359
|
+
console.log(`Current Model: \x1b[32m${config.model === 'auto' ? 'Mamba-Codestral 7B' : config.model}\x1b[0m`);
|
|
360
|
+
console.log(`Agent Mode: ${agentStatus}`);
|
|
361
|
+
console.log(`\nCommands:`);
|
|
362
|
+
console.log(` \x1b[36m/agent\x1b[0m - Toggle Agent Mode (file/code operations)`);
|
|
363
|
+
console.log(` \x1b[36m/model\x1b[0m - Change AI Model`);
|
|
364
|
+
console.log(` \x1b[36m/clear\x1b[0m - Clear screen`);
|
|
365
|
+
console.log(` \x1b[36m/exit\x1b[0m - Exit\n`);
|
|
366
|
+
console.log(`\x1b[90mTip: In Chat mode, AI responds normally. In Agent mode, it can read/write files and run commands.\x1b[0m\n`);
|
|
430
367
|
|
|
431
368
|
function ask() {
|
|
432
369
|
const prompt = config.agentMode ? '\x1b[36mNoxyAI [Agent] > \x1b[0m' : '\x1b[36mNoxyAI [Chat] > \x1b[0m';
|
|
@@ -441,44 +378,39 @@ function startInteractiveMode() {
|
|
|
441
378
|
else if (lower === '/clear') {
|
|
442
379
|
console.clear();
|
|
443
380
|
printLogo();
|
|
444
|
-
printFunnyArt();
|
|
445
381
|
ask();
|
|
446
382
|
}
|
|
447
|
-
else if (lower === '/agent') {
|
|
383
|
+
else if (lower === '/agent' || lower === '/agent on' || lower === '/agent off') {
|
|
448
384
|
config.agentMode = !config.agentMode;
|
|
449
385
|
saveConfig(config);
|
|
450
386
|
const status = config.agentMode ? '\x1b[32mON\x1b[0m' : '\x1b[31mOFF\x1b[0m';
|
|
451
|
-
console.log(
|
|
387
|
+
console.log(`\n\x1b[33m🤖 Agent Mode: ${status}\x1b[0m`);
|
|
452
388
|
if (config.agentMode) {
|
|
453
|
-
console.log('\
|
|
454
|
-
console.log(' •
|
|
455
|
-
console.log(' •
|
|
456
|
-
console.log(' •
|
|
389
|
+
console.log('\x1b[36mAgent mode features:\x1b[0m');
|
|
390
|
+
console.log(' • Read & write files');
|
|
391
|
+
console.log(' • Execute terminal commands');
|
|
392
|
+
console.log(' • Web search integration');
|
|
393
|
+
console.log(' • Multi-step autonomous tasks\n');
|
|
394
|
+
} else {
|
|
395
|
+
console.log('\x1b[36mChat mode: Normal AI conversation without file access\x1b[0m\n');
|
|
457
396
|
}
|
|
458
397
|
ask();
|
|
459
398
|
}
|
|
460
|
-
else if (lower === '/auto') {
|
|
461
|
-
config.autoDeduct = !config.autoDeduct;
|
|
462
|
-
saveConfig(config);
|
|
463
|
-
const status = config.autoDeduct ? '\x1b[32mAUTO\x1b[0m' : '\x1b[33mMANUAL\x1b[0m';
|
|
464
|
-
console.log('\n\x1b[33m💰 Credit Deduction Mode: ${status}\x1b[0m\n');
|
|
465
|
-
ask();
|
|
466
|
-
}
|
|
467
399
|
else if (lower === '/model') {
|
|
468
400
|
console.log('\n\x1b[33mSelect an AI Model:\x1b[0m');
|
|
469
|
-
console.log(' \x1b[36m1)\x1b[0m Auto (
|
|
470
|
-
console.log(' \x1b[36m2)\x1b[0m Qwen3
|
|
471
|
-
console.log(' \x1b[36m3)\x1b[0m
|
|
401
|
+
console.log(' \x1b[36m1)\x1b[0m Auto (Mamba-Codestral 7B)');
|
|
402
|
+
console.log(' \x1b[36m2)\x1b[0m Qwen3 80B \x1b[32m[Reasoning in Green]\x1b[0m');
|
|
403
|
+
console.log(' \x1b[36m3)\x1b[0m Mamba-Codestral 7B');
|
|
472
404
|
|
|
473
405
|
rl.question('\nEnter number (1-3): ', (choice) => {
|
|
474
406
|
let selected = 'auto';
|
|
475
407
|
if (choice === '2') selected = 'Qwen3';
|
|
476
|
-
if (choice === '3') selected = '
|
|
408
|
+
if (choice === '3') selected = 'Mamba-Codestral';
|
|
477
409
|
|
|
478
410
|
config.model = selected;
|
|
479
411
|
saveConfig(config);
|
|
480
412
|
|
|
481
|
-
console.log(
|
|
413
|
+
console.log(`\n\x1b[32m✔ Model changed to: ${selected}\x1b[0m\n`);
|
|
482
414
|
ask();
|
|
483
415
|
});
|
|
484
416
|
return;
|
|
@@ -494,22 +426,22 @@ function startInteractiveMode() {
|
|
|
494
426
|
ask();
|
|
495
427
|
}
|
|
496
428
|
|
|
429
|
+
// Command handling
|
|
497
430
|
if (command === 'login') login();
|
|
498
431
|
else if (command === 'logout') logout();
|
|
499
432
|
else if (command === 'help' || command === '--help') {
|
|
500
433
|
printLogo();
|
|
501
|
-
console.log(
|
|
502
|
-
console.log(
|
|
503
|
-
console.log(
|
|
504
|
-
console.log(
|
|
505
|
-
console.log(
|
|
506
|
-
console.log(' \x1b[36m/model\x1b[0m Change AI Model\n');
|
|
434
|
+
console.log(`\n \x1b[32mnoxyai\x1b[0m Start Interactive Mode`);
|
|
435
|
+
console.log(` \x1b[32mnoxyai chat "<prompt>"\x1b[0m Run single prompt`);
|
|
436
|
+
console.log(`\n Interactive Commands:`);
|
|
437
|
+
console.log(` \x1b[36m/agent\x1b[0m Toggle Agent Mode (file/code operations)`);
|
|
438
|
+
console.log(` \x1b[36m/model\x1b[0m Change AI Model\n`);
|
|
507
439
|
}
|
|
508
440
|
else if (command === 'chat') {
|
|
509
441
|
chat(args.slice(1).join(' ')).then(() => process.exit(0));
|
|
510
442
|
}
|
|
511
443
|
else if (!command) startInteractiveMode();
|
|
512
444
|
else {
|
|
513
|
-
console.error(
|
|
445
|
+
console.error(`❌ Unknown command. Run "noxyai help"`);
|
|
514
446
|
process.exit(1);
|
|
515
447
|
}
|