trace.ai-cli 1.1.0 → 1.1.2
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/README.markdown +126 -57
- package/cli/traceAI.js +19 -0
- package/package.json +7 -5
- package/services/aiService.js +522 -1
- package/services/systemInfoService.js +713 -0
package/services/aiService.js
CHANGED
|
@@ -1,8 +1,526 @@
|
|
|
1
1
|
const fetch = require('node-fetch');
|
|
2
2
|
const { encryptData, decryptData } = require('../utils/encryption');
|
|
3
|
+
const { getSystemInfo, formatBytes } = require('./systemInfoService');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Use AI to determine what system information is being requested
|
|
7
|
+
* @param {string} prompt - The user's prompt
|
|
8
|
+
* @param {Object} basicInfo - Basic system information for context
|
|
9
|
+
* @returns {Object} Object containing the determined query
|
|
10
|
+
*/
|
|
11
|
+
async function determineSystemInfoQuery(prompt, basicInfo) {
|
|
12
|
+
try {
|
|
13
|
+
// Create a prompt for the AI to analyze the user's query
|
|
14
|
+
const analysisPrompt = `Analyze the user's query: "${prompt}" and determine which system information they need.`;
|
|
15
|
+
|
|
16
|
+
// Use the AI to analyze the query
|
|
17
|
+
const models = ['kimi', 'mvrk', 'gma3'];
|
|
18
|
+
|
|
19
|
+
const modelRequests = models.map(model =>
|
|
20
|
+
fetch('https://traceai.dukeindustries7.workers.dev/', {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23
|
+
body: encryptData({
|
|
24
|
+
a: model,
|
|
25
|
+
q: analysisPrompt,
|
|
26
|
+
r: [],
|
|
27
|
+
i: [],
|
|
28
|
+
c: JSON.stringify(basicInfo)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
.then(res => res.text())
|
|
32
|
+
.then(text => {
|
|
33
|
+
try {
|
|
34
|
+
return decryptData(text);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.error('Error decrypting data:', e.message);
|
|
37
|
+
return { text: null };
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.catch(err => {
|
|
41
|
+
console.error('Error in model request:', err.message);
|
|
42
|
+
return { text: null };
|
|
43
|
+
})
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const responses = await Promise.all(modelRequests);
|
|
47
|
+
// Ensure we have valid responses and filter out any null or undefined values
|
|
48
|
+
const validResponses = responses.filter(r => r && typeof r === 'object');
|
|
49
|
+
const responseTexts = validResponses
|
|
50
|
+
.filter(r => r.text && typeof r.text === 'string') // Ensure text exists and is a string
|
|
51
|
+
.map(r => r.text);
|
|
52
|
+
|
|
53
|
+
// Combine the responses to get the most accurate determination
|
|
54
|
+
let categories = new Set();
|
|
55
|
+
|
|
56
|
+
// Check if we have any valid responses
|
|
57
|
+
if (responseTexts && responseTexts.length > 0) {
|
|
58
|
+
for (const text of responseTexts) {
|
|
59
|
+
if (text && typeof text === 'string') {
|
|
60
|
+
const words = text.toLowerCase().trim().split(/\s+/);
|
|
61
|
+
for (const word of words) {
|
|
62
|
+
if (word && ['basic', 'cpu', 'memory', 'disk', 'network', 'process', 'environment', 'all'].includes(word)) {
|
|
63
|
+
categories.add(word);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
// No valid responses, default to basic
|
|
70
|
+
console.log('No valid AI responses for system info query, defaulting to basic');
|
|
71
|
+
categories.add('basic');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// If 'all' is included, just return that
|
|
75
|
+
if (categories.has('all')) {
|
|
76
|
+
return { query: 'all' };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// If no categories were determined, default to basic
|
|
80
|
+
if (categories.size === 0) {
|
|
81
|
+
categories.add('basic');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Convert the set to a space-separated string
|
|
85
|
+
const query = Array.from(categories).join(' ');
|
|
86
|
+
|
|
87
|
+
return { query };
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('❌ Error determining system info query:', error.message);
|
|
90
|
+
// Default to basic info if there's an error
|
|
91
|
+
return { query: 'basic' };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if a prompt is related to system information
|
|
97
|
+
* @param {string} prompt - The user's prompt
|
|
98
|
+
* @returns {boolean} True if the prompt is related to system information
|
|
99
|
+
*/
|
|
100
|
+
function isSystemInfoQuery(prompt) {
|
|
101
|
+
// Always return true for /system commands - we'll let the AI determine relevance
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Format system information into a readable response
|
|
107
|
+
* @param {Object} sysInfo - System information object
|
|
108
|
+
* @param {string} prompt - The original prompt
|
|
109
|
+
* @returns {string} Formatted response
|
|
110
|
+
*/
|
|
111
|
+
function formatSystemInfoResponse(sysInfo, prompt) {
|
|
112
|
+
let response = `Here's the system information you requested:\n\n`;
|
|
113
|
+
|
|
114
|
+
// Check if we have any system information
|
|
115
|
+
const hasInfo = Object.keys(sysInfo).length > 0;
|
|
116
|
+
|
|
117
|
+
if (!hasInfo) {
|
|
118
|
+
response = `I couldn't find specific system information for your query: "${prompt}"\n\n`;
|
|
119
|
+
response += `You can ask about:\n`;
|
|
120
|
+
response += `- Basic system information (platform, architecture, hostname, manufacturer, model)\n`;
|
|
121
|
+
response += `- CPU information (model, cores, speed, load, temperature, manufacturer)\n`;
|
|
122
|
+
response += `- Memory information (total, used, free, active, available, swap)\n`;
|
|
123
|
+
response += `- Disk information (size, used, available, file systems, block devices)\n`;
|
|
124
|
+
response += `- Network information (interfaces, IP addresses, connections, wifi, latency)\n`;
|
|
125
|
+
response += `- Process information (running processes, services, resource usage)\n`;
|
|
126
|
+
response += `- Environment variables (PATH, SHELL, user info, etc.)\n\n`;
|
|
127
|
+
response += `Try queries like:\n`;
|
|
128
|
+
response += `- "What's my IP address?" (network)\n`;
|
|
129
|
+
response += `- "How much disk space do I have?" (disk)\n`;
|
|
130
|
+
response += `- "What's my CPU usage?" (cpu)\n`;
|
|
131
|
+
response += `- "Show me all system information" (all)\n\n`;
|
|
132
|
+
return response;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (sysInfo.basic) {
|
|
136
|
+
const basic = sysInfo.basic;
|
|
137
|
+
response += `📱 **System Overview**\n`;
|
|
138
|
+
response += `- Platform: ${basic.platform} (${basic.type} ${basic.release})\n`;
|
|
139
|
+
response += `- Architecture: ${basic.arch}\n`;
|
|
140
|
+
response += `- Hostname: ${basic.hostname}\n`;
|
|
141
|
+
response += `- Uptime: ${Math.floor(basic.uptime / 3600)} hours ${Math.floor((basic.uptime % 3600) / 60)} minutes\n`;
|
|
142
|
+
|
|
143
|
+
// Add enhanced system information if available
|
|
144
|
+
if (basic.manufacturer) response += `- Manufacturer: ${basic.manufacturer}\n`;
|
|
145
|
+
if (basic.model) response += `- Model: ${basic.model}\n`;
|
|
146
|
+
if (basic.version) response += `- Version: ${basic.version}\n`;
|
|
147
|
+
if (basic.serial) response += `- Serial Number: ${basic.serial}\n`;
|
|
148
|
+
if (basic.uuid) response += `- UUID: ${basic.uuid}\n`;
|
|
149
|
+
if (basic.sku) response += `- SKU: ${basic.sku}\n`;
|
|
150
|
+
if (basic.virtual) response += `- Virtualization: ${basic.virtual ? 'Yes' : 'No'}\n`;
|
|
151
|
+
if (basic.distro) response += `- Distribution: ${basic.distro}\n`;
|
|
152
|
+
if (basic.codename) response += `- Codename: ${basic.codename}\n`;
|
|
153
|
+
if (basic.kernel) response += `- Kernel: ${basic.kernel}\n`;
|
|
154
|
+
|
|
155
|
+
response += `\n`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (sysInfo.cpu) {
|
|
159
|
+
const cpu = sysInfo.cpu;
|
|
160
|
+
response += `💻 **CPU Information**\n`;
|
|
161
|
+
response += `- Model: ${cpu.model}\n`;
|
|
162
|
+
response += `- Cores: ${cpu.cores}\n`;
|
|
163
|
+
response += `- Speed: ${cpu.speed} MHz\n`;
|
|
164
|
+
response += `- Load Average: ${cpu.loadAvg.map(load => load.toFixed(2)).join(', ')}\n`;
|
|
165
|
+
|
|
166
|
+
// Add enhanced CPU information if available
|
|
167
|
+
if (cpu.manufacturer) response += `- Manufacturer: ${cpu.manufacturer}\n`;
|
|
168
|
+
if (cpu.brand) response += `- Brand: ${cpu.brand}\n`;
|
|
169
|
+
if (cpu.physicalCores) response += `- Physical Cores: ${cpu.physicalCores}\n`;
|
|
170
|
+
if (cpu.processors) response += `- Processors: ${cpu.processors}\n`;
|
|
171
|
+
if (cpu.socket) response += `- Socket: ${cpu.socket}\n`;
|
|
172
|
+
if (cpu.vendor) response += `- Vendor: ${cpu.vendor}\n`;
|
|
173
|
+
if (cpu.family) response += `- Family: ${cpu.family}\n`;
|
|
174
|
+
if (cpu.stepping) response += `- Stepping: ${cpu.stepping}\n`;
|
|
175
|
+
if (cpu.virtualization) response += `- Virtualization: ${cpu.virtualization}\n`;
|
|
176
|
+
if (cpu.cache) {
|
|
177
|
+
response += `- Cache:\n`;
|
|
178
|
+
Object.entries(cpu.cache).forEach(([level, size]) => {
|
|
179
|
+
response += ` - ${level}: ${size}\n`;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
if (cpu.temperature) response += `- Temperature: ${cpu.temperature}°C\n`;
|
|
183
|
+
if (cpu.currentLoad) response += `- Current Load: ${cpu.currentLoad.toFixed(2)}%\n`;
|
|
184
|
+
if (cpu.currentLoadUser) response += `- User Load: ${cpu.currentLoadUser.toFixed(2)}%\n`;
|
|
185
|
+
if (cpu.currentLoadSystem) response += `- System Load: ${cpu.currentLoadSystem.toFixed(2)}%\n`;
|
|
186
|
+
|
|
187
|
+
response += `\n`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (sysInfo.memory) {
|
|
191
|
+
const memory = sysInfo.memory;
|
|
192
|
+
response += `🧠 **Memory Information**\n`;
|
|
193
|
+
response += `- Total: ${memory.total}\n`;
|
|
194
|
+
response += `- Used: ${memory.used} (${memory.usagePercent})\n`;
|
|
195
|
+
response += `- Free: ${memory.free}\n`;
|
|
196
|
+
|
|
197
|
+
// Add enhanced memory information if available
|
|
198
|
+
if (memory.active) response += `- Active: ${memory.active}\n`;
|
|
199
|
+
if (memory.available) response += `- Available: ${memory.available}\n`;
|
|
200
|
+
if (memory.buffers) response += `- Buffers: ${memory.buffers}\n`;
|
|
201
|
+
if (memory.cached) response += `- Cached: ${memory.cached}\n`;
|
|
202
|
+
if (memory.slab) response += `- Slab: ${memory.slab}\n`;
|
|
203
|
+
if (memory.swapTotal) response += `- Swap Total: ${memory.swapTotal}\n`;
|
|
204
|
+
if (memory.swapUsed) response += `- Swap Used: ${memory.swapUsed}\n`;
|
|
205
|
+
if (memory.swapFree) response += `- Swap Free: ${memory.swapFree}\n`;
|
|
206
|
+
|
|
207
|
+
// Add memory layout information if available
|
|
208
|
+
if (memory.layout && Array.isArray(memory.layout) && memory.layout.length > 0) {
|
|
209
|
+
response += `- Memory Modules:\n`;
|
|
210
|
+
memory.layout.forEach((module, index) => {
|
|
211
|
+
response += ` - Module ${index + 1}:\n`;
|
|
212
|
+
if (module.size) response += ` - Size: ${formatBytes(module.size)}\n`;
|
|
213
|
+
if (module.bank) response += ` - Bank: ${module.bank}\n`;
|
|
214
|
+
if (module.type) response += ` - Type: ${module.type}\n`;
|
|
215
|
+
if (module.clockSpeed) response += ` - Clock Speed: ${module.clockSpeed} MHz\n`;
|
|
216
|
+
if (module.formFactor) response += ` - Form Factor: ${module.formFactor}\n`;
|
|
217
|
+
if (module.manufacturer) response += ` - Manufacturer: ${module.manufacturer}\n`;
|
|
218
|
+
if (module.partNum) response += ` - Part Number: ${module.partNum}\n`;
|
|
219
|
+
if (module.serialNum) response += ` - Serial Number: ${module.serialNum}\n`;
|
|
220
|
+
if (module.voltageConfigured) response += ` - Voltage: ${module.voltageConfigured} V\n`;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
response += `\n`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (sysInfo.disk) {
|
|
228
|
+
response += `💾 **Disk Information**\n`;
|
|
229
|
+
|
|
230
|
+
// Handle enhanced disk information
|
|
231
|
+
if (sysInfo.disk.fsSize && Array.isArray(sysInfo.disk.fsSize)) {
|
|
232
|
+
response += `- File Systems:\n`;
|
|
233
|
+
sysInfo.disk.fsSize.forEach(fs => {
|
|
234
|
+
response += ` - ${fs.fs} (${fs.type}):\n`;
|
|
235
|
+
response += ` - Mount: ${fs.mount}\n`;
|
|
236
|
+
response += ` - Size: ${fs.size ? formatBytes(fs.size) : 'N/A'}\n`;
|
|
237
|
+
response += ` - Used: ${fs.used ? formatBytes(fs.used) : 'N/A'} (${fs.use ? fs.use.toFixed(1) + '%' : 'N/A'})\n`;
|
|
238
|
+
response += ` - Available: ${fs.available ? formatBytes(fs.available) : 'N/A'}\n`;
|
|
239
|
+
});
|
|
240
|
+
} else if (Array.isArray(sysInfo.disk)) {
|
|
241
|
+
// Windows format (legacy)
|
|
242
|
+
sysInfo.disk.forEach(disk => {
|
|
243
|
+
response += `- Drive ${disk.drive}:\n`;
|
|
244
|
+
response += ` - Size: ${disk.size}\n`;
|
|
245
|
+
response += ` - Used: ${disk.used} (${disk.usagePercent})\n`;
|
|
246
|
+
response += ` - Free: ${disk.free}\n`;
|
|
247
|
+
});
|
|
248
|
+
} else if (sysInfo.disk.error) {
|
|
249
|
+
response += `- Error retrieving disk information: ${sysInfo.disk.error}\n`;
|
|
250
|
+
} else if (sysInfo.disk.filesystem) {
|
|
251
|
+
// Unix format (legacy)
|
|
252
|
+
response += `- Filesystem: ${sysInfo.disk.filesystem}\n`;
|
|
253
|
+
response += `- Size: ${sysInfo.disk.size}\n`;
|
|
254
|
+
response += `- Used: ${sysInfo.disk.used} (${sysInfo.disk.usagePercent})\n`;
|
|
255
|
+
response += `- Available: ${sysInfo.disk.available}\n`;
|
|
256
|
+
response += `- Mounted on: ${sysInfo.disk.mountedOn}\n`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Add block devices information if available
|
|
260
|
+
if (sysInfo.disk.blockDevices && Array.isArray(sysInfo.disk.blockDevices)) {
|
|
261
|
+
response += `- Block Devices:\n`;
|
|
262
|
+
sysInfo.disk.blockDevices.forEach(device => {
|
|
263
|
+
response += ` - ${device.name}:\n`;
|
|
264
|
+
if (device.type) response += ` - Type: ${device.type}\n`;
|
|
265
|
+
if (device.size) response += ` - Size: ${formatBytes(device.size)}\n`;
|
|
266
|
+
if (device.physical) response += ` - Physical: ${device.physical}\n`;
|
|
267
|
+
if (device.uuid) response += ` - UUID: ${device.uuid}\n`;
|
|
268
|
+
if (device.label) response += ` - Label: ${device.label}\n`;
|
|
269
|
+
if (device.model) response += ` - Model: ${device.model}\n`;
|
|
270
|
+
if (device.serial) response += ` - Serial: ${device.serial}\n`;
|
|
271
|
+
if (device.removable !== undefined) response += ` - Removable: ${device.removable ? 'Yes' : 'No'}\n`;
|
|
272
|
+
if (device.protocol) response += ` - Protocol: ${device.protocol}\n`;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Add disk layout information if available
|
|
277
|
+
if (sysInfo.disk.diskLayout && Array.isArray(sysInfo.disk.diskLayout)) {
|
|
278
|
+
response += `- Disk Layout:\n`;
|
|
279
|
+
sysInfo.disk.diskLayout.forEach(disk => {
|
|
280
|
+
response += ` - ${disk.device}:\n`;
|
|
281
|
+
if (disk.type) response += ` - Type: ${disk.type}\n`;
|
|
282
|
+
if (disk.name) response += ` - Name: ${disk.name}\n`;
|
|
283
|
+
if (disk.vendor) response += ` - Vendor: ${disk.vendor}\n`;
|
|
284
|
+
if (disk.size) response += ` - Size: ${formatBytes(disk.size)}\n`;
|
|
285
|
+
if (disk.bytesPerSector) response += ` - Bytes Per Sector: ${disk.bytesPerSector}\n`;
|
|
286
|
+
if (disk.totalCylinders) response += ` - Total Cylinders: ${disk.totalCylinders}\n`;
|
|
287
|
+
if (disk.totalHeads) response += ` - Total Heads: ${disk.totalHeads}\n`;
|
|
288
|
+
if (disk.totalSectors) response += ` - Total Sectors: ${disk.totalSectors}\n`;
|
|
289
|
+
if (disk.totalTracks) response += ` - Total Tracks: ${disk.totalTracks}\n`;
|
|
290
|
+
if (disk.tracksPerCylinder) response += ` - Tracks Per Cylinder: ${disk.tracksPerCylinder}\n`;
|
|
291
|
+
if (disk.sectorsPerTrack) response += ` - Sectors Per Track: ${disk.sectorsPerTrack}\n`;
|
|
292
|
+
if (disk.firmwareRevision) response += ` - Firmware Revision: ${disk.firmwareRevision}\n`;
|
|
293
|
+
if (disk.serialNum) response += ` - Serial Number: ${disk.serialNum}\n`;
|
|
294
|
+
if (disk.interfaceType) response += ` - Interface Type: ${disk.interfaceType}\n`;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
response += `\n`;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (sysInfo.network) {
|
|
302
|
+
response += `🌐 **Network Information**\n`;
|
|
303
|
+
|
|
304
|
+
// Handle enhanced network interfaces information
|
|
305
|
+
if (sysInfo.network.interfaces && Array.isArray(sysInfo.network.interfaces)) {
|
|
306
|
+
response += `- Interfaces:\n`;
|
|
307
|
+
sysInfo.network.interfaces.forEach(iface => {
|
|
308
|
+
if (!iface.internal) { // Only show external interfaces
|
|
309
|
+
response += ` - ${iface.iface}:\n`;
|
|
310
|
+
if (iface.ifaceName) response += ` - Name: ${iface.ifaceName}\n`;
|
|
311
|
+
if (iface.ip4) response += ` - IPv4: ${iface.ip4}\n`;
|
|
312
|
+
if (iface.ip6) response += ` - IPv6: ${iface.ip6}\n`;
|
|
313
|
+
if (iface.mac) response += ` - MAC: ${iface.mac}\n`;
|
|
314
|
+
if (iface.speed) response += ` - Speed: ${iface.speed} Mbps\n`;
|
|
315
|
+
if (iface.type) response += ` - Type: ${iface.type}\n`;
|
|
316
|
+
if (iface.operstate) response += ` - State: ${iface.operstate}\n`;
|
|
317
|
+
if (iface.carrier !== undefined) response += ` - Carrier: ${iface.carrier ? 'Yes' : 'No'}\n`;
|
|
318
|
+
if (iface.mtu) response += ` - MTU: ${iface.mtu}\n`;
|
|
319
|
+
if (iface.dhcp !== undefined) response += ` - DHCP: ${iface.dhcp ? 'Yes' : 'No'}\n`;
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
} else if (Array.isArray(sysInfo.network)) {
|
|
323
|
+
// Legacy format
|
|
324
|
+
sysInfo.network.forEach(net => {
|
|
325
|
+
if (!net.internal) { // Only show external interfaces
|
|
326
|
+
response += `- Interface: ${net.interface}\n`;
|
|
327
|
+
response += ` - IP Address: ${net.address}\n`;
|
|
328
|
+
response += ` - Netmask: ${net.netmask}\n`;
|
|
329
|
+
response += ` - MAC: ${net.mac}\n`;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Add network stats if available
|
|
335
|
+
if (sysInfo.network.stats && Array.isArray(sysInfo.network.stats)) {
|
|
336
|
+
response += `- Network Stats:\n`;
|
|
337
|
+
sysInfo.network.stats.forEach(stat => {
|
|
338
|
+
if (!stat.iface.includes('lo')) { // Skip loopback
|
|
339
|
+
response += ` - ${stat.iface}:\n`;
|
|
340
|
+
if (stat.rx_bytes) response += ` - Received: ${formatBytes(stat.rx_bytes)}\n`;
|
|
341
|
+
if (stat.tx_bytes) response += ` - Sent: ${formatBytes(stat.tx_bytes)}\n`;
|
|
342
|
+
if (stat.rx_errors) response += ` - Receive Errors: ${stat.rx_errors}\n`;
|
|
343
|
+
if (stat.tx_errors) response += ` - Send Errors: ${stat.tx_errors}\n`;
|
|
344
|
+
if (stat.rx_dropped) response += ` - Receive Dropped: ${stat.rx_dropped}\n`;
|
|
345
|
+
if (stat.tx_dropped) response += ` - Send Dropped: ${stat.tx_dropped}\n`;
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Add connection information if available
|
|
351
|
+
if (sysInfo.network.connections && sysInfo.network.connections.length > 0) {
|
|
352
|
+
const connections = sysInfo.network.connections;
|
|
353
|
+
const totalConnections = connections.length;
|
|
354
|
+
const establishedCount = connections.filter(conn => conn.state === 'ESTABLISHED').length;
|
|
355
|
+
const listeningCount = connections.filter(conn => conn.state === 'LISTEN').length;
|
|
356
|
+
|
|
357
|
+
response += `- Connections:\n`;
|
|
358
|
+
response += ` - Total: ${totalConnections}\n`;
|
|
359
|
+
response += ` - Established: ${establishedCount}\n`;
|
|
360
|
+
response += ` - Listening: ${listeningCount}\n`;
|
|
361
|
+
|
|
362
|
+
// Show top 5 connections
|
|
363
|
+
if (totalConnections > 0) {
|
|
364
|
+
response += ` - Top 5 Connections:\n`;
|
|
365
|
+
connections.slice(0, 5).forEach(conn => {
|
|
366
|
+
response += ` - ${conn.protocol} ${conn.localAddress}:${conn.localPort} -> ${conn.peerAddress}:${conn.peerPort} (${conn.state})\n`;
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Add wifi networks if available
|
|
372
|
+
if (sysInfo.network.wifiNetworks && Array.isArray(sysInfo.network.wifiNetworks)) {
|
|
373
|
+
response += `- WiFi Networks:\n`;
|
|
374
|
+
sysInfo.network.wifiNetworks.forEach(network => {
|
|
375
|
+
response += ` - ${network.ssid}:\n`;
|
|
376
|
+
if (network.bssid) response += ` - BSSID: ${network.bssid}\n`;
|
|
377
|
+
if (network.mode) response += ` - Mode: ${network.mode}\n`;
|
|
378
|
+
if (network.channel) response += ` - Channel: ${network.channel}\n`;
|
|
379
|
+
if (network.frequency) response += ` - Frequency: ${network.frequency} MHz\n`;
|
|
380
|
+
if (network.signalLevel) response += ` - Signal Level: ${network.signalLevel} dBm\n`;
|
|
381
|
+
if (network.quality) response += ` - Quality: ${network.quality}/100\n`;
|
|
382
|
+
if (network.security) response += ` - Security: ${network.security.join(', ')}\n`;
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Add internet connectivity information if available
|
|
387
|
+
if (sysInfo.network.internetLatency !== undefined) {
|
|
388
|
+
response += `- Internet Connectivity:\n`;
|
|
389
|
+
response += ` - Latency: ${sysInfo.network.internetLatency.toFixed(2)} ms\n`;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Add public IP if available
|
|
393
|
+
if (sysInfo.network.publicIp) {
|
|
394
|
+
response += `- Public IP: ${sysInfo.network.publicIp}\n`;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
response += `\n`;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (sysInfo.environment) {
|
|
401
|
+
response += `🔧 **Environment Variables**\n`;
|
|
402
|
+
|
|
403
|
+
// Add user information if available
|
|
404
|
+
if (sysInfo.environment.user) {
|
|
405
|
+
const user = sysInfo.environment.user;
|
|
406
|
+
response += `- User Information:\n`;
|
|
407
|
+
if (user.username) response += ` - Username: ${user.username}\n`;
|
|
408
|
+
if (user.uid) response += ` - UID: ${user.uid}\n`;
|
|
409
|
+
if (user.gid) response += ` - GID: ${user.gid}\n`;
|
|
410
|
+
if (user.shell) response += ` - Shell: ${user.shell}\n`;
|
|
411
|
+
if (user.homedir) response += ` - Home Directory: ${user.homedir}\n`;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Add shell history if available
|
|
415
|
+
if (sysInfo.environment.shell && sysInfo.environment.shell.length > 0) {
|
|
416
|
+
response += `- Recent Shell Commands:\n`;
|
|
417
|
+
sysInfo.environment.shell.slice(0, 5).forEach((cmd, index) => {
|
|
418
|
+
response += ` - ${index + 1}: ${cmd}\n`;
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Add environment variables
|
|
423
|
+
if (sysInfo.environment.variables) {
|
|
424
|
+
response += `- Environment Variables:\n`;
|
|
425
|
+
for (const [key, value] of Object.entries(sysInfo.environment.variables)) {
|
|
426
|
+
response += ` - ${key}: ${value}\n`;
|
|
427
|
+
}
|
|
428
|
+
} else {
|
|
429
|
+
// Legacy format
|
|
430
|
+
for (const [key, value] of Object.entries(sysInfo.environment)) {
|
|
431
|
+
if (typeof value === 'string') {
|
|
432
|
+
response += `- ${key}: ${value}\n`;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
response += `\n`;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (sysInfo.process) {
|
|
441
|
+
response += `⚙️ **Process Information**\n`;
|
|
442
|
+
|
|
443
|
+
// Add current process information
|
|
444
|
+
if (sysInfo.process.current) {
|
|
445
|
+
const current = sysInfo.process.current;
|
|
446
|
+
response += `- Current Process:\n`;
|
|
447
|
+
if (current.pid) response += ` - PID: ${current.pid}\n`;
|
|
448
|
+
if (current.ppid) response += ` - Parent PID: ${current.ppid}\n`;
|
|
449
|
+
if (current.name) response += ` - Name: ${current.name}\n`;
|
|
450
|
+
if (current.cpu) response += ` - CPU Usage: ${current.cpu.toFixed(2)}%\n`;
|
|
451
|
+
if (current.memory) response += ` - Memory Usage: ${formatBytes(current.memory)}\n`;
|
|
452
|
+
if (current.started) response += ` - Started: ${new Date(current.started).toLocaleString()}\n`;
|
|
453
|
+
if (current.state) response += ` - State: ${current.state}\n`;
|
|
454
|
+
if (current.path) response += ` - Path: ${current.path}\n`;
|
|
455
|
+
if (current.command) response += ` - Command: ${current.command}\n`;
|
|
456
|
+
if (current.params) response += ` - Parameters: ${current.params.join(' ')}\n`;
|
|
457
|
+
} else {
|
|
458
|
+
// Legacy format
|
|
459
|
+
response += `- PID: ${sysInfo.process.pid}\n`;
|
|
460
|
+
response += `- Node.js Version: ${sysInfo.process.version}\n`;
|
|
461
|
+
response += `- Current Directory: ${sysInfo.process.cwd}\n`;
|
|
462
|
+
response += `- Memory Usage: ${Math.round(sysInfo.process.memoryUsage.rss / (1024 * 1024))} MB\n`;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Add process summary if available
|
|
466
|
+
if (sysInfo.process.summary) {
|
|
467
|
+
const summary = sysInfo.process.summary;
|
|
468
|
+
response += `- Process Summary:\n`;
|
|
469
|
+
if (summary.total) response += ` - Total: ${summary.total}\n`;
|
|
470
|
+
if (summary.running) response += ` - Running: ${summary.running}\n`;
|
|
471
|
+
if (summary.blocked) response += ` - Blocked: ${summary.blocked}\n`;
|
|
472
|
+
if (summary.sleeping) response += ` - Sleeping: ${summary.sleeping}\n`;
|
|
473
|
+
if (summary.unknown) response += ` - Unknown: ${summary.unknown}\n`;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Add top processes if available
|
|
477
|
+
if (sysInfo.process.list && Array.isArray(sysInfo.process.list)) {
|
|
478
|
+
response += `- Top Processes (by CPU):\n`;
|
|
479
|
+
sysInfo.process.list.slice(0, 10).forEach((proc, index) => {
|
|
480
|
+
response += ` - ${index + 1}: ${proc.name} (PID: ${proc.pid})\n`;
|
|
481
|
+
response += ` - CPU: ${proc.cpu.toFixed(2)}%, Memory: ${formatBytes(proc.mem)}\n`;
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Add services if available
|
|
486
|
+
if (sysInfo.process.services && Array.isArray(sysInfo.process.services)) {
|
|
487
|
+
response += `- System Services:\n`;
|
|
488
|
+
sysInfo.process.services.slice(0, 10).forEach((service, index) => {
|
|
489
|
+
response += ` - ${index + 1}: ${service.name} (${service.running ? 'Running' : 'Stopped'})\n`;
|
|
490
|
+
if (service.pids && service.pids.length > 0) {
|
|
491
|
+
response += ` - PIDs: ${service.pids.join(', ')}\n`;
|
|
492
|
+
}
|
|
493
|
+
if (service.startmode) response += ` - Start Mode: ${service.startmode}\n`;
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
response += `\n`;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return response;
|
|
501
|
+
}
|
|
3
502
|
|
|
4
503
|
async function processWithAI(prompt, context = '') {
|
|
5
504
|
try {
|
|
505
|
+
// Check if the prompt is related to system information
|
|
506
|
+
if (isSystemInfoQuery(prompt)) {
|
|
507
|
+
try {
|
|
508
|
+
// First get basic system info to provide context
|
|
509
|
+
const basicInfo = await getSystemInfo('basic');
|
|
510
|
+
|
|
511
|
+
// Use AI to determine what system information is being requested
|
|
512
|
+
const aiResponse = await determineSystemInfoQuery(prompt, basicInfo);
|
|
513
|
+
|
|
514
|
+
// Get the specific system information based on AI's determination
|
|
515
|
+
const systemInfo = await getSystemInfo(aiResponse.query);
|
|
516
|
+
return formatSystemInfoResponse(systemInfo, prompt);
|
|
517
|
+
} catch (sysError) {
|
|
518
|
+
console.error('❌ System info error:', sysError.message);
|
|
519
|
+
// If system info fails, fall back to AI processing
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Regular AI processing
|
|
6
524
|
const models = ['kimi', 'mvrk', 'gma3', 'dsv3', 'qw32b', 'ms24b', 'll70b', 'qw3', 'mp4', 'nlm3'];
|
|
7
525
|
|
|
8
526
|
const modelRequests = models.map(model =>
|
|
@@ -46,5 +564,8 @@ async function processWithAI(prompt, context = '') {
|
|
|
46
564
|
}
|
|
47
565
|
|
|
48
566
|
module.exports = {
|
|
49
|
-
processWithAI
|
|
567
|
+
processWithAI,
|
|
568
|
+
determineSystemInfoQuery,
|
|
569
|
+
isSystemInfoQuery,
|
|
570
|
+
formatSystemInfoResponse
|
|
50
571
|
};
|