Memory Bank Architecture for Persistent Context in OpenWork

OpenWork implements a persistent memory bank using Den DB with dual-table relational storage, portable timestamp defaults, and full-text search capabilities to maintain agent and user context across sessions.

The memory bank architecture in OpenWork provides durable storage for contextual information such as chat memories, snippets, and embeddings. Built on the Den DB layer within the different-ai/openwork repository—documented in docs/memory-bank-architecture.md—this system ensures that conversational context and agent state survive application restarts while supporting multi-tenant isolation.

Core Schema Design

The foundation of OpenWork's persistent context relies on two relational tables defined in ee/packages/den-db/src/schema/memory.ts.

The memory and memory_context Tables

The schema implements a parent-child relationship between primary records and their contextual metadata:

  • memory: Stores the primary record for each piece of context with columns id, user_id, org_id, scope, content, source, created_at, and updated_at. This table supports multi-tenant isolation through user_id and org_id fields, while scope enables granular access control.

  • memory_context: Maintains contextual snippets linked to parent memory entries via memory_id. This table includes id, memory_id, snippet, origin, and created_at columns to store excerpts and provenance information.

Both tables utilize a portable created_at default set to CURRENT_TIMESTAMP(3) to ensure consistent millisecond-precision timestamps across different database environments.

Migration Strategy and Portability

The Den DB layer enforces schema consistency through idempotent migration helpers located in ee/packages/den-db/src/fulltext.ts.

Portable Timestamp Defaults

The memoryCreatedAtDefaultIsPortable function normalizes timestamp defaults during migrations, guaranteeing that the created_at column behaves identically whether running in development, staging, or production environments. This normalization prevents timestamp precision drift that could compromise temporal queries.

Idempotent FULLTEXT Indexing

To enable efficient natural-language retrieval, the system creates a FULLTEXT index named memory_content_fulltext on the memory.content column. The ensureMemoryFulltextIndex function guards this operation idempotently, ensuring the index exists regardless of database provisioning method or migration history.

API Surface and Integration

The memory bank exposes CRUD operations through the Den API, implemented in ee/apps/den-api/src/routes/memory/*.

Den API Routes

The /v1/memory endpoints translate HTTP requests into database operations against the memory and memory_context tables. These routes enforce the multi-tenant isolation model by filtering queries against user_id, org_id, and scope parameters. Agents and UI components interact with persisted context through standardized REST interfaces for reading, writing, and searching memory entries.

Practical Implementation Examples

The following TypeScript examples demonstrate interacting with the memory bank schema:

// Insert a new memory entry (used by the "store chat" capability)
await executor.query(
  `INSERT INTO memory (id, user_id, org_id, scope, content, source)
   VALUES (?, ?, ?, 'user', ?, 'chat')`,
  [memoryId, userId, orgId, chatContent],
);
// Add a snippet linked to the memory (e.g., an excerpt)
await executor.query(
  `INSERT INTO memory_context (id, memory_id, snippet, origin)
   VALUES (?, ?, ?, 'active_conversation')`,
  [contextId, memoryId, excerpt],
);
// Full-text search across stored memories
const matches = await executor.query(
  `SELECT id, scope FROM memory
   WHERE MATCH(content) AGAINST (? IN NATURAL LANGUAGE MODE) AND id = ?`,
  [searchTerm, memoryId],
);

Summary

  • Dual-table architecture: The memory and memory_context tables in ee/packages/den-db/src/schema/memory.ts separate primary records from contextual snippets.
  • Portability guarantees: The memoryCreatedAtDefaultIsPortable function in ee/packages/den-db/src/fulltext.ts ensures consistent timestamp behavior across environments.
  • Full-text search: The memory_content_fulltext index enables natural-language queries, maintained idempotently via ensureMemoryFulltextIndex.
  • Multi-tenant API: Den API routes in ee/apps/den-api/src/routes/memory/* expose the memory bank through /v1/memory endpoints with isolation by user_id, org_id, and scope.
  • Validation: The schema is validated through ee/packages/den-db/scripts/verify-memory-schema.ts.

Frequently Asked Questions

How does OpenWork ensure memory persistence across application restarts?

OpenWork persists context through the Den DB relational layer, storing data in the memory and memory_context tables with durable defaults. The portable timestamp normalization in ee/packages/den-db/src/fulltext.ts ensures schema consistency across deployments, while the SQL schema itself guarantees data survives application restarts.

What is the purpose of the memory_context table?

The memory_context table stores supplementary snippets and origin metadata linked to parent records in the memory table via the memory_id foreign key. This separation allows the system to maintain granular contextual excerpts—such as conversation fragments or source attributions—without bloating the primary memory records.

How does the full-text search implementation work?

The implementation creates a MySQL FULLTEXT index named memory_content_fulltext on the memory.content column. The ensureMemoryFulltextIndex function in ee/packages/den-db/src/fulltext.ts manages this index idempotently during migrations, enabling natural-language queries using MATCH ... AGAINST syntax for efficient content retrieval.

Where is the memory bank schema defined and validated?

The schema definition resides in ee/packages/den-db/src/schema/memory.ts, which specifies the table structures and relationships. Validation occurs through ee/packages/den-db/scripts/verify-memory-schema.ts, a test harness that confirms schema integrity, timestamp portability, and index presence against live database instances.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →