bedrock-agentcore-starter-toolkit 0.1.14__py3-none-any.whl → 0.1.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bedrock-agentcore-starter-toolkit might be problematic. Click here for more details.

Files changed (29) hide show
  1. bedrock_agentcore_starter_toolkit/cli/runtime/commands.py +33 -2
  2. bedrock_agentcore_starter_toolkit/cli/runtime/configuration_manager.py +127 -1
  3. bedrock_agentcore_starter_toolkit/operations/memory/README.md +1109 -0
  4. bedrock_agentcore_starter_toolkit/operations/memory/constants.py +1 -9
  5. bedrock_agentcore_starter_toolkit/operations/memory/manager.py +248 -57
  6. bedrock_agentcore_starter_toolkit/operations/memory/models/__init__.py +106 -0
  7. bedrock_agentcore_starter_toolkit/operations/memory/models/strategies/__init__.py +52 -0
  8. bedrock_agentcore_starter_toolkit/operations/memory/models/strategies/base.py +77 -0
  9. bedrock_agentcore_starter_toolkit/operations/memory/models/strategies/custom.py +194 -0
  10. bedrock_agentcore_starter_toolkit/operations/memory/models/strategies/semantic.py +35 -0
  11. bedrock_agentcore_starter_toolkit/operations/memory/models/strategies/summary.py +35 -0
  12. bedrock_agentcore_starter_toolkit/operations/memory/models/strategies/user_preference.py +34 -0
  13. bedrock_agentcore_starter_toolkit/operations/memory/strategy_validator.py +395 -0
  14. bedrock_agentcore_starter_toolkit/operations/runtime/configure.py +54 -0
  15. bedrock_agentcore_starter_toolkit/operations/runtime/destroy.py +43 -3
  16. bedrock_agentcore_starter_toolkit/operations/runtime/invoke.py +45 -0
  17. bedrock_agentcore_starter_toolkit/operations/runtime/launch.py +164 -0
  18. bedrock_agentcore_starter_toolkit/operations/runtime/models.py +7 -0
  19. bedrock_agentcore_starter_toolkit/operations/runtime/status.py +62 -0
  20. bedrock_agentcore_starter_toolkit/utils/runtime/container.py +4 -0
  21. bedrock_agentcore_starter_toolkit/utils/runtime/schema.py +27 -1
  22. bedrock_agentcore_starter_toolkit/utils/runtime/templates/Dockerfile.j2 +9 -2
  23. bedrock_agentcore_starter_toolkit/utils/runtime/templates/execution_role_policy.json.j2 +31 -0
  24. {bedrock_agentcore_starter_toolkit-0.1.14.dist-info → bedrock_agentcore_starter_toolkit-0.1.15.dist-info}/METADATA +1 -1
  25. {bedrock_agentcore_starter_toolkit-0.1.14.dist-info → bedrock_agentcore_starter_toolkit-0.1.15.dist-info}/RECORD +29 -20
  26. {bedrock_agentcore_starter_toolkit-0.1.14.dist-info → bedrock_agentcore_starter_toolkit-0.1.15.dist-info}/WHEEL +0 -0
  27. {bedrock_agentcore_starter_toolkit-0.1.14.dist-info → bedrock_agentcore_starter_toolkit-0.1.15.dist-info}/entry_points.txt +0 -0
  28. {bedrock_agentcore_starter_toolkit-0.1.14.dist-info → bedrock_agentcore_starter_toolkit-0.1.15.dist-info}/licenses/LICENSE.txt +0 -0
  29. {bedrock_agentcore_starter_toolkit-0.1.14.dist-info → bedrock_agentcore_starter_toolkit-0.1.15.dist-info}/licenses/NOTICE.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  """Constants for Bedrock AgentCore Memory SDK."""
2
2
 
3
3
  from enum import Enum
4
- from typing import Dict, List, Optional
4
+ from typing import Optional
5
5
 
6
6
 
7
7
  class StrategyType(Enum):
@@ -88,11 +88,3 @@ class MemoryStrategyStatus(Enum):
88
88
  ACTIVE = "ACTIVE"
89
89
  DELETING = "DELETING"
90
90
  FAILED = "FAILED"
91
-
92
-
93
- # Default namespaces for each strategy type
94
- DEFAULT_NAMESPACES: Dict[StrategyType, List[str]] = {
95
- StrategyType.SEMANTIC: ["/actor/{actorId}/strategy/{strategyId}/{sessionId}"],
96
- StrategyType.SUMMARY: ["/actor/{actorId}/strategy/{strategyId}/{sessionId}"],
97
- StrategyType.USER_PREFERENCE: ["/actor/{actorId}/strategy/{strategyId}"],
98
- }
@@ -4,16 +4,19 @@ import copy
4
4
  import logging
5
5
  import time
6
6
  import uuid
7
- import warnings
8
- from typing import Any, Dict, List, Optional
7
+ from typing import Any, Dict, List, Optional, Union
9
8
 
10
9
  import boto3
10
+ from botocore.config import Config as BotocoreConfig
11
11
  from botocore.exceptions import ClientError
12
12
 
13
- from .constants import DEFAULT_NAMESPACES, MemoryStatus, MemoryStrategyStatus, OverrideType, StrategyType
13
+ from .constants import MemoryStatus, MemoryStrategyStatus, OverrideType, StrategyType
14
+ from .models import convert_strategies_to_dicts
14
15
  from .models.Memory import Memory
15
16
  from .models.MemoryStrategy import MemoryStrategy
16
17
  from .models.MemorySummary import MemorySummary
18
+ from .models.strategies import BaseStrategy
19
+ from .strategy_validator import validate_existing_memory_strategies
17
20
 
18
21
  logger = logging.getLogger(__name__)
19
22
 
@@ -24,14 +27,52 @@ class MemoryManager:
24
27
  This class handles all CONTROL PLANE CRUD operations.
25
28
  """
26
29
 
27
- def __init__(self, region_name: str):
30
+ def __init__(
31
+ self,
32
+ region_name: Optional[str] = None,
33
+ boto3_session: Optional[boto3.Session] = None,
34
+ boto_client_config: Optional[BotocoreConfig] = None,
35
+ ):
28
36
  """Initialize MemoryManager with AWS region.
29
37
 
30
38
  Args:
31
- region_name: AWS region name for the bedrock-agentcore-control client.
39
+ region_name: AWS region for the bedrock-agentcore-control client. If not provided,
40
+ will use the region from boto3_session or default session.
41
+ boto3_session: Optional boto3 Session to use. If provided and region_name
42
+ parameter is also specified, validation will ensure they match.
43
+ boto_client_config: Optional boto3 client configuration. If provided, will be
44
+ merged with default configuration including user agent.
45
+
46
+ Raises:
47
+ ValueError: If region_name parameter conflicts with boto3_session region.
32
48
  """
49
+ session = boto3_session or boto3.Session()
50
+ session_region = session.region_name
51
+
52
+ # Validate region consistency if both are provided
53
+ if region_name and boto3_session and session_region and region_name != session_region:
54
+ raise ValueError(
55
+ f"Region mismatch: provided region_name '{region_name}' does not match "
56
+ f"boto3_session region '{session_region}'. Please ensure both "
57
+ f"parameters specify the same region or omit the region_name parameter "
58
+ f"to use the session's region."
59
+ )
60
+
61
+ # Configure boto3 client with merged configuration
62
+ if boto_client_config:
63
+ existing_user_agent = getattr(boto_client_config, "user_agent_extra", None)
64
+ if existing_user_agent:
65
+ new_user_agent = f"{existing_user_agent} bedrock-agentcore-starter-toolkit"
66
+ else:
67
+ new_user_agent = "bedrock-agentcore-starter-toolkit"
68
+ client_config = boto_client_config.merge(BotocoreConfig(user_agent_extra=new_user_agent))
69
+ else:
70
+ client_config = BotocoreConfig(user_agent_extra="bedrock-agentcore-starter-toolkit")
71
+
33
72
  self.region_name = region_name
34
- self._control_plane_client = boto3.client("bedrock-agentcore-control", region_name=region_name)
73
+ self._control_plane_client = session.client(
74
+ "bedrock-agentcore-control", region_name=self.region_name, config=client_config
75
+ )
35
76
 
36
77
  # AgentCore Memory control plane methods
37
78
  self._ALLOWED_CONTROL_PLANE_METHODS = {
@@ -153,6 +194,7 @@ class MemoryManager:
153
194
  description: Optional[str] = None,
154
195
  event_expiry_days: int = 90,
155
196
  memory_execution_role_arn: Optional[str] = None,
197
+ encryption_key_arn: Optional[str] = None,
156
198
  ) -> Memory:
157
199
  """Create a memory resource and return the raw response.
158
200
 
@@ -162,12 +204,10 @@ class MemoryManager:
162
204
  strategies = []
163
205
 
164
206
  try:
165
- processed_strategies = self._add_default_namespaces(strategies)
166
-
167
207
  params = {
168
208
  "name": name,
169
209
  "eventExpiryDuration": event_expiry_days,
170
- "memoryStrategies": processed_strategies,
210
+ "memoryStrategies": strategies,
171
211
  "clientToken": str(uuid.uuid4()),
172
212
  }
173
213
 
@@ -177,6 +217,9 @@ class MemoryManager:
177
217
  if memory_execution_role_arn is not None:
178
218
  params["memoryExecutionRoleArn"] = memory_execution_role_arn
179
219
 
220
+ if encryption_key_arn is not None:
221
+ params["encryptionKeyArn"] = encryption_key_arn
222
+
180
223
  response = self._control_plane_client.create_memory(**params)
181
224
 
182
225
  memory = response["memory"]
@@ -193,12 +236,13 @@ class MemoryManager:
193
236
  def _create_memory_and_wait(
194
237
  self,
195
238
  name: str,
196
- strategies: List[Dict[str, Any]],
239
+ strategies: Optional[List[Dict[str, Any]]],
197
240
  description: Optional[str] = None,
198
241
  event_expiry_days: int = 90,
199
242
  memory_execution_role_arn: Optional[str] = None,
200
243
  max_wait: int = 300,
201
244
  poll_interval: int = 10,
245
+ encryption_key_arn: Optional[str] = None,
202
246
  ) -> Memory:
203
247
  """Create a memory and wait for it to become ACTIVE.
204
248
 
@@ -213,6 +257,7 @@ class MemoryManager:
213
257
  memory_execution_role_arn: IAM role ARN for memory execution
214
258
  max_wait: Maximum seconds to wait (default: 300)
215
259
  poll_interval: Seconds between status checks (default: 10)
260
+ encryption_key_arn: kms key ARN for encryption
216
261
 
217
262
  Returns:
218
263
  Created memory object in ACTIVE status
@@ -228,6 +273,7 @@ class MemoryManager:
228
273
  description=description,
229
274
  event_expiry_days=event_expiry_days,
230
275
  memory_execution_role_arn=memory_execution_role_arn,
276
+ encryption_key_arn=encryption_key_arn,
231
277
  )
232
278
 
233
279
  memory_id = memory.id
@@ -264,20 +310,64 @@ class MemoryManager:
264
310
  def create_memory_and_wait(
265
311
  self,
266
312
  name: str,
267
- strategies: List[Dict[str, Any]],
313
+ strategies: Optional[List[Union[BaseStrategy, Dict[str, Any]]]] = None,
268
314
  description: Optional[str] = None,
269
315
  event_expiry_days: int = 90,
270
316
  memory_execution_role_arn: Optional[str] = None,
317
+ encryption_key_arn: Optional[str] = None,
271
318
  max_wait: int = 300,
272
319
  poll_interval: int = 10,
273
320
  ) -> Memory:
274
- """Create a memory and wait for it to become ACTIVE - public method."""
321
+ """Create a memory and wait for it to become ACTIVE - public method.
322
+
323
+ Args:
324
+ name: Name for the memory resource
325
+ strategies: List of typed strategy objects or dictionary configurations
326
+ description: Optional description
327
+ event_expiry_days: How long to retain events (default: 90 days)
328
+ memory_execution_role_arn: IAM role ARN for memory execution
329
+ max_wait: Maximum seconds to wait (default: 300)
330
+ poll_interval: Seconds between status checks (default: 10)
331
+ encryption_key_arn: kms key ARN for encryption
332
+
333
+ Returns:
334
+ Created memory object in ACTIVE status
335
+
336
+ Example:
337
+ from bedrock_agentcore_starter_toolkit.operations.memory.models import (
338
+ SemanticStrategy, CustomSemanticStrategy, ExtractionConfig, ConsolidationConfig
339
+ )
340
+
341
+ # Create typed strategies
342
+ semantic = SemanticStrategy(name="MySemanticStrategy")
343
+ custom = CustomSemanticStrategy(
344
+ name="MyCustomStrategy",
345
+ extraction_config=ExtractionConfig(
346
+ append_to_prompt="Extract insights",
347
+ model_id="anthropic.claude-3-sonnet-20240229-v1:0"
348
+ ),
349
+ consolidation_config=ConsolidationConfig(
350
+ append_to_prompt="Consolidate insights",
351
+ model_id="anthropic.claude-3-haiku-20240307-v1:0"
352
+ )
353
+ )
354
+
355
+ # Create memory with typed strategies
356
+ memory = manager.create_memory_and_wait(
357
+ name="TypedMemory",
358
+ strategies=[semantic, custom]
359
+ )
360
+ """
361
+ # Convert typed strategies to dicts for internal processing
362
+ dict_strategies = convert_strategies_to_dicts(strategies) if strategies else None
363
+
275
364
  return self._create_memory_and_wait(
276
365
  name=name,
277
- strategies=strategies,
366
+ strategies=dict_strategies,
278
367
  description=description,
279
368
  event_expiry_days=event_expiry_days,
280
369
  memory_execution_role_arn=memory_execution_role_arn,
370
+ encryption_key_arn=encryption_key_arn,
281
371
  max_wait=max_wait,
282
372
  poll_interval=poll_interval,
283
373
  )
@@ -285,15 +375,37 @@ class MemoryManager:
285
375
  def get_or_create_memory(
286
376
  self,
287
377
  name: str,
288
- strategies: Optional[List[Dict[str, Any]]] = None,
378
+ strategies: Optional[List[Union[BaseStrategy, Dict[str, Any]]]] = None,
289
379
  description: Optional[str] = None,
290
380
  event_expiry_days: int = 90,
291
381
  memory_execution_role_arn: Optional[str] = None,
382
+ encryption_key_arn: Optional[str] = None,
292
383
  ) -> Memory:
293
384
  """Fetch an existing memory resource or create the memory.
294
385
 
386
+ Args:
387
+ name: Memory name
388
+ strategies: Optional List of typed strategy objects or dictionary configurations
389
+ description: Optional description
390
+ event_expiry_days: How long to retain events (default: 90 days)
391
+ memory_execution_role_arn: IAM role ARN for memory execution
392
+ encryption_key_arn: kms key ARN for encryption
393
+
295
394
  Returns:
296
395
  Memory object, either newly created or existing
396
+
397
+ Raises:
398
+ ValueError: If strategies are provided but existing memory has different strategies
399
+
400
+ Example:
401
+ from bedrock_agentcore_starter_toolkit.operations.memory.models import SemanticStrategy
402
+
403
+ # Create with typed strategy
404
+ semantic = SemanticStrategy(name="MyStrategy")
405
+ memory = manager.get_or_create_memory(
406
+ name="MyMemory",
407
+ strategies=[semantic]
408
+ )
297
409
  """
298
410
  memory: Memory = None
299
411
  try:
@@ -302,16 +414,27 @@ class MemoryManager:
302
414
 
303
415
  # Create Memory if it doesn't exist
304
416
  if memory_summary is None:
417
+ # Convert typed strategies to dicts for internal processing
418
+ dict_strategies = convert_strategies_to_dicts(strategies) if strategies else None
419
+
305
420
  memory = self._create_memory_and_wait(
306
421
  name=name,
307
- strategies=strategies,
422
+ strategies=dict_strategies,
308
423
  description=description,
309
424
  event_expiry_days=event_expiry_days,
310
425
  memory_execution_role_arn=memory_execution_role_arn,
426
+ encryption_key_arn=encryption_key_arn,
311
427
  )
312
428
  else:
313
429
  logger.info("Memory already exists. Using existing memory ID: %s", memory_summary.id)
314
430
  memory = self.get_memory(memory_summary.id)
431
+
432
+ # Validate strategies if provided using deep comparison
433
+ if strategies is not None:
434
+ existing_strategies = memory.get("strategies", memory.get("memoryStrategies", []))
435
+ memory_name = memory.get("name")
436
+ validate_existing_memory_strategies(existing_strategies, strategies, memory_name)
437
+
315
438
  return memory
316
439
  except ClientError as e:
317
440
  # Failed to create memory
@@ -470,7 +593,7 @@ class MemoryManager:
470
593
  if namespaces:
471
594
  strategy[StrategyType.SEMANTIC.value]["namespaces"] = namespaces
472
595
 
473
- return self._add_strategy(memory_id, strategy)
596
+ return self.add_strategy(memory_id, strategy)
474
597
 
475
598
  def add_semantic_strategy_and_wait(
476
599
  self,
@@ -514,7 +637,7 @@ class MemoryManager:
514
637
  if namespaces:
515
638
  strategy[StrategyType.SUMMARY.value]["namespaces"] = namespaces
516
639
 
517
- return self._add_strategy(memory_id, strategy)
640
+ return self.add_strategy(memory_id, strategy)
518
641
 
519
642
  def add_summary_strategy_and_wait(
520
643
  self,
@@ -551,7 +674,7 @@ class MemoryManager:
551
674
  if namespaces:
552
675
  strategy[StrategyType.USER_PREFERENCE.value]["namespaces"] = namespaces
553
676
 
554
- return self._add_strategy(memory_id, strategy)
677
+ return self.add_strategy(memory_id, strategy)
555
678
 
556
679
  def add_user_preference_strategy_and_wait(
557
680
  self,
@@ -610,7 +733,7 @@ class MemoryManager:
610
733
  if namespaces:
611
734
  strategy[StrategyType.CUSTOM.value]["namespaces"] = namespaces
612
735
 
613
- return self._add_strategy(memory_id, strategy)
736
+ return self.add_strategy(memory_id, strategy)
614
737
 
615
738
  def add_custom_semantic_strategy_and_wait(
616
739
  self,
@@ -656,17 +779,38 @@ class MemoryManager:
656
779
  def update_memory_strategies(
657
780
  self,
658
781
  memory_id: str,
659
- add_strategies: Optional[List[Dict[str, Any]]] = None,
782
+ add_strategies: Optional[List[Union[BaseStrategy, Dict[str, Any]]]] = None,
660
783
  modify_strategies: Optional[List[Dict[str, Any]]] = None,
661
784
  delete_strategy_ids: Optional[List[str]] = None,
662
785
  ) -> Memory:
663
- """Update memory strategies - add, modify, or delete."""
786
+ """Update memory strategies - add, modify, or delete.
787
+
788
+ Args:
789
+ memory_id: Memory resource ID
790
+ add_strategies: List of typed strategy objects or dictionaries to add
791
+ modify_strategies: List of strategy modification dictionaries
792
+ delete_strategy_ids: List of strategy IDs to delete
793
+
794
+ Returns:
795
+ Updated Memory object
796
+
797
+ Example:
798
+ from bedrock_agentcore_starter_toolkit.operations.memory.models import SemanticStrategy
799
+
800
+ # Add typed strategy
801
+ semantic = SemanticStrategy(name="NewStrategy")
802
+ memory = manager.update_memory_strategies(
803
+ memory_id="mem-123",
804
+ add_strategies=[semantic]
805
+ )
806
+ """
664
807
  try:
665
808
  memory_strategies = {}
666
809
 
667
810
  if add_strategies:
668
- processed_add = self._add_default_namespaces(add_strategies)
669
- memory_strategies["addMemoryStrategies"] = processed_add
811
+ # Convert typed strategies to dicts for internal processing
812
+ dict_strategies = convert_strategies_to_dicts(add_strategies)
813
+ memory_strategies["addMemoryStrategies"] = dict_strategies
670
814
 
671
815
  if modify_strategies:
672
816
  current_strategies = self.get_memory_strategies(memory_id)
@@ -722,7 +866,7 @@ class MemoryManager:
722
866
  def update_memory_strategies_and_wait(
723
867
  self,
724
868
  memory_id: str,
725
- add_strategies: Optional[List[Dict[str, Any]]] = None,
869
+ add_strategies: Optional[List[Union[BaseStrategy, Dict[str, Any]]]] = None,
726
870
  modify_strategies: Optional[List[Dict[str, Any]]] = None,
727
871
  delete_strategy_ids: Optional[List[str]] = None,
728
872
  max_wait: int = 300,
@@ -732,6 +876,27 @@ class MemoryManager:
732
876
 
733
877
  This method handles the temporary CREATING state that occurs when
734
878
  updating strategies, preventing subsequent update errors.
879
+
880
+ Args:
881
+ memory_id: Memory resource ID
882
+ add_strategies: List of typed strategy objects or dictionaries to add
883
+ modify_strategies: List of strategy modification dictionaries
884
+ delete_strategy_ids: List of strategy IDs to delete
885
+ max_wait: Maximum seconds to wait (default: 300)
886
+ poll_interval: Seconds between checks (default: 10)
887
+
888
+ Returns:
889
+ Updated Memory object in ACTIVE state
890
+
891
+ Example:
892
+ from bedrock_agentcore_starter_toolkit.operations.memory.models import SummaryStrategy
893
+
894
+ # Add typed strategy and wait
895
+ summary = SummaryStrategy(name="NewSummaryStrategy")
896
+ memory = manager.update_memory_strategies_and_wait(
897
+ memory_id="mem-123",
898
+ add_strategies=[summary]
899
+ )
735
900
  """
736
901
  # Update strategies
737
902
  self.update_memory_strategies(memory_id, add_strategies, modify_strategies, delete_strategy_ids)
@@ -739,31 +904,77 @@ class MemoryManager:
739
904
  # Wait for memory to return to ACTIVE
740
905
  return self._wait_for_memory_active(memory_id, max_wait, poll_interval)
741
906
 
742
- def add_strategy(self, memory_id: str, strategy: Dict[str, Any]) -> Memory:
907
+ def add_strategy(self, memory_id: str, strategy: Union[BaseStrategy, Dict[str, Any]]) -> Memory:
743
908
  """Add a strategy to a memory (without waiting).
744
909
 
745
910
  WARNING: After adding a strategy, the memory enters CREATING state temporarily.
746
- Use add_*_strategy_and_wait() methods instead to avoid errors.
911
+ Use add_strategy_and_wait() method instead to avoid errors.
747
912
 
748
913
  Args:
749
914
  memory_id: Memory resource ID
750
- strategy: Strategy configuration dictionary
915
+ strategy: Typed strategy object or dictionary configuration
751
916
 
752
917
  Returns:
753
918
  Updated memory response
754
- """
755
- warnings.warn(
756
- "add_strategy() may leave memory in CREATING state. "
757
- "Use add_*_strategy_and_wait() methods to avoid subsequent errors.",
758
- UserWarning,
759
- stacklevel=2,
760
- )
761
- return self._add_strategy(memory_id, strategy)
762
919
 
763
- def _add_strategy(self, memory_id: str, strategy: Dict[str, Any]) -> Memory:
764
- """Internal method to add a single strategy."""
920
+ Example:
921
+ from bedrock_agentcore_starter_toolkit.operations.memory.models.semantic import SemanticStrategy
922
+
923
+ # Using typed strategy (recommended)
924
+ semantic = SemanticStrategy(name="MyStrategy", description="Test")
925
+ memory = manager.add_strategy(memory_id="mem-123", strategy=semantic)
926
+
927
+ # Using dictionary (legacy support)
928
+ strategy_dict = {"semanticMemoryStrategy": {"name": "MyStrategy"}}
929
+ memory = manager.add_strategy(memory_id="mem-123", strategy=strategy_dict)
930
+ """
765
931
  return self.update_memory_strategies(memory_id=memory_id, add_strategies=[strategy])
766
932
 
933
+ def add_strategy_and_wait(
934
+ self,
935
+ memory_id: str,
936
+ strategy: Union[BaseStrategy, Dict[str, Any]],
937
+ max_wait: int = 300,
938
+ poll_interval: int = 10,
939
+ ) -> Memory:
940
+ """Add a strategy to a memory and wait for it to return to ACTIVE state.
941
+
942
+ Args:
943
+ memory_id: Memory resource ID
944
+ strategy: Typed strategy object or dictionary configuration
945
+ max_wait: Maximum seconds to wait (default: 300)
946
+ poll_interval: Seconds between status checks (default: 10)
947
+
948
+ Returns:
949
+ Updated memory response in ACTIVE state
950
+
951
+ Example:
952
+ from bedrock_agentcore_starter_toolkit.operations.memory.models.strategies import (
953
+ SemanticStrategy, CustomSemanticStrategy, ExtractionConfig, ConsolidationConfig
954
+ )
955
+
956
+ # Using typed strategy (recommended)
957
+ semantic = SemanticStrategy(name="MyStrategy", description="Test")
958
+ memory = manager.add_strategy_and_wait(memory_id="mem-123", strategy=semantic)
959
+
960
+ # Using custom strategy with configurations
961
+ custom = CustomSemanticStrategy(
962
+ name="CustomStrategy",
963
+ extraction_config=ExtractionConfig(
964
+ append_to_prompt="Extract insights",
965
+ model_id="anthropic.claude-3-sonnet-20240229-v1:0"
966
+ ),
967
+ consolidation_config=ConsolidationConfig(
968
+ append_to_prompt="Consolidate insights",
969
+ model_id="anthropic.claude-3-haiku-20240307-v1:0"
970
+ )
971
+ )
972
+ memory = manager.add_strategy_and_wait(memory_id="mem-123", strategy=custom)
973
+ """
974
+ return self.update_memory_strategies_and_wait(
975
+ memory_id=memory_id, add_strategies=[strategy], max_wait=max_wait, poll_interval=poll_interval
976
+ )
977
+
767
978
  def _check_strategies_terminal_state(self, strategies: List[Dict[str, Any]]) -> tuple[bool, List[str], List[str]]:
768
979
  """Check if all strategies are in terminal states.
769
980
 
@@ -851,26 +1062,6 @@ class MemoryManager:
851
1062
  % (memory_id, max_wait)
852
1063
  )
853
1064
 
854
- def _add_default_namespaces(self, strategies: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
855
- """Add default namespaces to strategies that don't have them."""
856
- processed = []
857
-
858
- for strategy in strategies:
859
- strategy_copy = copy.deepcopy(strategy)
860
-
861
- strategy_type_key = list(strategy.keys())[0]
862
- strategy_config = strategy_copy[strategy_type_key]
863
-
864
- if "namespaces" not in strategy_config:
865
- strategy_type = StrategyType(strategy_type_key)
866
- strategy_config["namespaces"] = DEFAULT_NAMESPACES.get(strategy_type, ["custom/{actorId}/{sessionId}"])
867
-
868
- self._validate_strategy_config(strategy_copy, strategy_type_key)
869
-
870
- processed.append(strategy_copy)
871
-
872
- return processed
873
-
874
1065
  def _validate_namespace(self, namespace: str) -> bool:
875
1066
  """Validate namespace format - basic check only."""
876
1067
  # Only check for template variables in namespace definition
@@ -0,0 +1,106 @@
1
+ """Bedrock AgentCore Memory Models.
2
+
3
+ This module provides strongly typed models for memory operations,
4
+ including memory resources, strategies, and configurations.
5
+
6
+ Example:
7
+ # Import strategy classes
8
+ from bedrock_agentcore_starter_toolkit.operations.memory.models import (
9
+ SemanticStrategy,
10
+ SummaryStrategy,
11
+ CustomSemanticStrategy,
12
+ ExtractionConfig,
13
+ ConsolidationConfig
14
+ )
15
+
16
+ # Create typed strategies
17
+ semantic_strategy = SemanticStrategy(
18
+ name="ConversationSemantics",
19
+ description="Extract semantic information",
20
+ namespaces=["semantics/{actorId}/{sessionId}"]
21
+ )
22
+
23
+ custom_strategy = CustomSemanticStrategy(
24
+ name="CustomExtraction",
25
+ extraction_config=ExtractionConfig(
26
+ append_to_prompt="Extract key insights",
27
+ model_id="anthropic.claude-3-sonnet-20240229-v1:0"
28
+ ),
29
+ consolidation_config=ConsolidationConfig(
30
+ append_to_prompt="Consolidate insights",
31
+ model_id="anthropic.claude-3-haiku-20240307-v1:0"
32
+ )
33
+ )
34
+ """
35
+
36
+ # Memory resource models
37
+ from typing import Any, Dict, List
38
+
39
+ from .Memory import Memory
40
+ from .MemoryStrategy import MemoryStrategy
41
+ from .MemorySummary import MemorySummary
42
+
43
+ # Strategy models
44
+ from .strategies import (
45
+ BaseStrategy,
46
+ ConsolidationConfig,
47
+ CustomSemanticStrategy,
48
+ ExtractionConfig,
49
+ SemanticStrategy,
50
+ StrategyType,
51
+ SummaryStrategy,
52
+ UserPreferenceStrategy,
53
+ )
54
+
55
+
56
+ def convert_strategies_to_dicts(strategies: List[StrategyType]) -> List[Dict[str, Any]]:
57
+ """Convert mixed strategy types to dictionary format for API calls.
58
+
59
+ This function handles both new typed strategies and legacy dictionary
60
+ strategies, ensuring backward compatibility.
61
+
62
+ Args:
63
+ strategies: List of strategy objects (typed or dict)
64
+
65
+ Returns:
66
+ List of strategy dictionaries compatible with the API
67
+
68
+ Raises:
69
+ ValueError: If an invalid strategy type is provided
70
+
71
+ Example:
72
+ strategies = [
73
+ SemanticStrategy(name="Test"),
74
+ {"semanticMemoryStrategy": {"name": "Legacy"}}
75
+ ]
76
+ dicts = convert_strategies_to_dicts(strategies)
77
+ """
78
+ result = []
79
+ for strategy in strategies:
80
+ if isinstance(strategy, BaseStrategy):
81
+ result.append(strategy.to_dict())
82
+ elif isinstance(strategy, dict):
83
+ result.append(strategy) # Backward compatibility
84
+ else:
85
+ raise ValueError(f"Invalid strategy type: {type(strategy)}. Expected BaseStrategy or dict.")
86
+ return result
87
+
88
+
89
+ __all__ = [
90
+ # Memory models
91
+ "Memory",
92
+ "MemorySummary",
93
+ "MemoryStrategy",
94
+ # Strategy base classes and types
95
+ "BaseStrategy",
96
+ "StrategyType",
97
+ "ExtractionConfig",
98
+ "ConsolidationConfig",
99
+ # Strategy models
100
+ "SemanticStrategy",
101
+ "SummaryStrategy",
102
+ "UserPreferenceStrategy",
103
+ "CustomSemanticStrategy",
104
+ # Utility functions
105
+ "convert_strategies_to_dicts",
106
+ ]
@@ -0,0 +1,52 @@
1
+ """Memory strategy models and configurations.
2
+
3
+ This module provides strongly typed strategy classes for creating
4
+ memory strategies with full type safety and IDE support.
5
+
6
+ Example:
7
+ from bedrock_agentcore_starter_toolkit.operations.memory.models.strategies import (
8
+ SemanticStrategy,
9
+ CustomSemanticStrategy,
10
+ ExtractionConfig,
11
+ ConsolidationConfig
12
+ )
13
+
14
+ # Create typed strategies manually
15
+ semantic = SemanticStrategy(
16
+ name="MySemanticStrategy",
17
+ description="Extract key information"
18
+ )
19
+
20
+ custom = CustomSemanticStrategy(
21
+ name="MyCustomStrategy",
22
+ extraction_config=ExtractionConfig(
23
+ append_to_prompt="Extract insights",
24
+ model_id="anthropic.claude-3-sonnet-20240229-v1:0"
25
+ ),
26
+ consolidation_config=ConsolidationConfig(
27
+ append_to_prompt="Consolidate insights",
28
+ model_id="anthropic.claude-3-haiku-20240307-v1:0"
29
+ )
30
+ )
31
+ """
32
+
33
+ from .base import BaseStrategy, ConsolidationConfig, ExtractionConfig, StrategyType
34
+ from .custom import CustomSemanticStrategy, CustomSummaryStrategy, CustomUserPreferenceStrategy
35
+ from .semantic import SemanticStrategy
36
+ from .summary import SummaryStrategy
37
+ from .user_preference import UserPreferenceStrategy
38
+
39
+ __all__ = [
40
+ # Base classes and types
41
+ "BaseStrategy",
42
+ "StrategyType",
43
+ "ExtractionConfig",
44
+ "ConsolidationConfig",
45
+ # Concrete strategy classes
46
+ "SemanticStrategy",
47
+ "SummaryStrategy",
48
+ "UserPreferenceStrategy",
49
+ "CustomSemanticStrategy",
50
+ "CustomSummaryStrategy",
51
+ "CustomUserPreferenceStrategy",
52
+ ]