Skip to main content

@tokenring-ai/memory

The @tokenring-ai/memory package provides short-term memory management functionality for Token Ring AI agents. It enables agents to store and recall information during chat sessions, maintaining context across interactions with a simple, effective memory system. Memories are stored in agent state and accessible via service methods, tools, chat commands, context handlers, and scripting functions.

Key Features

  • Memory Storage: Store and retrieve text-based memories as strings in an ordered list
  • State Management: Memories stored in agent state with serialization and persistence support
  • Service-Based Access: Programmatic access to memories through ShortTermMemoryService
  • Interactive Management: Chat commands for interactive memory operations
  • Context Injection: Automatic injection of memories into agent context via context handlers
  • Scripting Integration: Native functions for scripting workflows
  • Memory Manipulation: Full CRUD operations including add, remove, replace, and update
  • Sub-agent Support: State transfer capability between parent and child agents
  • Session Management: Memories clear on chat or memory resets

Core Components

ShortTermMemoryService

The primary service class implementing memory management for agents. Provides programmatic access to memory operations.

import ShortTermMemoryService from '@tokenring-ai/memory/ShortTermMemoryService';

// Service is automatically available through agent
const memoryService = agent.requireServiceByType(ShortTermMemoryService);

Service Class

class ShortTermMemoryService implements TokenRingService {
name = "ShortTermMemoryService";
description = "Provides Short Term Memory functionality";

attach(agent: Agent): void;
addMemory(memory: string, agent: Agent): void;
clearMemory(agent: Agent): void;
spliceMemory(index: number, count: number, agent: Agent, ...items: string[]): void;
}

Properties:

  • name: string = "ShortTermMemoryService" — Service identifier
  • description: string = "Provides Short Term Memory functionality" — Service description

Methods:

  • attach(agent: Agent): void — Initializes the MemoryState on agent attachment. Stores memories in agent state.

    service.attach(agent);
    // Initializes MemoryState with empty memories array
  • addMemory(memory: string, agent: Agent): void — Adds a memory string to the agent's memory state. Memory is pushed to the end of the memories array.

    memoryService.addMemory('Important meeting at 3 PM', agent);
  • clearMemory(agent: Agent): void — Clears all memories from the agent's state.

    memoryService.clearMemory(agent);
  • spliceMemory(index: number, count: number, agent: Agent, ...items: string[]): void — Modifies the memory array at the specified index. Can be used for:

    • Removing items: spliceMemory(0, 1, agent) — Remove first item
    • Replacing items: spliceMemory(0, 1, agent, 'New memory') — Replace first item with new content
    • Inserting items: spliceMemory(0, 0, agent, 'New memory') — Insert at beginning
    // Remove first memory
    memoryService.spliceMemory(0, 1, agent);

    // Replace first memory
    memoryService.spliceMemory(0, 1, agent, 'Updated memory');

    // Insert at beginning
    memoryService.spliceMemory(0, 0, agent, 'New memory at start');

MemoryState

The memory state slice that stores memory data with serialization support. This is the actual storage mechanism used by the memory service.

import { MemoryState } from '@tokenring-ai/memory/state/memoryState';

const state = new MemoryState({ memories: ['First memory'] });

State Class

class MemoryState implements AgentStateSlice<typeof serializationSchema> {
name = "MemoryState";
serializationSchema = serializationSchema;
memories: string[] = [];

reset(): void;
transferStateFromParent(parent: Agent): void;
serialize(): z.output<typeof serializationSchema>;
deserialize(data: z.output<typeof serializationSchema>): void;
show(): string[];
}

const serializationSchema = z.object({
memories: z.array(z.string())
});

Properties:

  • name: string = "MemoryState" — State slice name
  • serializationSchema: z.ZodObject — Zod schema for serialization validation
  • memories: string[] — Array of memory strings

Methods:

  • constructor({memories = []}: { memories?: string[] } = {}) — Creates a new memory state with optional initial memories.

    const state = new MemoryState({ memories: ['Initial memory'] });
  • reset(): void — Clears all memories when reset is called for chat or memory resets.

    state.reset();
    // memories array is cleared
  • transferStateFromParent(parent: Agent): void — Transfers state from parent agent to this agent. Useful for sub-agent patterns.

    const subState = subAgent.getState(MemoryState);
    subState.transferStateFromParent(parentAgent);
  • serialize(): z.output<typeof serializationSchema> — Serializes memories to a plain object for persistence.

    const data = state.serialize();
    // Returns: { memories: ['memory1', 'memory2'] }
  • deserialize(data: z.output<typeof serializationSchema>): void — Restores memories from serialized data.

    state.deserialize({ memories: ['memory1', 'memory2'] });
  • show(): string[] — Returns a formatted string representation of memories with 1-based indexing.

    const display = state.show();
    // Returns:
    // [
    // 'Memories: 2',
    // ' [1] memory1',
    // ' [2] memory2'
    // ]

Services

ShortTermMemoryService

The ShortTermMemoryService is a TokenRingService implementation that provides memory management functionality. It is automatically registered when the memory plugin is installed.

Service Registration

import ShortTermMemoryService from '@tokenring-ai/memory/ShortTermMemoryService';

// Automatic registration via plugin
import memoryPlugin from '@tokenring-ai/memory/plugin';
app.installPlugin(memoryPlugin);

// Or manual registration
app.addServices(new ShortTermMemoryService());

Service Methods

MethodDescriptionParametersReturns
attachInitialize memory state on agent attachmentagent: Agentvoid
addMemoryAdd a memory string to the agent's memory statememory: string, agent: Agentvoid
clearMemoryClear all memories from the agent's stateagent: Agentvoid
spliceMemoryModify the memory array at specified indexindex: number, count: number, agent: Agent, ...items: string[]void

RPC Endpoints

This package does not define any RPC endpoints. Memory operations are accessed through:

  • Tools (via ChatService)
  • Chat commands (via AgentCommandService)
  • Service methods (via Agent)
  • Scripting functions (via ScriptingService)

Chat Commands

The package provides the following slash-prefixed commands for memory management:

CommandDescriptionExample
/memory listDisplay all stored memory items/memory list
/memory add <text>Add a new memory item/memory add Remember to call client
/memory clearClear all memory items/memory clear
/memory remove <index>Remove memory item at specified index (0-based)/memory remove 0
/memory set <index> <text>Update memory item at specified index/memory set 1 Updated meeting notes

Command Details

/memory list

Display all stored memory items.

Help:

# /memory list

Display all stored memory items.

## Example

/memory list

Output Format:

Memory items:
[0] First memory item
[1] Second memory item

/memory add <text>

Add a new memory item.

Help:

# /memory add

Add a new memory item.

## Example

/memory add Remember to buy groceries tomorrow

Output:

Added new memory: Remember to buy groceries tomorrow
Memory items:
[0] Remember to buy groceries tomorrow

/memory clear

Remove all memory items.

Help:

# /memory clear

Remove all memory items.

## Example

/memory clear

Output:

Cleared all memory items

/memory remove <index>

Remove memory item at specific index.

Help:

# /memory remove

Remove memory item at specific index.

## Example

/memory remove 0

Output:

Removed memory item at index 0
Memory items:
[0] Remaining memory item

/memory set <index> <text>

Update memory item at specific index.

Help:

# /memory set

Update memory item at specific index.

## Example

/memory set 0 Updated meeting notes

Output:

Updated memory item at index 0
Memory items:
[0] Updated meeting notes

Usage Examples

// Add memory items
await agent.executeCommand('/memory add Remember to check emails tomorrow');
await agent.executeCommand('/memory add Meeting notes: Discuss project timeline');

// List memory items
const result = await agent.executeCommand('/memory list');
// Output:
// Memory items:
// [0] Remember to check emails tomorrow
// [1] Meeting notes: Discuss project timeline

// Remove memory at index 0
await agent.executeCommand('/memory remove 0');
// Output:
// Removed memory item at index 0
// Memory items:
// [0] Meeting notes: Discuss project timeline

// Update memory at index 0
await agent.executeCommand('/memory set 0 Updated meeting time');
// Output:
// Updated memory item at index 0
// Memory items:
// [0] Updated meeting time

// Clear all memories
await agent.executeCommand('/memory clear');
// Output:
// Cleared all memory items

Configuration

Plugin Configuration

The memory plugin has no specific configuration options. The configuration schema is empty:

import { z } from "zod";

const packageConfigSchema = z.object({});

Integration

Agent System

The memory service integrates with the agent framework through:

  • Service Registration: TokenRingService interface implementation
  • State Management: AgentStateSlice for memory persistence
  • Agent Access: Service accessed via agent.requireServiceByType()
  • State Mutation: agent.mutateState() for memory modifications

Chat Service

Memory tools and context handlers are registered with the chat service automatically when the plugin is installed:

// Automatic registration via plugin
import memoryPlugin from '@tokenring-ai/memory/plugin';
app.installPlugin(memoryPlugin);

// The plugin automatically registers:
// - addMemory tool with ChatService
// - short-term-memory context handler with ChatService

Agent Command Service

Chat commands are registered with the agent command service for interactive management:

// Automatic registration via plugin
// The memory commands are registered with AgentCommandService:
// - memory list
// - memory add
// - memory clear
// - memory remove
// - memory set

Scripting Service

Global functions provide scripting access to memory operations:

// Automatic registration via plugin
// The following functions are registered with ScriptingService:
// - addMemory(memory: string): string
// - clearMemory(): string

Usage Examples

Basic Memory Operations

import Agent from '@tokenring-ai/agent/Agent';
import { ShortTermMemoryService } from '@tokenring-ai/memory';
import { MemoryState } from '@tokenring-ai/memory/state/memoryState';

// Create agent with memory service
const agent = new Agent({ services: [new ShortTermMemoryService()] });
const memoryService = agent.requireServiceByType(ShortTermMemoryService);

// Add memories
memoryService.addMemory('User prefers dark mode', agent);
memoryService.addMemory('Meeting at 3 PM tomorrow', agent);

// Check memory state
const state = agent.getState(MemoryState);
console.log(state.show());
// Output:
// [
// 'Memories: 2',
// ' [1] User prefers dark mode',
// ' [2] Meeting at 3 PM tomorrow'
// ]

Memory Manipulation

// Replace first memory with new content
memoryService.spliceMemory(0, 1, agent, 'Updated user preference');

// Insert new memory at index 1
memoryService.spliceMemory(1, 0, agent, 'New important fact');

// Remove memory at index 2
memoryService.spliceMemory(2, 1, agent);

// Display updated memory list
const state = agent.getState(MemoryState);
console.log(state.show());

State Persistence

import { MemoryState } from '@tokenring-ai/memory/state/memoryState';

// Serialize memories for persistence
const state = agent.getState(MemoryState);
const serializedData = state.serialize();
console.log('Serialized:', serializedData);
// Output: { memories: ['memory1', 'memory2'] }

// Save serialized data (e.g., to database, file)
// ... persistence logic ...

// Later, restore memories for a new agent
const newAgent = new Agent({ services: [new ShortTermMemoryService()] });
const newState = newAgent.getState(MemoryState);
const savedData = { memories: ['memory1', 'memory2'] };
newState.deserialize(savedData);

Sub-agent Integration

import { MemoryState } from '@tokenring-ai/memory/state/memoryState';

// Parent agent with memory
const parentAgent = new Agent({ services: [new ShortTermMemoryService()] });
parentAgent.addState(new MemoryState({ memories: ['Parent memory 1', 'Parent memory 2'] }));

// Create sub-agent
const subAgent = parentAgent.createSubAgent();
const subState = subAgent.getState(MemoryState);

// Transfer state from parent
subState.transferStateFromParent(parentAgent);

// Sub-agent now has access to parent's memories
console.log(subState.show());
// Output:
// [
// 'Memories: 2',
// ' [1] Parent memory 1',
// ' [2] Parent memory 2'
// ]

Tool Usage

// Execute memory_add tool programmatically
await agent.executeTool('memory_add', {
memory: 'Project deadline is Friday'
});

Context Handler Integration

The context handler automatically injects memories into agent context:

// Context structure after adding memories:
// [
// ...previous conversation,
// { role: "user", content: "User prefers coffee over tea" },
// { role: "user", content: "Meeting scheduled for 2 PM tomorrow" }
// ]

Scripting Integration

import { ScriptingService } from '@tokenring-ai/scripting';

// Access scripting service
const scriptingService = app.requireService(ScriptingService);

// Add memory via scripting
await scriptingService.eval('addMemory("Scripting example")');
// Returns: "Added memory: Scripting example..."

// Clear memory via scripting
await scriptingService.eval('clearMemory()');
// Returns: "Memory cleared"

Best Practices

  1. Use Service Methods: Access memories through ShortTermMemoryService methods for consistency
  2. Handle State Correctly: Always use agent.mutateState() for memory modifications (handled automatically by service methods)
  3. Serialize Before Persistence: Call state.serialize() before saving agent state
  4. Use Index Carefully: Remember that indices are 0-based in memory operations
  5. Validate Input: Use tool and command functions for proper validation
  6. Transfer State Appropriately: Only transfer state between related parent/child agents
  7. Leverage Context Handlers: Use the context handler system for automatic memory injection rather than manual injection

Error Handling

The package provides comprehensive error handling for memory operations:

Error Types

Error TypeDescriptionWhen Thrown
ErrorMissing parameter errorWhen memory_add tool receives empty memory
CommandFailedErrorCommand execution failureWhen memory command receives invalid operation or parameters

Error Examples

// Tool error - missing memory parameter
try {
await agent.executeTool('memory_add', { memory: '' });
} catch (error) {
console.error(error.message); // "[memory_add] Missing parameter: memory"
}

// Command error - invalid operation
try {
await agent.executeCommand('/memory invalid_op');
} catch (error) {
console.error(error.message); // "Unknown operation."
}

// Command error - missing text
try {
await agent.executeCommand('/memory add');
} catch (error) {
console.error(error.message); // "Please provide text for the memory item"
}

// Command error - invalid index
try {
await agent.executeCommand('/memory remove abc');
} catch (error) {
console.error(error.message); // "Please provide a valid index number"
}

Testing and Development

Testing

# Run tests
bun test

# Run tests in watch mode
bun test:watch

# Run tests with coverage
bun test:coverage

# Build TypeScript
bun run build

Package Structure

pkg/memory/
├── index.ts # Main entry point, exports ShortTermMemoryService
├── ShortTermMemoryService.ts # Service implementation providing memory methods
├── state/
│ └── memoryState.ts # Agent state slice for memory storage and serialization
├── contextHandlers/
│ └── shortTermMemory.ts # Context handler for injecting memories into agent context
├── tools/
│ └── addMemory.ts # Tool to add memory items
├── commands/
│ ├── memory.ts # /memory command index
│ └── memory/
│ ├── list.ts # /memory list
│ ├── add.ts # /memory add
│ ├── clear.ts # /memory clear
│ ├── remove.ts # /memory remove
│ ├── set.ts # /memory set
│ └── _listMemories.ts # Shared list helper
├── tools.ts # Exports agent tools
├── commands.ts # Exports chat commands
├── contextHandlers.ts # Exports context handlers
├── plugin.ts # Plugin for automatic service registration
├── package.json # Package metadata and dependencies
├── vitest.config.ts # Vitest configuration
└── README.md # Package documentation

Dependencies

PackageVersionPurpose
@tokenring-ai/app0.2.0Application framework for service registration and plugin system
@tokenring-ai/chat0.2.0Chat functionality and tool definitions
@tokenring-ai/agent0.2.0Agent framework and state management
@tokenring-ai/scripting0.2.0Scripting capability for custom functions
@tokenring-ai/utility0.2.0Utility functions
zod^4.3.6Runtime type validation for state serialization

Dev Dependencies

PackageVersionPurpose
vitest^4.0.18Testing framework
typescript5.9.3TypeScript compiler
  • @tokenring-ai/agent — Agent framework with state management
  • @tokenring-ai/app — Application system and service registration
  • @tokenring-ai/chat — Chat functionality and tool system
  • @tokenring-ai/scripting — Scripting context for custom functions
  • State Management — Agent state slices for persistence

License

MIT License - see LICENSE file for details.