close
Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Spring AI AgentCore Memory

Spring AI ChatMemory integration with Amazon AgentCore Memory service.

For quick start and usage examples, see the main README.

Features

  • Spring AI Integration: Implements ChatMemoryRepository interface
  • Auto-configuration: Zero-configuration setup with Spring Boot
  • Short-Term Memory: Conversation history with MessageWindowChatMemory
  • Long-Term Memory: 4 consolidation strategies (Semantic, User Preference, Summary, Episodic)

Memory Types

Short-Term Memory (STM)

  • Implements ChatMemoryRepository interface for conversation history
  • Works with MessageWindowChatMemory for sliding window conversations

Long-Term Memory (LTM)

  • Semantic: Semantic search for user facts using the current query
  • User Preference: Lists ALL stored preferences regardless of query — preferences should always apply
  • Summary: Semantic search for conversation summaries by session
  • Episodic: Semantic search for past interactions and reflections

Advisor Execution Order

LTM advisors run before STM advisor (lower order = earlier execution):

Order Advisor Target Purpose
100 Semantic System prompt Add relevant facts
101 User Preference System prompt Add preferences
102 Summary User prompt Augment query with context
103 Episodic System prompt Add past interactions
1000+ STM (MessageChatMemoryAdvisor) Messages Add conversation history

Why LTM before STM? LTM enriches the prompt with persistent knowledge (facts, preferences) before STM adds recent conversation history. This ensures the model has full context: who the user is (LTM) + what was just discussed (STM).

System Prompt vs User Prompt

Memory Type Target Reason
Semantic System Stable context about user, cacheable
User Preference System Stable settings, cacheable
Episodic System Background context, cacheable
Summary User Query-specific augmentation, varies per request

Prompt Caching Benefits: Facts, preferences, and episodic memories go to the system prompt because they're relatively stable across requests. With Bedrock's prompt caching (cache-options.strategy: SYSTEM_AND_TOOLS), the system prompt is cached and reused, reducing latency and cost. Only summaries augment the user prompt since they're query-specific.

Configuration Reference

STM Configuration

agentcore:
  memory:
    memory-id: your-memory-id                    # Required: AgentCore Memory ID (shared with LTM)
    short-term:
      total-events-limit: 100                    # Optional: Max events to retrieve (context window)
      default-session: default-session           # Optional: Default session name
      page-size: 50                              # Optional: API pagination size

Migration (1.1.0): STM-only properties moved from agentcore.memory.* to agentcore.memory.short-term.* for consistency with agentcore.memory.long-term.*. The old keys still work in 1.1.x but log a deprecation warning at startup and will be removed in a future release. See issue #49.

The default of ignore-unknown-roles has changed from false to true. Spring AI 2.0.0-M7+ runs tool execution at the advisor layer, which routes ToolResponseMessage through ChatMemory.add(...). With the previous default the repository threw IllegalStateException: Unsupported message type on any tool-using turn. The new default skips non-dialogue messages (TOOL, OTHER) instead, which is the only sensible behaviour for M7+ agents — tool results are point-in-time facts that should not be persisted into conversation history. The property itself (ignore-unknown-roles) is now deprecated and will be removed in a future major: skipping non-dialogue messages becomes hardcoded behaviour. The misnomer ("unknown roles" — TOOL/OTHER are first-class AgentCore roles) and the lack of a useful false mode mean the toggle has no production value. See issue #109.

LTM Configuration

There are two ways to configure Long-Term Memory:

Option 1: Autodiscovery (Recommended)

Automatically discover all strategies from your AgentCore Memory:

agentcore:
  memory:
    memory-id: ${MEMORY_ID}
    long-term:
      auto-discovery: true                        # Discovers strategies from AWS

Autodiscovery behavior:

  • Queries AWS to discover all strategies configured in your memory
  • Creates advisors only for supported types: SEMANTIC, SUMMARIZATION, USER_PREFERENCE, EPISODIC
  • Skips CUSTOM strategy types (not supported by autodiscovery)
  • Uses the first namespace if a strategy has multiple namespaces
  • Uses default topK values for each strategy type

Overriding discovered defaults:

You can override specific settings for discovered strategies by providing explicit configuration. The explicit config is applied only when the strategy-id matches the discovered one:

agentcore:
  memory:
    memory-id: ${MEMORY_ID}
    long-term:
      auto-discovery: true
      semantic:
        strategy-id: discovered-semantic-id      # Must match discovered ID
        top-k: 5                                  # Override default topK
        namespace-pattern: /custom/namespace     # Override namespace (must exist in AWS)
      summary:
        strategy-id: discovered-summary-id
        top-k: 3

Override rules:

  • strategy-id must match the discovered strategy ID for overrides to apply
  • If strategy-id doesn't match, the explicit config is ignored
  • namespace-pattern must match one of the namespaces discovered from AWS, or use auto-register=true

Namespace auto-registration:

If you want to use a namespace that doesn't exist in AWS yet:

agentcore:
  memory:
    long-term:
      auto-discovery: true
      namespace:
        auto-register: true                      # Register new namespaces in AWS
      semantic:
        strategy-id: discovered-semantic-id
        namespace-pattern: /new/custom/namespace # Will be registered in AWS

Option 2: Explicit Configuration

Manually specify each strategy:

agentcore:
  memory:
    long-term:
      semantic:
        strategy-id: ${SEMANTIC_STRATEGY_ID}     # Enables strategy (omit to disable)
        top-k: 3                                 # Default: 3
        scope: ACTOR                             # Default: ACTOR
      user-preference:
        strategy-id: ${USER_PREFERENCE_STRATEGY_ID}  # Enables strategy (no top-k: lists all)
        scope: ACTOR                             # Default: ACTOR
      summary:
        strategy-id: ${SUMMARY_STRATEGY_ID}      # Enables strategy
        top-k: 3                                 # Default: 3
        scope: SESSION                           # Default: SESSION
      episodic:
        strategy-id: ${EPISODIC_STRATEGY_ID}     # Enables strategy
        reflections-strategy-id: ${REFLECTIONS_STRATEGY_ID}  # Optional: enables reflections
        episodes-top-k: 3                        # Default: 3
        reflections-top-k: 2                     # Default: 2
        scope: ACTOR                             # Default: ACTOR

Scope Options

Scope Namespace Pattern Use Case
ACTOR /strategies/{memoryStrategyId}/actors/{actorId} Search across all sessions for the user
SESSION /strategies/{memoryStrategyId}/actors/{actorId}/sessions/{sessionId} Search only current session

Custom Namespace Patterns

You can override the default namespace patterns with custom ones using the namespace-pattern property:

agentcore:
  memory:
    long-term:
      summary:
        strategy-id: ${SUMMARY_STRATEGY_ID}
        namespace-pattern: custom-namespace/strategies/{memoryStrategyId}/actors/{actorId}/sessions/{sessionId}

Important: The custom namespace pattern must match the namespace configured in your AgentCore Memory strategy. At startup, the library validates that the configured pattern matches what's in AWS. If there's a mismatch, the application will fail to start with a clear error message.

Available placeholders:

  • {memoryStrategyId} - The strategy ID
  • {actorId} - The user/actor ID
  • {sessionId} - The session ID (required for session-scoped patterns)

Note: Only these predefined placeholders are supported. Custom placeholders are not allowed.

Defaults Summary

Strategy top-k scope
semantic 3 ACTOR
user-preference n/a (lists all) ACTOR
summary 3 SESSION
episodic episodes: 3, reflections: 2 ACTOR

Set enabled: true to activate LTM, then configure individual strategies. Each strategy is optional - only configure the ones you need. Advisors are auto-created for configured strategies. Set enabled: false to temporarily disable all LTM without removing strategy configuration.

Conversation ID Format

The repository supports flexible conversation ID formats:

  • Simple: user123 → actor: user123, session: default-session
  • With Session: user123:session456 → actor: user123, session: session456

Error Handling

Messages with non-dialogue roles (e.g. ToolResponseMessage, system messages) are skipped with a WARN log line rather than persisted, since they are point-in-time facts that should not be replayed from conversation history. This is the only behaviour in 1.1.x and will be hardcoded in the next major.

The legacy agentcore.memory[.short-term].ignore-unknown-roles property is deprecated in 1.1.0 (@Deprecated(since = "1.1.0", forRemoval = true)); setting it logs a deprecation warning at startup and will be removed in the next major. See issue #109.

All AWS SDK exceptions are wrapped in AgentCoreMemoryException.

API Reference

ChatMemoryRepository

List<Message> findByConversationId(String conversationId);
void saveAll(String conversationId, List<Message> messages);
void deleteByConversationId(String conversationId);

Configuration Properties

Property Type Default Description
agentcore.memory.memory-id String null AgentCore Memory ID (required, shared with LTM)
agentcore.memory.short-term.total-events-limit Integer null Context window size
agentcore.memory.short-term.default-session String "default-session" Default session
agentcore.memory.short-term.page-size Integer 100 API pagination size
agentcore.memory.short-term.ignore-unknown-roles Boolean true Deprecated (since 1.1.0, for removal). Skipping non-dialogue messages will become hardcoded — see #109

Supported Message Types

Spring AI Message AgentCore Role
UserMessage USER
AssistantMessage ASSISTANT
SystemMessage Filtered ⚠️
ToolResponseMessage Filtered ⚠️

Performance

  • Page Size: Adjust agentcore.memory.short-term.page-size based on typical conversation length
  • Total Limit: Use agentcore.memory.short-term.total-events-limit to control context window size
  • Logging: Set org.springaicommunity.agentcore.memory: DEBUG for detailed logs

Troubleshooting

  1. Memory ID not found: Verify AGENTCORE_MEMORY_MEMORY_ID environment variable

  2. AWS Permissions: Required:

    • bedrock-agentcore:ListEvents
    • bedrock-agentcore:CreateEvent
    • bedrock-agentcore:DeleteEvent
    • bedrock-agentcore:RetrieveMemoryRecords (for LTM)
  3. Debug logging:

    logging:
      level:
        org.springaicommunity.agentcore.memory: DEBUG

Requirements

  • Java 17+
  • Spring Boot 4.x
  • Spring AI 2.0.0+

Testing

See the Build & Test and Integration Test Environment Variables sections in AGENTS.md for testing instructions.

License

Apache License 2.0