AWS Builder Center
Memory Consolidation Daemon for AI Agents with Bedrock

Memory Consolidation Daemon for AI Agents with Bedrock

Open-source daemon that uses Amazon Bedrock to extract and consolidate AI agent memory from session files. Covers architecture, prompt caching, and guardrails.

AI agents that operate over multiple sessions face a persistent challenge: memory management.
Session transcripts accumulate, facts contradict each other, and the agent's context window fills with redundant or stale information. Most agent frameworks provide memory storage, but few provide memory curation — the ongoing process of organizing, deduplicating, and pruning what the agent remembers.
 agent-memory-daemon  is an open-source TypeScript daemon that runs alongside any agent framework and uses Amazon Bedrock to automatically extract knowledge from session files and consolidate it into structured, size-budgeted memory.
This article covers the architecture, the Bedrock integration patterns, and how to deploy it alongside agent workloads.

Architecture overview

The daemon operates in two complementary modes within a single process:
Plain text
┌─────────────────────────────────────────────────┐
│ Daemon Process │
│ │
│ ┌──────────────┐ ┌─────────────────────┐ │
│ │ Extraction │ │ Consolidation │ │
│ │ │ │ │ │
│ │ Session files │ │ Memory directory │ │
│ │ → LLM pass │ │ → orient → gather │ │
│ │ → New memory │ │ → consolidate │ │
│ │ files │ │ → prune → index │ │
│ └──────┬───────┘ └──────────┬──────────┘ │
│ │ Shared lock │ │
│ └──────────┬───────────────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ PID-based │ │
│ │ mutual │ │
│ │ exclusion │ │
│ └────────────────┘ │
└─────────────────────────────────────────────────┘
│ │
┌────▼─────┐ ┌─────▼──────┐
│ Session │ │ Memory │
│ directory│ │ directory │
│ (input) │ │ (output) │
└──────────┘ └────────────┘
Extraction watches for new session content using a per-session cursor (file offset + mtime tracking), builds a prompt containing the current memory manifest and new session content, and calls Bedrock to identify facts, decisions, preferences, and error corrections worth persisting.
Consolidation runs on a three-gate trigger system (time elapsed + session count + lock acquisition), executing a four-phase LLM pass that orients on the current state, gathers related content, merges and deduplicates, then prunes stale entries. The  MEMORY.md  index is kept within a configurable line and byte budget.
Both modes share a PID-based lock file for mutual exclusion. Consolidation takes priority when both triggers fire simultaneously.

Amazon Bedrock integration

Converse API

The daemon uses the Bedrock Converse API via  @aws-sdk/client-bedrock-runtime , which provides a model-agnostic interface. This avoids model-specific payload formats and allows switching between Anthropic Claude, Amazon Nova, or other models by changing a single configuration value.
TypeScript
const command = new ConverseCommand({
modelId: this.modelId,
messages,
system: systemBlocks,
inferenceConfig: {
maxTokens: 8192,
temperature: 0.2,
},
});

Prompt caching with cachePoint

Both consolidation and extraction split their prompts into a stable system prefix (instructions, classification rules, response format) and a variable user message (memory manifest, session content). The system prefix is placed before a  cachePoint  block:
TypeScript
const systemBlocks: SystemContentBlock[] = [];

if (options?.systemPrompt) {
systemBlocks.push({ text: options.systemPrompt });
// Anthropic prompt caching: cache everything up to this point
systemBlocks.push({ cachePoint: { type: 'default' } });
}

systemBlocks.push({
text: 'You are a memory consolidation assistant...',
});
For Anthropic models on Bedrock, this means the ~2K character instruction prefix is cached across calls. In consolidation's multi-chunk mode (where a large memory directory is processed in multiple LLM calls), chunks 2+ get a cache hit on the shared instruction prefix. Non-Anthropic models silently ignore the  cachePoint  block.

Credential handling

The daemon uses the SDK's default credential provider chain, supporting environment variables,  ~/.aws/credentials , SSO, ECS container credentials, and EC2 instance metadata. An optional  profile  configuration allows specifying a named AWS profile:
toml
[llm_backend]
name = "bedrock"
region = "us-east-1"
profile = "my-profile"
model = "us.anthropic.claude-sonnet-4-20250514-v1:0"
Credentials are verified at startup by resolving them before the first API call, providing a clear error message if resolution fails.

Timeout configuration

Large memory directories can produce prompts exceeding 40K characters. The default SDK timeout is insufficient for these workloads. The daemon configures  NodeHttpHandler  with a 10-second connection timeout and a 5-minute request timeout:
TypeScript
requestHandler: new NodeHttpHandler({
connectionTimeout: 10_000,
requestTimeout: 300_000,
}),
Transient failures (network errors, 429 rate limits, 5xx server errors) are retried with exponential backoff up to 3 attempts. Client errors (4xx except 429) fail immediately.

Memory file structure

Each memory file is a markdown document with YAML frontmatter:
Markdown
---
name: "Bedrock request timeout"
description: "SDK default timeout insufficient for large prompts"
type: reference
---
BedrockRuntimeClient requires NodeHttpHandler with requestTimeout
of 300000ms (5 min) for prompts over 30K characters. The default
timeout causes ECONNABORTED errors on large consolidation passes.
Memory types ( user ,  feedback ,  project ,  reference ) are assigned by the LLM during extraction and used for manifest formatting. The memory manifest includes age information ("today", "yesterday", "N days ago") so the LLM can prioritize updating stale entries over creating duplicates.

Guardrails

Without limits, extraction can create files exponentially — each pass sees new files from the previous pass, producing an ever-growing manifest that prompts the LLM to create even more files. The daemon enforces several caps:
Guardrail
Default
Purpose
 max_memory_files 
50
Hard cap on total files in the memory directory
 max_files_per_batch 
10
Maximum creates per extraction pass
 max_prompt_chars 
40,000
Total prompt budget with progressive truncation
Per-session cursor
—
Tracks file offset + mtime to avoid reprocessing
Update and delete operations are not subject to creation caps, ensuring consolidation can always reorganize existing content.
Prompt budget enforcement uses progressive truncation: session blocks are removed from the end first, then the manifest is truncated at line boundaries. A final safety-net truncation ensures the prompt never exceeds the budget.

Deployment patterns

Alongside Strands agents

Point  session_directory  at the directory where your Strands agent writes session artifacts. At agent startup, read  MEMORY.md  and relevant topic files into the system prompt:
toml
memory_directory = "/app/memory"
session_directory = "/app/sessions"
extraction_enabled = true

[llm_backend]
name = "bedrock"
region = "us-east-1"
model = "us.anthropic.claude-sonnet-4-20250514-v1:0"

On ECS or EC2

The daemon runs as a long-lived Node.js process. It handles SIGTERM and SIGINT for graceful shutdown, rolling back any in-progress lock. The credential chain automatically picks up ECS task role credentials or EC2 instance profile credentials.
Bash
npx agent-memory-daemon start /app/memconsolidate.toml

Dry-run mode

Set  dry_run = true  to preview what the daemon would do without writing any files. All operations are logged with their content lengths and paths, allowing validation before enabling writes.

Observability

The daemon emits structured JSON logs to stderr:
JSON
{
"timestamp": "2026-04-07T14:23:01.234Z",
"level": "info",
"event": "extraction:complete",
"data": {
"created": 3,
"updated": 1,
"durationMs": 4521,
"promptLength": 39102,
"operationsRequested": 5,
"operationsApplied": 4,
"operationsSkipped": 1
}
}
Key events include  daemon:extraction-start ,  daemon:extraction-complete ,  daemon:consolidation-complete ,  extraction:max-memory-files-reached , and  extraction:max-files-per-batch-reached . These can be piped to CloudWatch Logs, parsed with  jq , or ingested by any log aggregation system.

Testing approach

The project uses property-based testing with fast-check extensively. Rather than example-based tests that check specific inputs, property tests generate random inputs and verify invariants:
  • Guardrail properties: for all generated extraction scenarios, post-extraction file count never exceeds  maxMemoryFiles 
  • Preservation properties: for all valid update operations, updates are applied regardless of creation caps
  • Round-trip properties: building a prompt and parsing a conforming JSON response always produces valid  FileOperation  objects
This approach caught the exponential file creation bug during development — the property test generated a scenario where 200+ files were created in a single pass, which would have been missed by hand-written examples.

Getting started

Bash
npm install agent-memory-daemon
npx agent-memory-daemon init
# Edit memconsolidate.toml with your Bedrock configuration
npx agent-memory-daemon start
The project is MIT-licensed and available on  GitHub . Contributions are welcome — see  CONTRIBUTING.md  for development setup and guidelines.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article