@bestdefense/bd-agent
Version:
An AI-powered coding assistant CLI that connects to AWS Bedrock
157 lines (154 loc) • 5.31 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryManager = void 0;
const chalk_1 = __importDefault(require("chalk"));
class MemoryManager {
bedrockClient;
config = {
maxMessages: 50,
maxTokensPerMessage: 4000,
summaryThreshold: 30
};
summaries = [];
messageCount = 0;
constructor(bedrockClient) {
this.bedrockClient = bedrockClient;
}
/**
* Process messages and return optimized conversation history
*/
async processMessages(messages) {
this.messageCount = messages.length;
// If conversation is short, return as-is
if (messages.length <= this.config.summaryThreshold) {
return messages;
}
// All messages are conversation messages (no system messages in BedrockMessage)
const conversationMessages = messages;
// Calculate how many messages to keep in full
const recentMessagesToKeep = Math.floor(this.config.maxMessages / 2);
const oldMessages = conversationMessages.slice(0, -recentMessagesToKeep);
const recentMessages = conversationMessages.slice(-recentMessagesToKeep);
// Summarize old messages if we have a bedrock client
if (this.bedrockClient && oldMessages.length > 0) {
const summary = await this.summarizeMessages(oldMessages);
if (summary) {
this.summaries.push(summary);
}
}
// Build optimized message list
const optimizedMessages = [];
// Add summary as conversation context if we have summaries
if (this.summaries.length > 0) {
optimizedMessages.push({
role: 'user',
content: `Previous conversation summary:\n${this.summaries.join('\n\n')}\n\n[End of summary]`
});
optimizedMessages.push({
role: 'assistant',
content: 'I understand the context from our previous conversation. Let me continue helping you.'
});
}
// Add recent messages
optimizedMessages.push(...recentMessages);
return optimizedMessages;
}
/**
* Summarize a set of messages
*/
async summarizeMessages(messages) {
if (!this.bedrockClient)
return null;
try {
const summaryPrompt = this.createSummaryPrompt(messages);
const summaryMessages = [
{
role: 'user',
content: summaryPrompt
}
];
let summary = '';
// Pass a minimal tool to satisfy AWS Bedrock requirements
const minimalTools = [{
name: 'placeholder',
description: 'Placeholder tool to satisfy API requirements',
input_schema: {
type: 'object',
properties: {},
required: []
}
}];
const stream = this.bedrockClient.streamMessage(summaryMessages, minimalTools, 'You are a helpful assistant that creates concise summaries.');
for await (const chunk of stream) {
if (typeof chunk === 'string') {
summary += chunk;
}
}
return summary.trim();
}
catch (error) {
console.error(chalk_1.default.yellow('Warning: Failed to create summary'), error);
return null;
}
}
/**
* Create a prompt for summarizing messages
*/
createSummaryPrompt(messages) {
const conversationText = messages
.map(msg => `${msg.role.toUpperCase()}: ${this.extractTextContent(msg.content)}`)
.join('\n\n');
return `Please create a concise summary of the following conversation, focusing on:
1. The main topics discussed
2. Any decisions made or conclusions reached
3. Important context that should be remembered
4. Any ongoing tasks or unresolved issues
Keep the summary brief but comprehensive.
Conversation:
${conversationText}
Summary:`;
}
/**
* Extract text content from message content (handles both string and array formats)
*/
extractTextContent(content) {
if (typeof content === 'string') {
return content;
}
if (Array.isArray(content)) {
return content
.filter(block => block.text)
.map(block => block.text)
.join(' ');
}
return '';
}
/**
* Get memory statistics
*/
getStats() {
return {
totalMessages: this.messageCount,
summaryCount: this.summaries.length,
config: this.config
};
}
/**
* Clear memory
*/
clear() {
this.summaries = [];
this.messageCount = 0;
}
/**
* Update configuration
*/
updateConfig(config) {
this.config = { ...this.config, ...config };
}
}
exports.MemoryManager = MemoryManager;
//# sourceMappingURL=memory-manager.js.map