Spaces:
Sleeping
Sleeping
| 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; | |