Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions mind-agents/src/utils/MemoryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ interface LeakDetectionResult {
recommendations: string[];
}

interface ManagedResource {
interface ManagedResource<T = unknown> {
id: string;
type: string;
resource: any;
resource: T;
cleanup: () => Promise<void> | void;
createdAt: number;
lastAccessed: number;
accessCount: number;
ttl?: number;
}

export class MemoryManager extends EventEmitter {
export class MemoryManager<T = unknown> extends EventEmitter {
private snapshots: MemorySnapshot[] = [];
private maxSnapshots = 100;
private snapshotInterval = 30000; // 30 seconds
private resources = new Map<string, ManagedResource>();
private weakRefs = new Set<WeakRef<any>>();
private resources = new Map<string, ManagedResource<T>>();
private weakRefs = new Set<WeakRef<T>>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The type of weakRefs is coupled with the class generic T, but the trackWeakRef method uses its own generic type parameter. This creates a type mismatch and will lead to a compilation error.

The trackWeakRef<T extends object>(obj: T) method is designed to track any object, not just resources of type T managed by this MemoryManager instance. Therefore, weakRefs should not be tied to the class generic T.

A more type-safe and correct type for weakRefs would be Set<WeakRef<object>> to reflect that it can hold weak references to any object.

Suggested change
private weakRefs = new Set<WeakRef<T>>();
private weakRefs = new Set<WeakRef<object>>();

private isMonitoring = false;
private monitoringTimer?: NodeJS.Timer;
private cleanupTimer?: NodeJS.Timer;
Expand Down Expand Up @@ -131,7 +131,7 @@ export class MemoryManager extends EventEmitter {
*/
registerResource(
type: string,
resource: any,
resource: T,
cleanup: () => Promise<void> | void,
options?: {
ttl?: number;
Expand All @@ -140,7 +140,7 @@ export class MemoryManager extends EventEmitter {
): string {
const id = options?.id || this.generateResourceId();

const managedResource: ManagedResource = {
const managedResource: ManagedResource<T> = {
id,
type,
resource,
Expand Down Expand Up @@ -185,7 +185,7 @@ export class MemoryManager extends EventEmitter {
/**
* Access a registered resource (updates access tracking)
*/
accessResource(id: string): any {
accessResource(id: string): T | null {
const resource = this.resources.get(id);
if (!resource) return null;

Expand Down Expand Up @@ -476,7 +476,7 @@ export class MemoryManager extends EventEmitter {

private cleanupWeakRefs(): void {
const initialSize = this.weakRefs.size;
const toRemove: WeakRef<any>[] = [];
const toRemove: WeakRef<T>[] = [];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Following the recommended change to weakRefs, the type of the toRemove array in cleanupWeakRefs should also be updated for consistency. It should hold WeakRef<object> instead of WeakRef<T>.

Suggested change
const toRemove: WeakRef<T>[] = [];
const toRemove: WeakRef<object>[] = [];


for (const weakRef of this.weakRefs) {
if (weakRef.deref() === undefined) {
Expand All @@ -503,4 +503,4 @@ export const memoryManager = new MemoryManager({
// Auto-start if not in test environment
if (process.env.NODE_ENV !== 'test') {
memoryManager.start();
}
}
18 changes: 11 additions & 7 deletions mind-agents/src/utils/context-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface CacheEntry<T> {
hits: number;
size: number;
ttl?: number;
metadata?: Record<string, any>;
metadata?: Record<string, unknown>;
}

/**
Expand Down Expand Up @@ -157,7 +157,7 @@ export class LRUCache<T> {
/**
* Estimate size of value
*/
private estimateSize(value: any): number {
private estimateSize(value: T): number {
try {
return JSON.stringify(value).length;
} catch {
Expand Down Expand Up @@ -202,8 +202,8 @@ export class LRUCache<T> {
/**
* Multi-level context cache
*/
export class ContextCache {
private l1Cache: LRUCache<any>; // Hot cache - in memory
export class ContextCache<T = unknown> {
private l1Cache: LRUCache<T>; // Hot cache - in memory
private l2Cache: LRUCache<string>; // Warm cache - compressed
private cleanupInterval?: NodeJS.Timeout;

Expand All @@ -229,7 +229,7 @@ export class ContextCache {
/**
* Get context from cache
*/
async get(key: string): Promise<any | undefined> {
async get(key: string): Promise<T | undefined> {
// Check L1 first
const l1Result = this.l1Cache.get(key);
if (l1Result) {
Expand All @@ -256,7 +256,11 @@ export class ContextCache {
/**
* Set context in cache
*/
async set(key: string, value: any, options: { ttl?: number; priority?: 'high' | 'normal' } = {}): Promise<void> {
async set(
key: string,
value: T,
options: { ttl?: number; priority?: 'high' | 'normal' } = {}
): Promise<void> {
// Always set in L1 for immediate access
this.l1Cache.set(key, value, options.ttl);

Expand Down Expand Up @@ -379,4 +383,4 @@ export const contextCache = new ContextCache();
// Cleanup on process exit
process.on('beforeExit', () => {
contextCache.stop();
});
});
Loading