trace.ai-cli
Version:
A powerful AI-powered CLI tool
652 lines (564 loc) • 28.4 kB
JavaScript
const fetch = require('node-fetch');
const { encryptData, decryptData } = require('../utils/encryption');
const { getSystemInfo, formatBytes } = require('./systemInfoService');
// Mode selection helpers
function getMode(mode) {
switch (Number(mode)) {
case 1: // Fast
return 'fast';
case 2: // Balanced
return 'balance';
case 3: // Think
return 'think';
default:
return 'balance';
}
}
/**
* Use AI to determine what system information is being requested
* @param {string} prompt - The user's prompt
* @param {Object} basicInfo - Basic system information for context
* @returns {Object} Object containing the determined query
*/
async function determineSystemInfoQuery(prompt, basicInfo) {
try {
// Create a more specific prompt for the AI to analyze the user's query
const currentTimestamp = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''); // Format YYYY-MM-DD HH:MM:SS
const analysisPrompt = `Current Date/Time: ${currentTimestamp} UTC
User: ${basicInfo.user}
Analyze this user query about system information: "${prompt}"
Determine which categories of system information the user is asking about. Respond with one or more of these exact categories separated by spaces:
- basic (for OS, platform, architecture, hostname, manufacturer, model, uptime info)
- cpu (for processor, cores, speed, load, temperature, performance info)
- memory (for RAM, swap, memory usage, available memory info)
- disk (for storage, disk space, drives, file systems, partition info)
- network (for network interfaces, IP addresses, connections, wifi, bandwidth info)
- process (for running processes, services, applications, resource usage info)
- environment (for environment variables, user info, shell info, system config)
- all (for complete comprehensive system information)
Examples:
"What's my CPU usage?" -> cpu
"How much RAM do I have?" -> memory
"Show me my IP address" -> network
"What processes are running?" -> process
"System overview" -> basic
"Complete system info" -> all
"CPU and memory info" -> cpu memory
"Network and disk status" -> network disk
Only respond with the category names, nothing else. Be precise and focus on what the user actually needs.`;
// Use AI to analyze the query with balanced mode
const mode = getMode(2); // Balanced by default
try {
const response = await fetch('https://traceai.dukeindustries7.workers.dev/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: encryptData({
a: mode,
q: analysisPrompt,
i: [],
c: JSON.stringify({
basicInfo,
timestamp: currentTimestamp,
user: basicInfo.user
})
})
});
const text = await response.text();
const decrypted = decryptData(text);
const responses = [decrypted];
// Filter out null responses and extract valid text
const validResponses = responses
.filter(r => r && r.text && typeof r.text === 'string')
.map(r => r.text.toLowerCase().trim());
// Analyze responses to determine categories
let categories = new Set();
const validCategories = ['basic', 'cpu', 'memory', 'disk', 'network', 'process', 'environment', 'all'];
if (validResponses.length > 0) {
// Process each response and count category occurrences
const categoryCount = {};
for (const response of validResponses) {
const words = response.split(/\s+/);
for (const word of words) {
if (validCategories.includes(word)) {
categoryCount[word] = (categoryCount[word] || 0) + 1;
categories.add(word);
}
}
}
// If we found 'all', that takes precedence
if (categories.has('all')) {
return { query: 'all' };
}
// If we have valid categories, use the most commonly mentioned ones
if (categories.size > 0) {
// Sort categories by frequency and take top ones
const sortedCategories = Object.entries(categoryCount)
.sort(([, a], [, b]) => b - a)
.map(([category]) => category);
const query = sortedCategories.join(' ');
return { query };
}
}
} catch (e) {
// If API call fails, fall through to keyword matching
}
// Fallback: use keyword matching if AI didn't provide valid responses
const fallbackCategories = determineCategoriesByKeywords(prompt);
return { query: fallbackCategories };
} catch (error) {
// Final fallback to basic info
return { query: 'basic' };
}
}
/**
* Fallback function to determine categories using keyword matching
* @param {string} prompt - The user's prompt
* @returns {string} Space-separated categories
*/
function determineCategoriesByKeywords(prompt) {
const lowerPrompt = prompt.toLowerCase();
const categories = new Set();
// Define comprehensive keyword patterns for each category
const patterns = {
cpu: [
'cpu', 'processor', 'core', 'thread', 'clock', 'speed', 'ghz', 'mhz',
'load', 'usage', 'temperature', 'intel', 'amd', 'arm', 'performance',
'benchmark', 'processing', 'compute', 'cores', 'threads', 'frequency'
],
memory: [
'memory', 'ram', 'swap', 'heap', 'free', 'available', 'used', 'total',
'dram', 'dimm', 'stick', 'module', 'allocation', 'buffer', 'cache',
'virtual memory', 'physical memory', 'memory usage'
],
disk: [
'disk', 'drive', 'storage', 'space', 'filesystem', 'mount', 'partition',
'volume', 'hdd', 'ssd', 'nvme', 'capacity', 'free space', 'used space',
'hard drive', 'solid state', 'storage device', 'file system'
],
network: [
'network', 'internet', 'wifi', 'ip', 'address', 'connection', 'interface',
'ethernet', 'wireless', 'lan', 'wan', 'dns', 'gateway', 'router', 'subnet',
'bandwidth', 'latency', 'ping', 'download', 'upload', 'mac address'
],
process: [
'process', 'running', 'task', 'application', 'service', 'pid', 'program',
'app', 'daemon', 'thread', 'job', 'kill', 'terminate', 'processes',
'services', 'applications', 'background', 'foreground'
],
environment: [
'environment', 'env', 'variable', 'path', 'user', 'shell', 'config',
'terminal', 'console', 'profile', 'configuration', 'setting', 'preference',
'login', 'session', 'account', 'variables'
],
basic: [
'system', 'os', 'platform', 'version', 'architecture', 'hostname', 'machine',
'overview', 'info', 'information', 'details', 'specs', 'specification',
'operating system', 'computer', 'device', 'hardware'
]
};
// Check for 'all' keywords first
const allKeywords = ['all', 'everything', 'complete', 'full', 'entire', 'comprehensive'];
if (allKeywords.some(keyword => lowerPrompt.includes(keyword))) {
return 'all';
}
// Check each category and count matches
const categoryMatches = {};
for (const [category, keywords] of Object.entries(patterns)) {
const matches = keywords.filter(keyword => lowerPrompt.includes(keyword));
if (matches.length > 0) {
categories.add(category);
categoryMatches[category] = matches;
}
}
// If no categories matched, default to basic
if (categories.size === 0) {
categories.add('basic');
}
const result = Array.from(categories).join(' ');
return result;
}
/**
* Format system information into a readable response using AI
* @param {Object} sysInfo - System information object
* @param {string} prompt - The original prompt
* @returns {string} Formatted response
*/
async function formatSystemInfoResponse(sysInfo, prompt) {
try {
// Check if we have any system information
const hasInfo = Object.keys(sysInfo).length > 0;
if (!hasInfo) {
return getHelpMessage(prompt);
}
// Use AI to format the response based on the user's specific question
const formattingPrompt = `Current Date/Time: 2025-07-09 10:45:40 UTC
User: m0v0dga_walmart
The user asked: "${prompt}"
Here is the system information that was gathered:
${JSON.stringify(sysInfo, null, 2)}
Please format this system information into a clear, readable response that directly answers the user's question. Focus on the most relevant information for their query.
Formatting Guidelines:
- Start with a brief intro addressing their specific question
- Use bullet points and clear sections for organization
- Include relevant technical details but keep it understandable
- Use appropriate emojis for visual appeal:
💻 for CPU/Processor info
🧠 for Memory/RAM info
💾 for Disk/Storage info
🌐 for Network/Internet info
⚙️ for Process/Service info
🔧 for Environment/Config info
📱 for Basic/System info
- Format bytes/numbers in human-readable format
- Only include information that's directly relevant to their question
- Keep it concise but comprehensive
- Add context about what the numbers mean if helpful
- Include timestamp: "System information as of 2025-07-09 10:45:40 UTC"
Make the response helpful and easy to understand for the user.`;
try {
const response = await fetch('https://traceai.dukeindustries7.workers.dev/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: encryptData({
a: getMode(2), // Use balanced mode for formatting
q: formattingPrompt,
i: [],
c: JSON.stringify({
timestamp: '2025-07-09 10:45:40',
user: 'm0v0dga_walmart',
originalPrompt: prompt
})
})
});
const encryptedResult = await response.text();
const decryptedResult = decryptData(encryptedResult);
if (decryptedResult.text && typeof decryptedResult.text === 'string') {
return decryptedResult.text;
}
} catch (aiError) {
}
// Fallback to manual formatting if AI fails
return formatSystemInfoManually(sysInfo, prompt);
} catch (error) {
// Fallback to manual formatting
return formatSystemInfoManually(sysInfo, prompt);
}
}
/**
* Manual formatting fallback with enhanced output
* @param {Object} sysInfo - System information object
* @param {string} prompt - The original prompt
* @returns {string} Formatted response
*/
function formatSystemInfoManually(sysInfo, prompt) {
let response = `Here's the system information you requested:\n\n`;
response += `*System information as of 2025-07-09 10:45:40 UTC*\n\n`;
if (sysInfo.basic) {
const basic = sysInfo.basic;
response += `📱 **System Overview**\n`;
response += `- Platform: ${basic.platform || 'Unknown'} (${basic.type || 'Unknown'} ${basic.release || 'Unknown'})\n`;
response += `- Architecture: ${basic.arch || 'Unknown'}\n`;
response += `- Hostname: ${basic.hostname || 'Unknown'}\n`;
if (basic.manufacturer) response += `- Manufacturer: ${basic.manufacturer}\n`;
if (basic.model) response += `- Model: ${basic.model}\n`;
if (basic.distro) response += `- Distribution: ${basic.distro}\n`;
if (basic.kernel) response += `- Kernel: ${basic.kernel}\n`;
const uptimeHours = Math.floor((basic.uptime || 0) / 3600);
const uptimeMinutes = Math.floor(((basic.uptime || 0) % 3600) / 60);
response += `- Uptime: ${uptimeHours} hours ${uptimeMinutes} minutes\n`;
if (basic.loadAvg && Array.isArray(basic.loadAvg)) {
response += `- Load Average: ${basic.loadAvg.map(load => load.toFixed(2)).join(', ')}\n`;
}
response += `\n`;
}
if (sysInfo.cpu) {
const cpu = sysInfo.cpu;
response += `💻 **CPU Information**\n`;
response += `- Model: ${cpu.model || cpu.brand || 'Unknown'}\n`;
if (cpu.manufacturer) response += `- Manufacturer: ${cpu.manufacturer}\n`;
response += `- Cores: ${cpu.cores || 'Unknown'}\n`;
if (cpu.physicalCores) response += `- Physical Cores: ${cpu.physicalCores}\n`;
if (cpu.speed) response += `- Base Speed: ${cpu.speed} MHz\n`;
if (cpu.speedMax) response += `- Max Speed: ${cpu.speedMax} MHz\n`;
if (cpu.load) {
if (cpu.load.currentLoad !== undefined) response += `- Current Load: ${cpu.load.currentLoad.toFixed(2)}%\n`;
if (cpu.load.currentLoadUser !== undefined) response += `- User Load: ${cpu.load.currentLoadUser.toFixed(2)}%\n`;
if (cpu.load.currentLoadSystem !== undefined) response += `- System Load: ${cpu.load.currentLoadSystem.toFixed(2)}%\n`;
}
if (cpu.temperature && cpu.temperature.main) {
response += `- Temperature: ${cpu.temperature.main}°C\n`;
}
if (cpu.loadAvg && Array.isArray(cpu.loadAvg)) {
response += `- Load Average: ${cpu.loadAvg.map(load => load.toFixed(2)).join(', ')}\n`;
}
response += `\n`;
}
if (sysInfo.memory) {
const memory = sysInfo.memory;
response += `🧠 **Memory Information**\n`;
response += `- Total: ${memory.total || 'Unknown'}\n`;
response += `- Used: ${memory.used || 'Unknown'} (${memory.usagePercent || 'Unknown'})\n`;
response += `- Free: ${memory.free || 'Unknown'}\n`;
if (memory.available) response += `- Available: ${memory.available}\n`;
if (memory.active) response += `- Active: ${memory.active}\n`;
if (memory.swap) {
response += `- Swap Total: ${memory.swap.total || 'Unknown'}\n`;
response += `- Swap Used: ${memory.swap.used || 'Unknown'} (${memory.swap.usagePercent || 'Unknown'})\n`;
response += `- Swap Free: ${memory.swap.free || 'Unknown'}\n`;
}
if (memory.layout && Array.isArray(memory.layout) && memory.layout.length > 0) {
response += `- Memory Modules: ${memory.layout.length} installed\n`;
memory.layout.forEach((module, index) => {
if (module.size) {
response += ` - Module ${index + 1}: ${module.size}`;
if (module.type) response += ` ${module.type}`;
if (module.clockSpeed) response += ` @ ${module.clockSpeed} MHz`;
response += `\n`;
}
});
}
response += `\n`;
}
if (sysInfo.disk) {
response += `💾 **Disk Information**\n`;
if (sysInfo.disk.fsSize && Array.isArray(sysInfo.disk.fsSize)) {
response += `- File Systems:\n`;
sysInfo.disk.fsSize.forEach(fs => {
response += ` - ${fs.fs} (${fs.type || 'Unknown'}):\n`;
response += ` - Mount: ${fs.mount || 'Unknown'}\n`;
response += ` - Size: ${fs.size || 'Unknown'}\n`;
response += ` - Used: ${fs.used || 'Unknown'} (${fs.usagePercent || 'Unknown'})\n`;
response += ` - Available: ${fs.available || 'Unknown'}\n`;
});
} else if (Array.isArray(sysInfo.disk)) {
// Legacy Windows format
sysInfo.disk.forEach(disk => {
response += `- Drive ${disk.drive}:\n`;
response += ` - Size: ${disk.size}\n`;
response += ` - Used: ${disk.used} (${disk.usagePercent})\n`;
response += ` - Free: ${disk.free}\n`;
});
} else if (sysInfo.disk.filesystem) {
// Legacy Unix format
response += `- Filesystem: ${sysInfo.disk.filesystem}\n`;
response += `- Size: ${sysInfo.disk.size}\n`;
response += `- Used: ${sysInfo.disk.used} (${sysInfo.disk.usagePercent})\n`;
response += `- Available: ${sysInfo.disk.available}\n`;
response += `- Mounted on: ${sysInfo.disk.mountedOn}\n`;
} else if (sysInfo.disk.error) {
response += `- Error retrieving disk information: ${sysInfo.disk.error}\n`;
}
if (sysInfo.disk.diskLayout && Array.isArray(sysInfo.disk.diskLayout)) {
response += `- Physical Disks: ${sysInfo.disk.diskLayout.length} detected\n`;
sysInfo.disk.diskLayout.forEach((disk, index) => {
response += ` - Disk ${index + 1}: ${disk.name || disk.device}\n`;
if (disk.size) response += ` - Size: ${disk.size}\n`;
if (disk.type) response += ` - Type: ${disk.type}\n`;
if (disk.vendor) response += ` - Vendor: ${disk.vendor}\n`;
});
}
response += `\n`;
}
if (sysInfo.network) {
response += `🌐 **Network Information**\n`;
if (sysInfo.network.publicIp && sysInfo.network.publicIp !== 'Not available') {
response += `- Public IP: ${sysInfo.network.publicIp}\n`;
}
if (sysInfo.network.interfaces && Array.isArray(sysInfo.network.interfaces)) {
const activeInterfaces = sysInfo.network.interfaces.filter(iface => !iface.internal);
if (activeInterfaces.length > 0) {
response += `- Network Interfaces:\n`;
activeInterfaces.forEach(iface => {
response += ` - ${iface.interface || iface.ifaceName}:\n`;
if (iface.ip4) response += ` - IPv4: ${iface.ip4}\n`;
if (iface.ip6) response += ` - IPv6: ${iface.ip6}\n`;
if (iface.mac) response += ` - MAC: ${iface.mac}\n`;
if (iface.speed && iface.speed !== 'N/A') response += ` - Speed: ${iface.speed}\n`;
if (iface.operstate) response += ` - State: ${iface.operstate}\n`;
});
}
} else if (Array.isArray(sysInfo.network)) {
// Legacy format
const externalInterfaces = sysInfo.network.filter(net => !net.internal);
if (externalInterfaces.length > 0) {
response += `- Network Interfaces:\n`;
externalInterfaces.forEach(net => {
response += ` - ${net.interface}: ${net.address}\n`;
response += ` - Netmask: ${net.netmask}\n`;
response += ` - MAC: ${net.mac}\n`;
});
}
}
if (sysInfo.network.internetLatency && sysInfo.network.internetLatency !== 'N/A ms') {
response += `- Internet Connectivity: ${sysInfo.network.internetLatency}\n`;
}
if (sysInfo.network.connections && typeof sysInfo.network.connections === 'number') {
response += `- Active Connections: ${sysInfo.network.connections}\n`;
}
response += `\n`;
}
if (sysInfo.process) {
response += `⚙️ **Process Information**\n`;
if (sysInfo.process.currentProcess) {
const current = sysInfo.process.currentProcess;
response += `- Current Process:\n`;
response += ` - PID: ${current.pid || 'Unknown'}\n`;
if (current.name) response += ` - Name: ${current.name}\n`;
if (current.cpu) response += ` - CPU Usage: ${current.cpu}\n`;
if (current.mem) response += ` - Memory Usage: ${current.mem}\n`;
if (current.uptime) response += ` - Uptime: ${Math.floor(current.uptime / 60)} minutes\n`;
} else {
// Legacy format
response += `- Process ID: ${sysInfo.process.pid || 'Unknown'}\n`;
if (sysInfo.process.version) response += `- Node.js Version: ${sysInfo.process.version}\n`;
if (sysInfo.process.cwd) response += `- Working Directory: ${sysInfo.process.cwd}\n`;
if (sysInfo.process.memoryUsage && sysInfo.process.memoryUsage.rss) {
response += `- Memory Usage: ${Math.round(sysInfo.process.memoryUsage.rss / (1024 * 1024))} MB\n`;
}
}
if (sysInfo.process.summary) {
const summary = sysInfo.process.summary;
response += `- Process Summary:\n`;
if (summary.all) response += ` - Total: ${summary.all}\n`;
if (summary.running) response += ` - Running: ${summary.running}\n`;
if (summary.sleeping) response += ` - Sleeping: ${summary.sleeping}\n`;
if (summary.blocked) response += ` - Blocked: ${summary.blocked}\n`;
}
if (sysInfo.process.topProcesses && Array.isArray(sysInfo.process.topProcesses) && sysInfo.process.topProcesses.length > 0) {
response += `- Top Processes (by CPU):\n`;
sysInfo.process.topProcesses.slice(0, 5).forEach((proc, index) => {
response += ` - ${index + 1}: ${proc.name} (PID: ${proc.pid}) - CPU: ${proc.cpu}, Memory: ${proc.mem}\n`;
});
}
response += `\n`;
}
if (sysInfo.environment) {
response += `🔧 **Environment Information**\n`;
if (sysInfo.environment.variables) {
const envVars = sysInfo.environment.variables;
response += `- Key Environment Variables:\n`;
const importantVars = ['PATH', 'HOME', 'USER', 'SHELL', 'LANG', 'TERM'];
importantVars.forEach(varName => {
if (envVars[varName]) {
response += ` - ${varName}: ${envVars[varName]}\n`;
}
});
const otherVars = Object.keys(envVars).filter(key => !importantVars.includes(key));
if (otherVars.length > 0) {
response += ` - Other variables: ${otherVars.length} additional environment variables\n`;
}
}
if (sysInfo.environment.users && Array.isArray(sysInfo.environment.users) && sysInfo.environment.users.length > 0) {
response += `- Active Users: ${sysInfo.environment.users.length}\n`;
}
response += `\n`;
}
response;
return response;
}
/**
* Get help message when no system info is available
* @param {string} prompt - The original prompt
* @returns {string} Help message
*/
function getHelpMessage(prompt) {
return `I couldn't find specific system information for your query: "${prompt}"\n\n` +
`*Available system information queries:*\n\n` +
`📱 **Basic System Info:**\n` +
`- "What's my system info?" - Platform, OS, architecture\n` +
`- "System overview" - Complete basic information\n\n` +
`💻 **CPU Information:**\n` +
`- "What's my CPU usage?" - Processor load and performance\n` +
`- "Show me processor info" - CPU specifications\n\n` +
`🧠 **Memory Information:**\n` +
`- "How much RAM do I have?" - Memory specifications\n` +
`- "Memory usage" - Current memory utilization\n\n` +
`💾 **Disk Information:**\n` +
`- "How much disk space?" - Storage capacity and usage\n` +
`- "Storage info" - Disk and filesystem details\n\n` +
`🌐 **Network Information:**\n` +
`- "What's my IP address?" - Network interface details\n` +
`- "Network status" - Connection and interface info\n\n` +
`⚙️ **Process Information:**\n` +
`- "What processes are running?" - Active processes and services\n` +
`- "Process info" - System process details\n\n` +
`🔧 **Environment Variables:**\n` +
`- "Show environment variables" - System configuration\n` +
`- "User info" - User and shell information\n\n` +
`📊 **Complete Information:**\n` +
`- "Show me all system information" - Everything available\n` +
`- "Complete system report" - Comprehensive overview\n\n` +
`*System information as of 2025-07-09 10:45:40 UTC*\n` +
`*User: m0v0dga_walmart*`;
}
async function processWithAI(prompt, context = '', mode = 2) {
try {
// Enhanced system query detection - but EXCLUDE file/folder analysis prompts
const systemKeywords = [
'system', 'cpu', 'memory', 'ram', 'disk', 'network', 'ip', 'process',
'environment', 'hardware', 'computer', 'machine', 'specs', 'info',
'information', 'status', 'usage', 'performance', 'storage', 'processor'
];
// Check if this is a file/folder analysis (these should NOT trigger system info)
const isFileAnalysis = prompt.includes('File:') ||
prompt.includes('Analyze this') ||
prompt.includes('code file') ||
prompt.includes('Content:') ||
prompt.includes('User Question:');
const isSystemQuery = !isFileAnalysis && (
systemKeywords.some(keyword => prompt.toLowerCase().includes(keyword)) ||
prompt.toLowerCase().startsWith('get system information') ||
prompt.toLowerCase().includes('/system')
);
if (isSystemQuery) {
try {
// First get basic system info to provide context
const basicInfo = await getSystemInfo('basic');
// Use AI to determine what system information is being requested
const aiResponse = await determineSystemInfoQuery(prompt, basicInfo);
// Get the specific system information based on AI's determination
const systemInfo = await getSystemInfo(aiResponse.query);
// Format the response using AI
const formattedResponse = await formatSystemInfoResponse(systemInfo, prompt);
return formattedResponse;
} catch (sysError) {
console.error(`[${new Date().toISOString()}] ❌ System info error:`, sysError.message);
// If system info fails, fall back to AI processing
return `I encountered an error retrieving system information: ${sysError.message}\n\nPlease try a more specific query or check the system status.`;
}
}
// Regular AI processing for non-system queries
const selectedMode = getMode(mode); // Use selected mode
try {
const response = await fetch('https://traceai.dukeindustries7.workers.dev/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: encryptData({
a: selectedMode,
q: prompt,
i: [],
c: context
})
});
const text = await response.text();
const result = decryptData(text);
// The worker now handles orchestration internally
// It runs multiple models and synthesizes the response
if (result && result.text && typeof result.text === 'string') {
return result.text;
} else {
return 'I apologize, but I was unable to process your request at this time. Please try again.';
}
} catch (error) {
return 'I apologize, but I was unable to process your request at this time. Please try again.';
}
} catch (error) {
console.error(`[${new Date().toISOString()}] ❌ Processing error:`, error.message);
throw error;
}
}
module.exports = {
processWithAI,
determineSystemInfoQuery,
formatSystemInfoResponse
};