@hashgraphonline/conversational-agent
Version:
Hashgraph Online conversational AI agent implementing HCS-10 communication, HCS-2 registries, and content inscription on Hedera
181 lines (180 loc) • 5.72 kB
JavaScript
import { TokenCounter } from "./index12.js";
const _MemoryWindow = class _MemoryWindow {
constructor(maxTokens = _MemoryWindow.DEFAULT_MAX_TOKENS, reserveTokens = _MemoryWindow.DEFAULT_RESERVE_TOKENS, tokenCounter) {
this.messages = [];
this.systemPrompt = "";
this.systemPromptTokens = 0;
if (reserveTokens >= maxTokens) {
throw new Error("Reserve tokens must be less than max tokens");
}
this.maxTokens = maxTokens;
this.reserveTokens = reserveTokens;
this.tokenCounter = tokenCounter || new TokenCounter();
}
/**
* Add a message to the memory window, pruning old messages if necessary
* @param message - The message to add
* @returns Result of the add operation including any pruned messages
*/
addMessage(message) {
this.tokenCounter.countMessageTokens(message);
this.messages.push(message);
const currentTokens = this.getCurrentTokenCount();
const availableTokens = this.maxTokens - this.reserveTokens;
let prunedMessages = [];
if (currentTokens > availableTokens) {
this.messages.pop();
prunedMessages = this.pruneToFit();
this.messages.push(message);
}
return {
added: true,
prunedMessages,
currentTokenCount: this.getCurrentTokenCount(),
remainingCapacity: this.getRemainingTokenCapacity()
};
}
/**
* Prune old messages to fit within token limits
* Removes messages in pairs to maintain conversational flow
* @returns Array of pruned messages
*/
pruneToFit() {
const prunedMessages = [];
const targetTokens = this.maxTokens - this.reserveTokens;
while (this.getCurrentTokenCount() > targetTokens && this.messages.length > 0) {
const batchSize = Math.min(_MemoryWindow.PRUNING_BATCH_SIZE, this.messages.length);
for (let i = 0; i < batchSize; i++) {
const prunedMessage = this.messages.shift();
if (prunedMessage) {
prunedMessages.push(prunedMessage);
}
}
if (prunedMessages.length > 1e3) {
break;
}
}
return prunedMessages;
}
/**
* Get current token count including system prompt and messages
* @returns Current token count
*/
getCurrentTokenCount() {
const messageTokens = this.tokenCounter.countMessagesTokens(this.messages);
return this.systemPromptTokens + messageTokens;
}
/**
* Get remaining token capacity before hitting the reserve limit
* @returns Remaining tokens that can be used
*/
getRemainingTokenCapacity() {
return Math.max(0, this.maxTokens - this.getCurrentTokenCount());
}
/**
* Check if a message can be added without exceeding limits
* @param message - The message to check
* @returns True if message can be added within reserve limits
*/
canAddMessage(message) {
const messageTokens = this.tokenCounter.countMessageTokens(message);
const currentTokens = this.getCurrentTokenCount();
const wouldExceedReserve = currentTokens + messageTokens > this.maxTokens - this.reserveTokens;
if (messageTokens > this.maxTokens) {
return false;
}
return !wouldExceedReserve || this.messages.length > 0;
}
/**
* Get all messages in the memory window
* @returns Copy of current messages array
*/
getMessages() {
return [...this.messages];
}
/**
* Clear all messages from the memory window
*/
clear() {
this.messages = [];
}
/**
* Set the system prompt and update token calculations
* @param systemPrompt - The system prompt text
*/
setSystemPrompt(systemPrompt) {
this.systemPrompt = systemPrompt;
this.systemPromptTokens = this.tokenCounter.estimateSystemPromptTokens(systemPrompt);
}
/**
* Get the current system prompt
* @returns Current system prompt
*/
getSystemPrompt() {
return this.systemPrompt;
}
/**
* Get current configuration
* @returns Memory window configuration
*/
getConfig() {
return {
maxTokens: this.maxTokens,
reserveTokens: this.reserveTokens,
currentTokens: this.getCurrentTokenCount(),
messageCount: this.messages.length,
systemPromptTokens: this.systemPromptTokens
};
}
/**
* Update token limits
* @param maxTokens - New maximum token limit
* @param reserveTokens - New reserve token amount
*/
updateLimits(maxTokens, reserveTokens) {
if (reserveTokens !== void 0 && reserveTokens >= maxTokens) {
throw new Error("Reserve tokens must be less than max tokens");
}
this.maxTokens = maxTokens;
if (reserveTokens !== void 0) {
this.reserveTokens = reserveTokens;
}
if (this.getCurrentTokenCount() > this.maxTokens - this.reserveTokens) {
this.pruneToFit();
}
}
/**
* Get statistics about the memory window
* @returns Memory usage statistics
*/
getStats() {
const currentTokens = this.getCurrentTokenCount();
const capacity = this.maxTokens;
const usagePercentage = currentTokens / capacity * 100;
return {
totalMessages: this.messages.length,
currentTokens,
maxTokens: capacity,
reserveTokens: this.reserveTokens,
systemPromptTokens: this.systemPromptTokens,
usagePercentage: Math.round(usagePercentage * 100) / 100,
remainingCapacity: this.getRemainingTokenCapacity(),
canAcceptMore: this.getRemainingTokenCapacity() > this.reserveTokens
};
}
/**
* Clean up resources
*/
dispose() {
this.clear();
this.tokenCounter.dispose();
}
};
_MemoryWindow.DEFAULT_MAX_TOKENS = 8e3;
_MemoryWindow.DEFAULT_RESERVE_TOKENS = 1e3;
_MemoryWindow.PRUNING_BATCH_SIZE = 2;
let MemoryWindow = _MemoryWindow;
export {
MemoryWindow
};
//# sourceMappingURL=index13.js.map