— No reviews yet
0 installs
14 views
0.0% view→install
Install
$ agentstack add skill-latestaiagents-agent-skills-agent-memory-systems ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Are you the author of Agent Memory Systems? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claimAbout
Agent Memory Systems
Design and implement memory systems that give agents persistent knowledge and context.
When to Use
- Agents need to remember across sessions
- Multiple agents share knowledge
- Long-running tasks require state persistence
- Building agents that learn from experience
Memory Types
┌─────────────────────────────────────────────────────────────┐
│ AGENT MEMORY TAXONOMY │
├─────────────────────────────────────────────────────────────┤
│ │
│ Working Memory (Active Context) │
│ └─ Current conversation, immediate task state │
│ │
│ Short-Term Memory (Session) │
│ └─ Recent interactions, temporary facts │
│ │
│ Long-Term Memory (Persistent) │
│ ├─ Episodic: Past events, experiences │
│ ├─ Semantic: Facts, knowledge, learned info │
│ └─ Procedural: How to do things, skills │
│ │
└─────────────────────────────────────────────────────────────┘
Working Memory
The agent's current context window.
interface WorkingMemory {
// Current task context
task: {
description: string;
requirements: string[];
progress: string[];
};
// Active entities being discussed
entities: Map;
// Recent messages
conversationWindow: Message[];
// Scratchpad for reasoning
scratchpad: string;
}
class WorkingMemoryManager {
private memory: WorkingMemory;
private MAX_MESSAGES = 20;
addMessage(message: Message) {
this.memory.conversationWindow.push(message);
// Evict old messages
if (this.memory.conversationWindow.length > this.MAX_MESSAGES) {
const evicted = this.memory.conversationWindow.shift();
// Optionally summarize and store
this.summarizeToShortTerm(evicted);
}
}
updateEntity(id: string, entity: Entity) {
this.memory.entities.set(id, entity);
}
getContext(): string {
return `
Task: ${this.memory.task.description}
Progress: ${this.memory.task.progress.join(', ')}
Key Entities: ${[...this.memory.entities.values()].map(e => e.summary).join('\n')}
Recent Discussion: ${this.memory.conversationWindow.slice(-5).map(m => m.content).join('\n')}
`;
}
}
Short-Term Memory
Session-scoped, expires after inactivity.
interface ShortTermMemory {
sessionId: string;
startedAt: Date;
lastAccessedAt: Date;
expiresAt: Date;
// Conversation summary
summary: string;
// Key facts learned this session
facts: Fact[];
// Decisions made
decisions: Decision[];
// Files accessed
touchedFiles: string[];
}
class ShortTermStore {
private store = new Map();
private TTL_MS = 30 * 60 * 1000; // 30 minutes
async get(sessionId: string): Promise {
const memory = this.store.get(sessionId);
if (!memory) return null;
if (Date.now() > memory.expiresAt.getTime()) {
// Expired - archive to long-term
await this.archiveToLongTerm(memory);
this.store.delete(sessionId);
return null;
}
// Touch
memory.lastAccessedAt = new Date();
memory.expiresAt = new Date(Date.now() + this.TTL_MS);
return memory;
}
async addFact(sessionId: string, fact: Fact) {
const memory = await this.getOrCreate(sessionId);
memory.facts.push(fact);
// Check if fact should be promoted to long-term
if (this.shouldPromote(fact)) {
await this.promoteToLongTerm(fact);
}
}
}
Long-Term Memory
Episodic Memory (Events/Experiences)
interface Episode {
id: string;
timestamp: Date;
type: 'task_completed' | 'error_resolved' | 'user_feedback' | 'learning';
// What happened
description: string;
context: Record;
// Outcome
outcome: 'success' | 'failure' | 'partial';
lessons: string[];
// For retrieval
embedding: number[];
tags: string[];
}
class EpisodicMemory {
private vectorStore: VectorStore;
async remember(episode: Episode): Promise {
// Generate embedding for semantic search
episode.embedding = await this.embed(
`${episode.description} ${episode.lessons.join(' ')}`
);
await this.vectorStore.insert(episode);
}
async recall(query: string, limit: number = 5): Promise {
const queryEmbedding = await this.embed(query);
return this.vectorStore.similaritySearch(queryEmbedding, {
limit,
threshold: 0.7
});
}
async recallByType(type: Episode['type'], limit: number = 10): Promise {
return this.vectorStore.filter({ type }, { limit, orderBy: 'timestamp DESC' });
}
}
Semantic Memory (Facts/Knowledge)
interface Fact {
id: string;
subject: string;
predicate: string;
object: string;
confidence: number;
source: string;
learnedAt: Date;
lastVerified: Date;
embedding: number[];
}
class SemanticMemory {
private facts: VectorStore;
async learn(fact: Omit): Promise {
// Check for conflicts
const existing = await this.findRelated(fact.subject, fact.predicate);
if (existing.length > 0) {
// Handle contradiction or update
await this.resolveConflict(existing, fact);
return;
}
// Store new fact
await this.facts.insert({
...fact,
id: generateId(),
embedding: await this.embed(`${fact.subject} ${fact.predicate} ${fact.object}`)
});
}
async query(question: string): Promise {
// Semantic search for relevant facts
const embedding = await this.embed(question);
return this.facts.similaritySearch(embedding, { limit: 10 });
}
async getFactsAbout(subject: string): Promise {
return this.facts.filter({ subject });
}
}
Procedural Memory (Skills/How-To)
interface Procedure {
id: string;
name: string;
description: string;
trigger: string; // When to use this
steps: string[];
examples: Example[];
successRate: number;
usageCount: number;
}
class ProceduralMemory {
private procedures: Map = new Map();
async findProcedure(task: string): Promise {
// Match task to known procedures
const candidates = await this.matchProcedures(task);
if (candidates.length === 0) return null;
// Return best match by success rate and relevance
return candidates.sort((a, b) =>
(b.successRate * b.relevanceScore) - (a.successRate * a.relevanceScore)
)[0];
}
async recordOutcome(procedureId: string, success: boolean): Promise {
const proc = this.procedures.get(procedureId);
if (!proc) return;
// Update success rate with exponential moving average
const alpha = 0.1;
proc.successRate = alpha * (success ? 1 : 0) + (1 - alpha) * proc.successRate;
proc.usageCount++;
}
async learnProcedure(
name: string,
steps: string[],
fromEpisode: Episode
): Promise {
// Create new procedure from successful episode
this.procedures.set(generateId(), {
id: generateId(),
name,
description: fromEpisode.description,
trigger: this.extractTrigger(fromEpisode),
steps,
examples: [{ input: fromEpisode.context, output: fromEpisode.outcome }],
successRate: 1.0,
usageCount: 1
});
}
}
Shared Memory (Multi-Agent)
interface SharedMemory {
// Namespace for isolation
namespace: string;
// Read/write with locking
read(key: string): Promise;
write(key: string, value: unknown): Promise;
// Atomic operations
compareAndSwap(key: string, expected: unknown, newValue: unknown): Promise;
// Subscriptions
subscribe(pattern: string, callback: (key: string, value: unknown) => void): void;
}
class RedisSharedMemory implements SharedMemory {
constructor(
private redis: Redis,
public namespace: string
) {}
private key(k: string): string {
return `${this.namespace}:${k}`;
}
async read(key: string): Promise {
const value = await this.redis.get(this.key(key));
return value ? JSON.parse(value) : null;
}
async write(key: string, value: unknown): Promise {
await this.redis.set(this.key(key), JSON.stringify(value));
await this.redis.publish(`${this.namespace}:updates`, JSON.stringify({ key, value }));
}
subscribe(pattern: string, callback: (key: string, value: unknown) => void): void {
const subscriber = this.redis.duplicate();
subscriber.psubscribe(`${this.namespace}:${pattern}`);
subscriber.on('pmessage', (_, channel, message) => {
const { key, value } = JSON.parse(message);
callback(key, value);
});
}
}
Memory Retrieval Strategies
Strategy 1: Recency-Weighted
function recencyWeightedRetrieval(
memories: Memory[],
query: string,
recencyWeight: number = 0.3
): Memory[] {
const now = Date.now();
return memories
.map(m => ({
memory: m,
score: (1 - recencyWeight) * m.relevanceScore +
recencyWeight * Math.exp(-(now - m.timestamp.getTime()) / TIME_DECAY)
}))
.sort((a, b) => b.score - a.score)
.map(x => x.memory);
}
Strategy 2: Importance-Based
function importanceBasedRetrieval(
memories: Memory[],
query: string
): Memory[] {
return memories
.map(m => ({
memory: m,
score: m.relevanceScore * m.importance * (m.accessCount / 10)
}))
.sort((a, b) => b.score - a.score)
.map(x => x.memory);
}
Strategy 3: Contextual (RAG)
async function contextualRetrieval(
query: string,
currentContext: Context
): Promise {
// Expand query with context
const expandedQuery = `
${query}
Current task: ${currentContext.task}
Related entities: ${currentContext.entities.join(', ')}
`;
// Vector search
const candidates = await vectorStore.search(expandedQuery, { limit: 20 });
// Rerank with cross-encoder
return reranker.rerank(query, candidates, { limit: 5 });
}
Memory Maintenance
class MemoryMaintenance {
// Consolidate short-term to long-term
async consolidate(): Promise {
const sessions = await shortTermStore.getExpired();
for (const session of sessions) {
// Extract key learnings
const learnings = await this.extractLearnings(session);
// Store in appropriate long-term stores
for (const learning of learnings) {
if (learning.type === 'fact') {
await semanticMemory.learn(learning);
} else if (learning.type === 'procedure') {
await proceduralMemory.learnProcedure(learning);
} else {
await episodicMemory.remember(learning);
}
}
}
}
// Forget outdated/irrelevant memories
async forget(): Promise {
// Remove low-value memories
await episodicMemory.prune({
olderThan: days(90),
accessCountBelow: 2,
importanceBelow: 0.2
});
// Update fact confidence based on verification
await semanticMemory.decayUnverified({
olderThan: days(30),
decayRate: 0.1
});
}
}
Best Practices
- Separate concerns - Different memory types for different purposes
- Index wisely - Use embeddings for semantic search
- Expire aggressively - Don't let memory grow unbounded
- Version memories - Track when facts were learned/updated
- Handle conflicts - New information may contradict old
- Secure sensitive data - Some memories shouldn't be shared
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: latestaiagents
- Source: latestaiagents/agent-skills
- License: MIT
- Homepage: https://latestaiagents.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.