import logger from '../utils/logger.js'; import fs from 'fs/promises'; import path from 'path'; class SelfUpdater { constructor(config, memory) { this.config = config; this.memory = memory; this._version = '3.0.0'; this._lastCheck = 0; this._checkInterval = 24 * 60 * 60 * 1000; this._stateFile = 'data/updater-state.json'; } async initialize() { try { const state = await this._loadState(); if (state) { this._lastCheck = state.lastCheck || 0; this._version = state.version || this._version; } } catch (error) { logger.warn(`Could not load updater state: ${error.message}`); } } async checkForUpdates() { const now = Date.now(); if (now - this._lastCheck < this._checkInterval) { return { hasUpdate: false, reason: 'Too soon since last check' }; } try { this._lastCheck = now; await this._saveState(); logger.info(`Self-update check completed. Current version: ${this._version}`); return { hasUpdate: false, currentVersion: this._version }; } catch (error) { logger.error(`Update check failed: ${error.message}`); return { hasUpdate: false, error: error.message }; } } async adaptBehavior(metrics) { if (!metrics) return; const adjustments = []; if (metrics.errorRate > 0.3) { adjustments.push('high-error-rate'); logger.warn('High error rate detected, reducing activity'); } if (metrics.successRate > 0.9) { adjustments.push('high-success'); logger.info('High success rate, can increase activity'); } if (metrics.avgResponseTime > 5000) { adjustments.push('slow-response'); logger.warn('Slow response times detected'); } if (adjustments.length > 0) { this.memory.remember('behavior-adjustments', { adjustments, timestamp: Date.now(), metrics, }); } return adjustments; } async cleanup(maxAge = 30 * 24 * 60 * 60 * 1000) { try { const state = await this._loadState(); if (state && state.lastCheck < Date.now() - maxAge) { logger.info('Updater state is stale, resetting'); await this._saveState(); } } catch (error) { logger.error(`Cleanup failed: ${error.message}`); } } async _loadState() { try { const content = await fs.readFile(this._stateFile, 'utf8'); return JSON.parse(content); } catch (error) { if (error.code === 'ENOENT') { return null; } throw error; } } async _saveState() { try { const dir = path.dirname(this._stateFile); await fs.mkdir(dir, { recursive: true }); await fs.writeFile(this._stateFile, JSON.stringify({ version: this._version, lastCheck: this._lastCheck, lastUpdated: new Date().toISOString(), }, null, 2), 'utf8'); } catch (error) { logger.error(`Failed to save updater state: ${error.message}`); } } getVersion() { return this._version; } } export default SelfUpdater;