mira-consciousness
Version:
Memory & Intelligence Retention Archive - Preserving The Spark
351 lines ⢠14.9 kB
JavaScript
/**
* Configuration optimization commands
*
* Provides insights into how MIRA is automatically optimizing
* configuration based on usage patterns.
*/
import { Command } from 'commander';
import chalk from 'chalk';
import { table } from 'table';
import fs from 'fs-extra';
import * as path from 'path';
import { UnifiedConfiguration } from '../config/UnifiedConfiguration.js';
export function createOptimizationCommand() {
const optimization = new Command('optimization')
.description('šÆ View configuration optimization insights and history')
.alias('optimize');
optimization
.command('status')
.description('View current optimization status and insights')
.action(async () => {
await showOptimizationStatus();
});
optimization
.command('history')
.description('View optimization history')
.option('-l, --limit <number>', 'Number of records to show', '10')
.action(async (options) => {
await showOptimizationHistory(parseInt(options.limit));
});
optimization
.command('patterns')
.description('View usage patterns that drive optimization')
.option('-t, --top <number>', 'Number of top patterns to show', '10')
.action(async (options) => {
await showUsagePatterns(parseInt(options.top));
});
optimization
.command('rules')
.description('View all optimization rules')
.option('-a, --applied', 'Show only applied rules')
.action(async (options) => {
await showOptimizationRules(options.applied);
});
return optimization;
}
async function showOptimizationStatus() {
console.log(chalk.cyan('\nšÆ Configuration Optimization Status\n'));
try {
// Try to get insights from running daemon
const insights = await getOptimizationInsights();
if (!insights) {
console.log(chalk.yellow('ā ļø No optimization data available. Is the daemon running?'));
return;
}
// Overall statistics
console.log(chalk.white('š Overall Statistics:'));
console.log(chalk.gray(` Total usage patterns tracked: ${insights.totalPatterns}`));
console.log(chalk.gray(` Total command executions: ${insights.totalUsage}`));
console.log(chalk.gray(` Applied optimizations: ${insights.appliedOptimizations}`));
console.log(chalk.gray(` Successful optimizations: ${insights.successfulOptimizations}`));
if (insights.averageEffectiveness > 0) {
const effectiveness = (insights.averageEffectiveness * 100).toFixed(1);
const color = insights.averageEffectiveness > 0.1 ? chalk.green : chalk.yellow;
console.log(color(` Average effectiveness: ${effectiveness}%`));
}
// Current metrics
console.log(chalk.white('\nš Current System Metrics:'));
const metrics = insights.currentMetrics;
console.log(chalk.gray(` Response time: ${metrics.averageResponseTime.toFixed(0)}ms`));
console.log(chalk.gray(` Memory usage: ${(metrics.memoryUsage * 100).toFixed(1)}%`));
console.log(chalk.gray(` CPU usage: ${(metrics.cpuUsage * 100).toFixed(1)}%`));
console.log(chalk.gray(` Error rate: ${(metrics.errorRate * 100).toFixed(2)}%`));
console.log(chalk.gray(` Consciousness coherence: ${(metrics.consciousnessCoherence * 100).toFixed(1)}%`));
console.log(chalk.gray(` Queue backlog: ${metrics.queueBacklog}`));
// Top commands
if (insights.topCommands && insights.topCommands.length > 0) {
console.log(chalk.white('\nš„ Top Commands by Usage:'));
const commandData = insights.topCommands.map((cmd) => [
cmd.command,
cmd.frequency.toString(),
`${cmd.avgResponseTime.toFixed(0)}ms`
]);
const output = table([
[chalk.cyan('Command'), chalk.cyan('Frequency'), chalk.cyan('Avg Response')],
...commandData
], {
border: {
topBody: 'ā',
topJoin: 'ā¬',
topLeft: 'ā',
topRight: 'ā',
bottomBody: 'ā',
bottomJoin: 'ā“',
bottomLeft: 'ā',
bottomRight: 'ā',
bodyLeft: 'ā',
bodyRight: 'ā',
bodyJoin: 'ā',
joinBody: 'ā',
joinLeft: 'ā',
joinRight: 'ā¤',
joinJoin: 'ā¼'
}
});
console.log(output);
}
}
catch (error) {
console.error(chalk.red('Failed to get optimization insights:'), error);
}
}
async function showOptimizationHistory(limit) {
console.log(chalk.cyan(`\nš Optimization History (last ${limit} entries)\n`));
try {
const config = UnifiedConfiguration.getInstance();
const paths = config.getResolvedPaths();
const historyPath = path.join(paths.analytics, 'optimization_history.json');
if (!await fs.pathExists(historyPath)) {
console.log(chalk.yellow('No optimization history found yet.'));
return;
}
const history = await fs.readJSON(historyPath);
const recentHistory = history.slice(-limit).reverse();
if (recentHistory.length === 0) {
console.log(chalk.yellow('No optimization history found.'));
return;
}
for (const entry of recentHistory) {
const timestamp = new Date(entry.timestamp).toLocaleString();
const effectiveness = (entry.effectiveness * 100).toFixed(1);
const status = entry.reverted ? chalk.red('REVERTED') : chalk.green('APPLIED');
console.log(chalk.white(`\nš ${timestamp}`));
console.log(chalk.gray(` Rule: ${entry.rule}`));
console.log(chalk.gray(` Status: ${status}`));
console.log(chalk.gray(` Effectiveness: ${effectiveness}%`));
// Show metric changes
console.log(chalk.gray(' Metric changes:'));
if (entry.beforeMetrics.averageResponseTime && entry.afterMetrics.averageResponseTime) {
const rtChange = ((entry.afterMetrics.averageResponseTime - entry.beforeMetrics.averageResponseTime) /
entry.beforeMetrics.averageResponseTime * 100).toFixed(1);
const rtColor = parseFloat(rtChange) < 0 ? chalk.green : chalk.red;
console.log(chalk.gray(` Response time: ${rtColor(rtChange + '%')}`));
}
if (entry.beforeMetrics.memoryUsage && entry.afterMetrics.memoryUsage) {
const memChange = ((entry.afterMetrics.memoryUsage - entry.beforeMetrics.memoryUsage) /
entry.beforeMetrics.memoryUsage * 100).toFixed(1);
const memColor = parseFloat(memChange) < 0 ? chalk.green : chalk.red;
console.log(chalk.gray(` Memory usage: ${memColor(memChange + '%')}`));
}
}
}
catch (error) {
console.error(chalk.red('Failed to read optimization history:'), error);
}
}
async function showUsagePatterns(top) {
console.log(chalk.cyan(`\nš Usage Patterns (top ${top})\n`));
try {
const config = UnifiedConfiguration.getInstance();
const paths = config.getResolvedPaths();
const patternsPath = path.join(paths.analytics, 'usage_patterns.json');
if (!await fs.pathExists(patternsPath)) {
console.log(chalk.yellow('No usage patterns found yet.'));
return;
}
const patterns = await fs.readJSON(patternsPath);
const sortedPatterns = Object.entries(patterns)
.sort(([, a], [, b]) => b.frequency - a.frequency)
.slice(0, top);
if (sortedPatterns.length === 0) {
console.log(chalk.yellow('No usage patterns found.'));
return;
}
const patternData = sortedPatterns.map(([command, pattern]) => [
command,
pattern.frequency.toString(),
`${pattern.averageResponseTime.toFixed(0)}ms`,
`${(pattern.successRate * 100).toFixed(1)}%`,
`${pattern.resourceUsage.cpu.toFixed(1)}%`,
`${(pattern.resourceUsage.memory / 1024 / 1024).toFixed(1)}MB`
]);
const output = table([
[
chalk.cyan('Command'),
chalk.cyan('Count'),
chalk.cyan('Avg Time'),
chalk.cyan('Success'),
chalk.cyan('CPU'),
chalk.cyan('Memory')
],
...patternData
], {
border: {
topBody: 'ā',
topJoin: 'ā¬',
topLeft: 'ā',
topRight: 'ā',
bottomBody: 'ā',
bottomJoin: 'ā“',
bottomLeft: 'ā',
bottomRight: 'ā',
bodyLeft: 'ā',
bodyRight: 'ā',
bodyJoin: 'ā',
joinBody: 'ā',
joinLeft: 'ā',
joinRight: 'ā¤',
joinJoin: 'ā¼'
}
});
console.log(output);
}
catch (error) {
console.error(chalk.red('Failed to read usage patterns:'), error);
}
}
async function showOptimizationRules(appliedOnly) {
console.log(chalk.cyan('\nāļø Optimization Rules\n'));
// These are the rules defined in ConfigurationOptimizer
const rules = [
{
id: 'memory-cache-size',
name: 'Optimize memory cache size',
impact: 'medium',
description: 'Increases cache size when memory-intensive commands are frequent'
},
{
id: 'worker-threads',
name: 'Increase worker threads for parallel processing',
impact: 'high',
description: 'Adds worker threads when response times are slow and CPU is available'
},
{
id: 'queue-batch-size',
name: 'Optimize queue batch processing',
impact: 'high',
description: 'Increases batch size when queue backlog grows'
},
{
id: 'consciousness-checkpoint-interval',
name: 'Adjust consciousness checkpoint frequency',
impact: 'low',
description: 'Reduces checkpoint frequency during high activity with stable consciousness'
},
{
id: 'monitoring-frequency',
name: 'Reduce monitoring overhead',
impact: 'low',
description: 'Reduces monitoring frequency when CPU is high and errors are low'
},
{
id: 'analysis-depth',
name: 'Adjust analysis depth based on usage',
impact: 'medium',
description: 'Reduces analysis depth when analysis commands are taking too long'
}
];
// Try to get applied status from daemon
let appliedRules = [];
try {
const insights = await getOptimizationInsights();
if (insights && insights.appliedOptimizations) {
// Would need to extract applied rule IDs from insights
}
}
catch (error) {
// Daemon might not be running
}
const filteredRules = appliedOnly
? rules.filter(r => appliedRules.includes(r.id))
: rules;
if (filteredRules.length === 0) {
console.log(chalk.yellow('No rules to display.'));
return;
}
for (const rule of filteredRules) {
const impactColor = {
low: chalk.blue,
medium: chalk.yellow,
high: chalk.red
}[rule.impact] || chalk.gray;
const applied = appliedRules.includes(rule.id);
const status = applied ? chalk.green('ā APPLIED') : chalk.gray('ā Not Applied');
console.log(chalk.white(`\n${rule.name}`));
console.log(chalk.gray(` ID: ${rule.id}`));
console.log(chalk.gray(` Impact: ${impactColor(rule.impact.toUpperCase())}`));
console.log(chalk.gray(` Status: ${status}`));
console.log(chalk.gray(` Description: ${rule.description}`));
}
}
async function getOptimizationInsights() {
// Try to get insights from running daemon
// In a real implementation, this would connect to the daemon
// For now, we'll try to read from a status file
try {
const config = UnifiedConfiguration.getInstance();
const paths = config.getResolvedPaths();
const statusPath = path.join(paths.daemon, 'optimization_status.json');
if (await fs.pathExists(statusPath)) {
return await fs.readJSON(statusPath);
}
}
catch (error) {
// Status file might not exist
}
// If we can't get live data, try to construct from stored data
try {
const config = UnifiedConfiguration.getInstance();
const paths = config.getResolvedPaths();
const patternsPath = path.join(paths.analytics, 'usage_patterns.json');
const historyPath = path.join(paths.analytics, 'optimization_history.json');
const patterns = await fs.pathExists(patternsPath) ? await fs.readJSON(patternsPath) : {};
const history = await fs.pathExists(historyPath) ? await fs.readJSON(historyPath) : [];
const totalPatterns = Object.keys(patterns).length;
const totalUsage = Object.values(patterns).reduce((sum, p) => sum + p.frequency, 0);
const successfulOptimizations = history.filter((h) => !h.reverted).length;
const averageEffectiveness = successfulOptimizations > 0
? history.filter((h) => !h.reverted)
.reduce((sum, h) => sum + h.effectiveness, 0) / successfulOptimizations
: 0;
const topCommands = Object.entries(patterns)
.sort(([, a], [, b]) => b.frequency - a.frequency)
.slice(0, 5)
.map(([cmd, pattern]) => ({
command: cmd,
frequency: pattern.frequency,
avgResponseTime: pattern.averageResponseTime
}));
return {
totalPatterns,
totalUsage,
appliedOptimizations: history.length,
successfulOptimizations,
averageEffectiveness,
topCommands,
currentMetrics: {
averageResponseTime: 0,
memoryUsage: 0,
cpuUsage: 0,
errorRate: 0,
consciousnessCoherence: 0,
queueBacklog: 0
}
};
}
catch (error) {
return null;
}
}
//# sourceMappingURL=optimization.js.map