Skip to content

Conversation

sundargthb
Copy link
Contributor

@sundargthb sundargthb commented Sep 24, 2025

  • Integrate AgentCore Memory Manager for STM and LTM configuration
  • Add memory type selection prompt during agent configuration
  • Implement automatic memory resource creation with appropriate strategies
  • Support both short-term memory (30-day retention) and long-term memory extraction
  • Pass memory configuration to container runtime via environment variables
  • Handle idempotent memory operations for existing resources

Description

This PR integrates AWS Bedrock AgentCore Memory into the CLI toolkit, enabling automatic provisioning of both short-term memory (STM) and long-term memory (LTM) capabilities for agents. Users can now seamlessly enable memory features during agent configuration without manual API calls.

Changes

  • Configuration Phase: Added memory type selection prompt in configure.py allowing users to choose between STM-only or STM+LTM
  • Launch Phase: Integrated MemoryManager from operations/memory to automatically provision memory resources
  • Strategy Management: Automatic creation of three LTM strategies when enabled:
    • User Preferences (/users/{actorId}/preferences)
    • Semantic Facts (/users/{actorId}/facts)
    • Session Summaries (/summaries/{actorId}/{sessionId})
  • Environment Integration: Memory ID and configuration passed to container runtime

Usage

agentcore configure --entrypoint my_agent.py  # Prompts for memory configuration
agentcore launch                               # Automatically provisions memory
agentcore invoke '{"prompt": "Hello"}'         # Agent has memory capabilities

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • [X ] New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Testing

  • [X ] Unit tests pass locally
  • [X ] Integration tests pass (if applicable)
  • [x ] Test coverage remains above 80%
  • [ x] Manual testing completed

Checklist

  • [x ] My code follows the project's style guidelines (ruff/pre-commit)
  • [x ] I have performed a self-review of my own code
  • [x ] I have commented my code, particularly in hard-to-understand areas
  • [] I have made corresponding changes to the documentation
  • [x ] My changes generate no new warnings
  • [x ] I have added tests that prove my fix is effective or that my feature works
  • [x ] New and existing unit tests pass locally with my changes
  • [x ] Any dependent changes have been merged and published

Security Checklist

  • [x ] No hardcoded secrets or credentials
  • [x ] No new security warnings from bandit
  • [x ] Dependencies are from trusted sources
  • [x ] No sensitive data logged

Breaking Changes

List any breaking changes and migration instructions:

N/A

Additional Notes

Add any additional notes or context about the PR here.

- Integrate AgentCore Memory Manager for STM and LTM configuration
- Add memory type selection prompt during agent configuration
- Implement automatic memory resource creation with appropriate strategies
- Support both short-term memory (30-day retention) and long-term memory extraction
- Pass memory configuration to container runtime via environment variables
- Handle idempotent memory operations for existing resources
Sundar Raghavan added 3 commits September 25, 2025 06:16
Remove blocking wait for LTM strategy provisioning during launch
Use batch strategy updates to reduce provisioning time from ~3 minutes to seconds
Add memory provisioning status to agentcore status command
Fix status panel formatting with proper newline characters
Use async memory creation for faster agent deployment
Remove blocking wait for LTM strategy provisioning during launch
Use batch strategy updates to reduce provisioning time from ~3 minutes to seconds
Add memory provisioning status to agentcore status command
Fix status panel formatting with proper newline characters
Use async memory creation for faster agent deployment
class MemoryConfig(BaseModel):
"""Memory configuration for BedrockAgentCore."""

enabled: bool = Field(default=False, description="Whether memory is enabled")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we enable memory by default? also does this mean short-term memory (event/conversation history) or long-term memory (extraction of memory records from short-term memory)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see there is also enable_ltm -- I think this is confusing to have both controls. Instead, this argument should be an enum like STM_AND_LTM or STM_ONLY or NO_MEMORY (to have LTM, you must have STM)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

short term memory is enabled by default. User will be given a choice to enable LTM - that will be Yes/No - If yes, both STM and LTM - I can clarify the verbiage in setup

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the enabled + enable_ltm boolean combo with a single enum-style field using Literal types (STM_ONLY, STM_AND_LTM, NO_MEMORY)


# Create memory config
memory_config = MemoryConfig()
memory_config.enabled = True # Always true for STM

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as below about using enums and having only one input

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the enabled + enable_ltm boolean combo with a single enum-style field using Literal types (STM_ONLY, STM_AND_LTM, NO_MEMORY)

Comment on lines +11 to +12
BEDROCK_AGENTCORE_MEMORY_ID={{ memory_id }}{% endif %}{% if memory_name %} \
BEDROCK_AGENTCORE_MEMORY_NAME={{ memory_name }}{% endif %}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we give the user some easier affordance for setting this up? Like can we (or do we) prompt the user to provide these? Or, better yet, could we call ListMemories and let the user choose and then assist them in creating a memory if there isn't a memory in the list?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - this is planned as a fast follow up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed this implementation - Users can choose memory id from the List of memories.

Returns:
Tuple of (enable_memory, enable_ltm)
"""
console.print("\\n🧠 [cyan]Memory Configuration[/cyan]")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


⚠️  ℹ️  No container engine found (Docker/Finch/Podman not installed)
✅ Default deployment uses CodeBuild (no container engine needed)
💡 Run 'agentcore launch' for cloud-based building and deployment
💡 For local builds, install Docker, Finch, or Podman
\n🧠 Memory Configuration
✓ Short-term memory is enabled by default

this \n is extra

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will fix this

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still need this :)

# Use private method to avoid waiting
memory = memory_manager._create_memory(
name=memory_name,
description=f"Memory for agent {agent_name} with {'STM+LTM' if strategies else 'STM only'}",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure where to leave this comment, but in agentcore status

 ➜ agentcore status
✅ MemoryManager initialized for region: us-east-1
╭────────────────────────────────────────────────────────────────────────── Agent Status: my_agent ──────────────────────────────────────────────────────────────────────────╮
│ Ready - Agent deployed and endpoint available                                                                                                                              │
│                                                                                                                                                                            │
│ Agent Details:                                                                                                                                                             │
│ Agent Name: my_agent                                                                                                                                                       │
│ Agent ARN: arn:aws:bedrock-agentcore:us-east-1:332634280070:runtime/my_agent-SnemZt47u5                                                                                    │
│ Endpoint: DEFAULT (READY)                                                                                                                                                  │
│ Region: us-east-1 | Account: 332634280070                                                                                                                                  │
│                                                                                                                                                                            │
│ Memory: STM+LTM (3 strategies) (bedrock_agentcore_my_agent_memory-J7Aosv7Rh7)                                                                                              │
│                                                                                                                                                                            │
│ Deployment Info:                                                                                                                                                           │
│ Created: 2025-09-26 17:50:16.300812+00:00                                                                                                                                  │
│ Last Updated: 2025-09-26 17:50:17.515972+00:00                                                                                                                             │
│                                                                                                                                                                            │
│ 📋 CloudWatch Logs:                                                                                                                                                        │
│    /aws/bedrock-agentcore/runtimes/my_agent-SnemZt47u5-DEFAULT --log-stream-name-prefix "2025/09/26/[runtime-logs]"                                                        │
│    /aws/bedrock-agentcore/runtimes/my_agent-SnemZt47u5-DEFAULT --log-stream-names "otel-rt-logs"                                                                           │
│                                                                                                                                                                            │
│ 🔍 GenAI Observability Dashboard:                                                                                                                                          │
│    https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#gen-ai-observability/agent-core                                                                         │
│                                                                                                                                                                            │
│ ⏱️  Note: Observability data may take up to 10 minutes to appear after first launch                                                                                         │
│                                                                                                                                                                            │
│ 💡 Tail logs with:                                                                                                                                                         │
│    aws logs tail /aws/bedrock-agentcore/runtimes/my_agent-SnemZt47u5-DEFAULT --log-stream-name-prefix "2025/09/26/[runtime-logs]" --follow                                 │
│    aws logs tail /aws/bedrock-agentcore/runtimes/my_agent-SnemZt47u5-DEFAULT --log-stream-name-prefix "2025/09/26/[runtime-logs]" --since 1h                               │
│                                                                                                                                                                            │
│ Ready to invoke:                                                                                                                                                           │
│    agentcore invoke '{"prompt": "Hello"}'                                                                                                                                  │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

we need more details about the memory resource

│ Memory: STM+LTM (3 strategies) (bedrock_agentcore_my_agent_memory-J7Aosv7Rh7)

we should render all the fields that are on the memory resource here. Should be pretty straightforward to just get an LLM to do that imo

Addresses PR review comments:
- Replace boolean flags (enabled/enable_ltm) with single Literal enum type
  (STM_ONLY, STM_AND_LTM, NO_MEMORY) for clearer memory mode configuration
- Add ListMemories integration in configure flow allowing users to select
  existing memory resources or create new ones with guided prompts
- Enhance agentcore status output to display comprehensive memory resource
  details including all fields, strategies, namespaces, and provisioning status
return False, False

# If memory is enabled, ask about long-term memory
console.print("\\n[dim]Long-term memory extracts:[/dim]")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the \n a typo here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, updated this

return self._prompt_new_memory_config()

memory_manager = MemoryManager(region_name=region)
existing_memories = memory_manager.list_memories(max_results=10)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in a follow up, would be nice to figure out how to list all for pre-selection (like maybe exposed via a search or displayed in 3 columns with the full names truncated)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

else:
log.debug("No execution role provided and auto-create disabled")

# Prompt for memory configuration BEFORE generating Dockerfile

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this commented out code be here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. updated this

Comment on lines 568 to 606
# Create memory if configured
if agent_config.memory and not agent_config.memory.memory_id:
log.info("Creating memory resource for agent: %s", agent_name)
try:
from ...operations.memory.constants import StrategyType
from ...operations.memory.manager import MemoryManager

memory_manager = MemoryManager(region_name=agent_config.aws.region)
memory_name = f"bedrock_agentcore_{agent_name}_memory"

# Check if memory already exists
existing_memory = None
try:
memories = memory_manager.list_memories()
for m in memories:
if m.id.startswith(memory_name):
existing_memory = memory_manager.get_memory(m.id)
log.info("Found existing memory: %s", m.id)
break
except Exception as e:
log.debug("Error checking for existing memory: %s", e)

# Determine if we need to create new memory or add strategies to existing
if existing_memory:
# Check if strategies need to be added
existing_strategies = []
if hasattr(existing_memory, "strategies") and existing_memory.strategies:
existing_strategies = existing_memory.strategies

log.info("Existing memory has %d strategies", len(existing_strategies))

# If LTM is enabled but no strategies exist, add them
if agent_config.memory.has_ltm and len(existing_strategies) == 0:
log.info("Adding LTM strategies to existing memory...")

# Add all strategies in one batch call
memory_manager.update_memory_strategies_and_wait(
memory_id=existing_memory.id,
add_strategies=[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reuse same logic across code-build and non code-build functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted all memory creation logic into a single _ensure_memory_for_agent() helper function at the top of launch.py. Both CodeBuild and non-CodeBuild paths now call this one function.

entrypoint_path = Path(entrypoint_parts[0])
agent_var_name = entrypoint_parts[1] if len(entrypoint_parts) > 1 else agent_name

runtime.generate_dockerfile(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should generate Dockerfile with launch. This should also be dine with non code build launch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the Dockerfile regeneration in _launch_with_codebuild(). Memory env vars now passed purely at runtime via environmentVariables in the agent deployment call. The _deploy_to_bedrock_agentcore() function already handles this injection

agent_arn=agent_config.bedrock_agentcore.agent_arn,
)

if agent_config.memory and agent_config.memory.memory_id:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memory specific method for status.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed status.py to use MemoryManager's dedicated methods instead of raw dictionary access:

get_memory_status(memory_id) - returns status string with proper error handling
get_memory() - returns memory metadata
get_memory_strategies(memory_id) - handles field name variations (strategies vs memoryStrategies)


## Prerequisites

- **AWS Permissions:** You need specific permissions to use the starter toolkit. See the [Permissions Reference](#permissions-reference) section for the complete IAM policy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highlight that if developer is using root user/admins permissions then these steps are not required.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Comment on lines 102 to 114
if memory['status'] != 'ACTIVE':
agent = Agent(
model=MODEL_ID,
system_prompt="You are a helpful assistant.",
tools=[calculate]
)
result = agent(payload.get("prompt", ""))
return {
"response": f"[Memory initializing] {result.message.get('content', [{}])[0].get('text', '')}",
"session_id": "temp"
}
except Exception:
pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completed

Key components in this implementation:

- **Runtime**: Container orchestration service that hosts your agent
- **Memory Service**: Dual-layer storage with STM (exact conversation storage) and LTM (intelligent fact extraction)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does more than fact extraction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated to mention all strategies.


Key components in this implementation:

- **Runtime**: Container orchestration service that hosts your agent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its not an orchestration service. Use descriptions for each aligned aws docs and add those refs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated this.

memory_config = AgentCoreMemoryConfig(
memory_id=MEMORY_ID,
session_id=session_id,
actor_id="user",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not use env var for user?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed to update this in the latest version w/ streaming.. updated this now

# "You work at TechCorp."
```

### Test Code Interpreter with Memory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is memory important for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

originally had this testing with different session ids.. removed it

project_config = load_config(config_path)
agent_config = project_config.get_agent_config(agent_name)

# Check memory status on first invoke if LTM is enabled
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not reuse the status method with status.py instead? seems duplicate logic across invoke and status.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invoke.py needs a single lightweight check: "Is memory ready or should I fail gracefully?" Adding a dependency on status.py would add 2+ API calls per invoke (agent runtime, endpoint, strategies) and couple invoke logic to CLI display formatting

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have a method that can serve both?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that will work but needs some design considerations.. right now - invoke.py needs: “Is memory ready?” (boolean, 1 API call). and status.py needs: “Full memory diagnostics” (rich object, 4 API calls).. creating a shared method with a flag like get_memory_info(full_diagnostics=True/False) will returns different types..

Comment on lines 77 to 78
code_session_id = code_interpreter.start(
name="calc_session",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use same as runtime session id? That would avoid potential crosswiring across multiple sessions/users within an account.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right.. now uses runtime session id

Copy link
Contributor

@Vivekbhadauria1 Vivekbhadauria1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets follow up on -

  1. Streaming
  2. Memory status simplification
  3. Strands documentation links in sample

- **Runtime**: Managed compute service that runs your containerized agent with automatic scaling. See [AgentCore Runtime docs](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/agents-tools-runtime.html)
- **Memory Service**: Dual-layer storage with short-term memory (chronological event storage with 30-day retention) and long-term memory (extraction of user preferences, semantic facts, and session summaries). See [AgentCore Memory docs](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/memory.html)
- **Code Interpreter**: AWS-managed Python sandbox with pre-installed libraries. See [AgentCore Code Interpreter](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/code-interpreter-tool.html)
- **Strands Framework**: Simplifies agent creation with memory session management
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ref for this and the description is not correct.

@sundargthb sundargthb merged commit d58b61c into main Sep 30, 2025
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants