Claude hooks auto-backup: manual (backup_20250720_091250)
This commit is contained in:
parent
9445e09c48
commit
392833187e
135 changed files with 16151 additions and 3439 deletions
156
lib/context-monitor.js
Normal file
156
lib/context-monitor.js
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
* Context Monitor - Estimates context usage and triggers backups
|
||||
*/
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
class ContextMonitor {
|
||||
constructor() {
|
||||
this.estimatedTokens = 0;
|
||||
this.promptCount = 0;
|
||||
this.toolExecutions = 0;
|
||||
this.sessionStartTime = Date.now();
|
||||
|
||||
// Configuration
|
||||
this.maxContextTokens = 200000; // Conservative estimate
|
||||
this.backupThreshold = 0.85; // 85% of max context
|
||||
this.timeThresholdMinutes = 30; // 30 minutes
|
||||
this.toolThreshold = 25; // 25 tool executions
|
||||
|
||||
this.lastBackupTime = Date.now();
|
||||
this.lastBackupToolCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update context estimates from user prompt
|
||||
*/
|
||||
updateFromPrompt(promptData) {
|
||||
this.promptCount++;
|
||||
|
||||
// Estimate tokens from prompt
|
||||
const prompt = promptData.prompt || '';
|
||||
const estimatedPromptTokens = this._estimateTokens(prompt);
|
||||
|
||||
this.estimatedTokens += estimatedPromptTokens;
|
||||
|
||||
// Add context size if provided
|
||||
if (promptData.context_size) {
|
||||
this.estimatedTokens += promptData.context_size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update context estimates from tool usage
|
||||
*/
|
||||
updateFromToolUse(toolData) {
|
||||
this.toolExecutions++;
|
||||
|
||||
// Estimate tokens from tool parameters and output
|
||||
const parameters = JSON.stringify(toolData.parameters || {});
|
||||
const output = toolData.output || '';
|
||||
const error = toolData.error || '';
|
||||
|
||||
const toolTokens = this._estimateTokens(parameters + output + error);
|
||||
this.estimatedTokens += toolTokens;
|
||||
|
||||
// File operations add more context
|
||||
if (toolData.tool === 'Read' || toolData.tool === 'Edit') {
|
||||
this.estimatedTokens += 2000; // Typical file size estimate
|
||||
} else if (toolData.tool === 'Bash') {
|
||||
this.estimatedTokens += 500; // Command output estimate
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if backup should be triggered
|
||||
*/
|
||||
checkBackupTriggers(hookType, data) {
|
||||
const decisions = [];
|
||||
|
||||
// Context threshold trigger
|
||||
const contextRatio = this.getContextUsageRatio();
|
||||
if (contextRatio > this.backupThreshold) {
|
||||
decisions.push({
|
||||
shouldBackup: true,
|
||||
reason: `Context usage ${(contextRatio * 100).toFixed(1)}%`,
|
||||
urgency: 'high'
|
||||
});
|
||||
}
|
||||
|
||||
// Time-based trigger
|
||||
const sessionMinutes = (Date.now() - this.sessionStartTime) / (1000 * 60);
|
||||
const timeSinceBackup = (Date.now() - this.lastBackupTime) / (1000 * 60);
|
||||
|
||||
if (timeSinceBackup > this.timeThresholdMinutes) {
|
||||
decisions.push({
|
||||
shouldBackup: true,
|
||||
reason: `${this.timeThresholdMinutes} minutes since last backup`,
|
||||
urgency: 'medium'
|
||||
});
|
||||
}
|
||||
|
||||
// Tool-based trigger
|
||||
const toolsSinceBackup = this.toolExecutions - this.lastBackupToolCount;
|
||||
if (toolsSinceBackup >= this.toolThreshold) {
|
||||
decisions.push({
|
||||
shouldBackup: true,
|
||||
reason: `${this.toolThreshold} tools since last backup`,
|
||||
urgency: 'medium'
|
||||
});
|
||||
}
|
||||
|
||||
// Return highest priority decision
|
||||
if (decisions.length > 0) {
|
||||
const urgencyOrder = { high: 3, medium: 2, low: 1 };
|
||||
decisions.sort((a, b) => urgencyOrder[b.urgency] - urgencyOrder[a.urgency]);
|
||||
return decisions[0];
|
||||
}
|
||||
|
||||
return { shouldBackup: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current context usage ratio (0.0 to 1.0)
|
||||
*/
|
||||
getContextUsageRatio() {
|
||||
return Math.min(1.0, this.estimatedTokens / this.maxContextTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark that a backup was performed
|
||||
*/
|
||||
markBackupPerformed() {
|
||||
this.lastBackupTime = Date.now();
|
||||
this.lastBackupToolCount = this.toolExecutions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate tokens from text (rough approximation)
|
||||
*/
|
||||
_estimateTokens(text) {
|
||||
if (!text) return 0;
|
||||
|
||||
// Rough estimate: ~4 characters per token for English text
|
||||
// Add some buffer for formatting and special tokens
|
||||
return Math.ceil(text.length / 3.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get context usage statistics
|
||||
*/
|
||||
getStats() {
|
||||
const sessionMinutes = (Date.now() - this.sessionStartTime) / (1000 * 60);
|
||||
|
||||
return {
|
||||
estimatedTokens: this.estimatedTokens,
|
||||
contextUsageRatio: this.getContextUsageRatio(),
|
||||
promptCount: this.promptCount,
|
||||
toolExecutions: this.toolExecutions,
|
||||
sessionMinutes: Math.round(sessionMinutes),
|
||||
lastBackupMinutesAgo: Math.round((Date.now() - this.lastBackupTime) / (1000 * 60))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { ContextMonitor };
|
||||
Loading…
Add table
Add a link
Reference in a new issue