// CONVERSATION CONTINUITY AGENT
// Monitors token usage and creates handoff documents for conversation continuity
// Ensures no critical data is lost between conversations
import { promises as fs } from 'fs';
import path from 'path';
import { actionLogger } from '../../logging/agent-action-logger.js';
import { configManager } from '../../config-manager.js';
export class ConversationContinuityAgent {
constructor() {
this.name = 'ConversationContinuityAgent';
this.role = 'Conversation monitoring and handoff documentation';
// Token thresholds
this.thresholds = {
warning: 150000, // 150k tokens - start preparing
critical: 180000 // 180k tokens - create handoff NOW
};
// Conversation tracking
this.currentConversation = {
startTime: new Date(),
estimatedTokens: 0,
keyDecisions: [],
codeCreated: [],
nextSteps: [],
criticalContext: [],
warnings: []
};
}
// Track conversation progress
trackProgress(data) {
const {
tokensUsed,
decision,
codeFile,
nextStep,
context,
warning
} = data;
// Update token count
if (tokensUsed) {
this.currentConversation.estimatedTokens = tokensUsed;
}
// Track decisions
if (decision) {
this.currentConversation.keyDecisions.push({
timestamp: new Date(),
decision: decision
});
}
// Track code created
if (codeFile) {
this.currentConversation.codeCreated.push({
timestamp: new Date(),
file: codeFile
});
}
// Track next steps
if (nextStep) {
this.currentConversation.nextSteps.push(nextStep);
}
// Track critical context
if (context) {
this.currentConversation.criticalContext.push({
timestamp: new Date(),
context: context
});
}
// Track warnings
if (warning) {
this.currentConversation.warnings.push({
timestamp: new Date(),
warning: warning
});
}
// Check if handoff needed
return this.checkHandoffNeeded();
}
// Check if handoff document needed
checkHandoffNeeded() {
const tokens = this.currentConversation.estimatedTokens;
if (tokens >= this.thresholds.critical) {
return {
needed: true,
urgency: 'CRITICAL',
message: '⚠️ TOKEN LIMIT APPROACHING - Creating handoff document NOW'
};
} else if (tokens >= this.thresholds.warning) {
return {
needed: false,
urgency: 'WARNING',
message: '⚠️ Approaching token limit - prepare for handoff soon'
};
}
return {
needed: false,
urgency: 'NORMAL',
message: 'Token usage normal'
};
}
// Create handoff document
async createHandoff(conversationSummary) {
console.log(`📝 ${this.name}: Creating handoff document...`);
const sessionId = await actionLogger.startSession(
this.name,
'Create conversation handoff document'
);
try {
const config = await configManager.initialize();
// Create handoff document
const handoff = {
metadata: {
createdAt: new Date().toISOString(),
conversationStart: this.currentConversation.startTime.toISOString(),
tokensUsed: this.currentConversation.estimatedTokens,
handoffReason: 'Token limit approaching'
},
// CRITICAL CONTEXT
criticalContext: [
...this.currentConversation.criticalContext,
{
context: conversationSummary || 'No summary provided',
timestamp: new Date()
}
],
// CURRENT STATE
currentState: {
project: 'MCP Agent System',
phase: 'Agent Development & Organization',
activeAgents: [
'Document Control Agent (doc-control.js)',
'Document Organizer Agent (doc-organizer.js)',
'Quality Agent (quality-agent.js)',
'Code Integrity Checker (code-integrity-checker.js)',
'Conversation Continuity Agent (conversation-continuity-agent.js)'
],
systemStatus: 'Building core agent infrastructure'
},
// KEY DECISIONS MADE
keyDecisions: this.currentConversation.keyDecisions,
// CODE FILES CREATED
filesCreated: this.currentConversation.codeCreated,
// IMMEDIATE NEXT STEPS
nextSteps: [
...this.currentConversation.nextSteps,
'Continue where we left off',
'No need to rebuild existing agents',
'Check handoff document for full context'
],
// WARNINGS & ISSUES
warnings: this.currentConversation.warnings,
// FILE LOCATIONS
fileLocations: {
root: 'C:\\MCP',
agents: 'C:\\MCP\\src\\agents\\core',
config: 'C:\\MCP\\config.json',
logs: 'C:\\MCP\\logs',
handoffs: 'C:\\MCP\\handoffs'
},
// QUICK REFERENCE
quickReference: {
existingAgents: [
'doc-control.js - Document version control',
'doc-organizer.js - File naming & filing',
'quality-agent.js - Code review & summaries',
'code-integrity-checker.js - Validates moves',
'conversation-continuity-agent.js - This agent'
],
existingTools: [
'agent-inventory-scanner.js - Scans for existing code',
'config-manager.js - Dynamic configuration',
'agent-action-logger.js - Logs all actions'
],
criticalFiles: [
'C:\\MCP\\config.json - All system configuration',
'C:\\MCP\\pre-init.js - Pre-initialization script',
'C:\\MCP\\run-pre-init.js - Script runner'
]
},
// TELEGRAM INTEGRATION STATUS
telegramStatus: {
botFile: 'C:\\Users\\bermi\\Agent-PA\\enhanced-telegram-bot.js',
status: 'Enhanced with N8N integration',
features: [
'Video production via /video command',
'Receipt processing via /receipt command',
'Natural language support',
'Agent system commands'
],
setupRequired: [
'Add TELEGRAM_BOT_TOKEN to .env',
'Start bot: node enhanced-telegram-bot.js',
'Test with /start command'
]
}
};
// Save handoff document
const handoffDir = path.join(config.paths.root, 'handoffs');
await fs.mkdir(handoffDir, { recursive: true });
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const handoffPath = path.join(handoffDir, `handoff-${timestamp}.json`);
await fs.writeFile(
handoffPath,
JSON.stringify(handoff, null, 2)
);
// Also create markdown version for easy reading
const mdPath = handoffPath.replace('.json', '.md');
await fs.writeFile(mdPath, this.formatMarkdown(handoff));
await actionLogger.endSession('completed');
console.log(`✅ ${this.name}: Handoff document created`);
console.log(` JSON: ${handoffPath}`);
console.log(` Markdown: ${mdPath}`);
return {
success: true,
handoffPath: handoffPath,
markdownPath: mdPath
};
} catch (error) {
await actionLogger.endSession('failed');
console.error(`❌ ${this.name}: Failed to create handoff:`, error);
throw error;
}
}
// Format handoff as markdown for easy reading
formatMarkdown(handoff) {
return `# 🔄 Conversation Handoff Document
**Created:** ${handoff.metadata.createdAt}
**Tokens Used:** ${handoff.metadata.tokensUsed}
**Reason:** ${handoff.metadata.handoffReason}
---
## 🎯 WHERE WE ARE NOW
**Project:** ${handoff.currentState.project}
**Phase:** ${handoff.currentState.phase}
**Status:** ${handoff.currentState.systemStatus}
### Active Agents
${handoff.currentState.activeAgents.map(a => `- ✅ ${a}`).join('\n')}
---
## 📋 IMMEDIATE NEXT STEPS
${handoff.nextSteps.map((step, i) => `${i + 1}. ${step}`).join('\n')}
---
## 🔑 CRITICAL CONTEXT
${handoff.criticalContext.map(c => `- ${c.context}`).join('\n')}
---
## 📁 FILES CREATED THIS SESSION
${handoff.filesCreated.length > 0
? handoff.filesCreated.map(f => `- ${f.file}`).join('\n')
: '- No files created yet'}
---
## ⚠️ WARNINGS & ISSUES
${handoff.warnings.length > 0
? handoff.warnings.map(w => `- ${w.warning}`).join('\n')
: '- No warnings'}
---
## 📍 FILE LOCATIONS
- **Root:** ${handoff.fileLocations.root}
- **Agents:** ${handoff.fileLocations.agents}
- **Config:** ${handoff.fileLocations.config}
- **Logs:** ${handoff.fileLocations.logs}
---
## 🚀 QUICK REFERENCE
### Existing Agents
${handoff.quickReference.existingAgents.map(a => `- ${a}`).join('\n')}
### Tools Available
${handoff.quickReference.existingTools.map(t => `- ${t}`).join('\n')}
### Critical Files
${handoff.quickReference.criticalFiles.map(f => `- ${f}`).join('\n')}
---
## 📱 TELEGRAM INTEGRATION
**Bot File:** ${handoff.telegramStatus.botFile}
**Status:** ${handoff.telegramStatus.status}
### Features
${handoff.telegramStatus.features.map(f => `- ${f}`).join('\n')}
### Setup Required
${handoff.telegramStatus.setupRequired.map(s => `- ${s}`).join('\n')}
---
## 💡 TO CONTINUE
1. Read this handoff document
2. Check what's already built (don't rebuild!)
3. Continue from "IMMEDIATE NEXT STEPS"
4. Use existing agents where possible
**Remember:** Agent delegation, not absorption! Let agents do the work.
`;
}
// Manual handoff trigger
async manualHandoff(summary) {
console.log(`🔄 ${this.name}: Manual handoff requested...`);
return await this.createHandoff(summary);
}
}
export const conversationContinuityAgent = new ConversationContinuityAgent();