bedrock-agentcore-starter-toolkit 0.1.3__py3-none-any.whl → 0.1.5__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 (27) hide show
  1. bedrock_agentcore_starter_toolkit/cli/__init__.py +1 -0
  2. bedrock_agentcore_starter_toolkit/cli/cli.py +2 -0
  3. bedrock_agentcore_starter_toolkit/cli/import_agent/README.md +35 -0
  4. bedrock_agentcore_starter_toolkit/cli/import_agent/__init__.py +1 -0
  5. bedrock_agentcore_starter_toolkit/cli/import_agent/agent_info.py +230 -0
  6. bedrock_agentcore_starter_toolkit/cli/import_agent/commands.py +518 -0
  7. bedrock_agentcore_starter_toolkit/operations/gateway/client.py +2 -2
  8. bedrock_agentcore_starter_toolkit/services/__init__.py +1 -0
  9. bedrock_agentcore_starter_toolkit/services/import_agent/__init__.py +1 -0
  10. bedrock_agentcore_starter_toolkit/services/import_agent/assets/memory_manager_template.py +207 -0
  11. bedrock_agentcore_starter_toolkit/services/import_agent/assets/requirements_langchain.j2 +9 -0
  12. bedrock_agentcore_starter_toolkit/services/import_agent/assets/requirements_strands.j2 +5 -0
  13. bedrock_agentcore_starter_toolkit/services/import_agent/assets/template_fixtures_merged.json +1102 -0
  14. bedrock_agentcore_starter_toolkit/services/import_agent/scripts/__init__.py +1 -0
  15. bedrock_agentcore_starter_toolkit/services/import_agent/scripts/base_bedrock_translate.py +1668 -0
  16. bedrock_agentcore_starter_toolkit/services/import_agent/scripts/bedrock_to_langchain.py +382 -0
  17. bedrock_agentcore_starter_toolkit/services/import_agent/scripts/bedrock_to_strands.py +374 -0
  18. bedrock_agentcore_starter_toolkit/services/import_agent/utils.py +417 -0
  19. bedrock_agentcore_starter_toolkit/services/runtime.py +13 -2
  20. bedrock_agentcore_starter_toolkit/utils/runtime/templates/Dockerfile.j2 +1 -1
  21. bedrock_agentcore_starter_toolkit/utils/runtime/templates/execution_role_policy.json.j2 +2 -1
  22. {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.5.dist-info}/METADATA +22 -2
  23. {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.5.dist-info}/RECORD +27 -11
  24. {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.5.dist-info}/WHEEL +0 -0
  25. {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.5.dist-info}/entry_points.txt +0 -0
  26. {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.5.dist-info}/licenses/LICENSE.txt +0 -0
  27. {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.5.dist-info}/licenses/NOTICE.txt +0 -0
@@ -0,0 +1,207 @@
1
+ # pylint: disable=line-too-long
2
+ """Long Term Memory Manager for generated agents.
3
+
4
+ This module provides a custom memory manager that mimics the functionality of Bedrock Agents
5
+ Long Term Memory and Sessions.
6
+ """
7
+
8
+ import asyncio
9
+ import json
10
+ import os
11
+ import weakref
12
+ from datetime import datetime
13
+ from typing import Any, Dict, List, Set
14
+
15
+
16
+ class LongTermMemoryManager:
17
+ """Custom Memory Manager to have equivalent functionality with Bedrock Agents Long Term Memory and Sessions."""
18
+
19
+ # Class variable to keep track of all instances
20
+ _instances: Set[weakref.ref] = set()
21
+
22
+ def __init__(
23
+ self,
24
+ llm_summarizer,
25
+ storage_path: str = "output",
26
+ max_sessions: int = 10,
27
+ summarization_prompt: str = None,
28
+ max_days: int = 30,
29
+ platform: str = "langchain",
30
+ ):
31
+ """Initialize the LongTermMemoryManager."""
32
+ self.llm_summarizer = llm_summarizer
33
+ self.storage_path = storage_path
34
+ self.max_sessions = max_sessions
35
+ self.max_days = max_days
36
+ self.current_session_messages = []
37
+ self.summarization_prompt = summarization_prompt
38
+ self._last_memory_update_time = 0
39
+ self.platform = platform
40
+ self._session_ended = False # Track if this instance has ended its session
41
+
42
+ self.session_summaries = self._load_session_summaries()
43
+
44
+ # Register this instance in the class-level instances set
45
+ self._instances.add(weakref.ref(self, self._cleanup_reference))
46
+
47
+ @staticmethod
48
+ def _cleanup_reference(ref):
49
+ """Callback for when a weak reference is removed."""
50
+ LongTermMemoryManager._instances.discard(ref)
51
+
52
+ def _load_session_summaries(self) -> List[Dict[str, Any]]:
53
+ """Load all stored session summaries."""
54
+ summary_file = self.storage_path
55
+ if os.path.exists(summary_file):
56
+ with open(summary_file, "r") as f:
57
+ return json.load(f)
58
+ return []
59
+
60
+ def _save_session_summaries(self):
61
+ summary_file = self.storage_path
62
+ with open(summary_file, "a+", encoding="utf-8") as f:
63
+ f.truncate(0)
64
+ json.dump(self.session_summaries, f)
65
+ self._last_memory_update_time = datetime.now().timestamp()
66
+
67
+ def add_message(self, message: Dict[str, str]):
68
+ """Add a message to the current session."""
69
+ self.current_session_messages.append(message)
70
+
71
+ def _generate_session_summary(self) -> str:
72
+ try:
73
+ conversation_str = "\n\n".join(
74
+ [f"{msg['role'].capitalize()}: {msg['content']}" for msg in self.current_session_messages]
75
+ )
76
+
77
+ past_summaries = "\n".join([summary["summary"] for summary in self.session_summaries])
78
+
79
+ summarization_prompt = self.summarization_prompt.replace(
80
+ "$past_conversation_summary$", past_summaries
81
+ ).replace("$conversation$", conversation_str)
82
+
83
+ if self.platform == "langchain":
84
+ summary_response = self.llm_summarizer.invoke(summarization_prompt).content
85
+ else:
86
+
87
+ def inference(model, messages, system_prompt=""):
88
+ async def run_inference():
89
+ results = []
90
+ async for event in model.stream(messages=messages, system_prompt=system_prompt):
91
+ results.append(event)
92
+ return results
93
+
94
+ response = asyncio.run(run_inference())
95
+
96
+ text = ""
97
+ for chunk in response:
98
+ if "contentBlockDelta" not in chunk:
99
+ continue
100
+ text += chunk["contentBlockDelta"].get("delta", {}).get("text", "")
101
+
102
+ return text
103
+
104
+ summary_response = inference(
105
+ self.llm_summarizer, messages=[{"role": "user", "content": [{"text": summarization_prompt}]}]
106
+ )
107
+
108
+ return summary_response
109
+ except Exception as e:
110
+ print(f"Error generating summary: {str(e)}")
111
+ message = self.current_session_messages[-1]["content"] if self.current_session_messages else "No messages"
112
+ return f"Session summary generation failed. Last message: {message}"
113
+
114
+ @classmethod
115
+ def _cleanup_instance(cls):
116
+ """Remove dead references from the instances set."""
117
+ cls._instances = {ref for ref in cls._instances if ref() is not None}
118
+
119
+ @classmethod
120
+ def get_active_instances_count(cls):
121
+ """Return the number of active memory manager instances."""
122
+ # Clean up any dead references first
123
+ cls._instances = {ref for ref in cls._instances if ref() is not None}
124
+ return len(cls._instances)
125
+
126
+ @classmethod
127
+ def get_active_instances(cls):
128
+ """Return a list of all active memory manager instances."""
129
+ # Clean up any dead references first
130
+ cls._instances = {ref for ref in cls._instances if ref() is not None}
131
+ return [ref() for ref in cls._instances if ref() is not None]
132
+
133
+ @classmethod
134
+ def end_all_sessions(cls):
135
+ """End sessions for all active memory manager instances.
136
+
137
+ This is a convenience method that can be called from anywhere to end all sessions.
138
+ """
139
+ instances = cls.get_active_instances()
140
+ if instances:
141
+ instances[0].end_session()
142
+
143
+ def end_session(self):
144
+ """End the current session and trigger end_session for all other instances.
145
+
146
+ This ensures that when one agent ends its session, all other agents do the same.
147
+ """
148
+ # Prevent recursive calls
149
+ if self._session_ended:
150
+ return
151
+
152
+ self._session_ended = True
153
+
154
+ # Process this instance's session
155
+ if self.current_session_messages:
156
+ summary = self._generate_session_summary()
157
+ session_summary = {"timestamp": datetime.now().isoformat(), "summary": summary}
158
+ self.session_summaries.append(session_summary)
159
+
160
+ self.session_summaries = [
161
+ summary
162
+ for summary in self.session_summaries
163
+ if (
164
+ datetime.fromisoformat(session_summary["timestamp"]) - datetime.fromisoformat(summary["timestamp"])
165
+ ).days
166
+ <= self.max_days
167
+ ]
168
+
169
+ if len(self.session_summaries) > self.max_sessions:
170
+ self.session_summaries = self.session_summaries[-self.max_sessions :]
171
+
172
+ self._save_session_summaries()
173
+
174
+ self.current_session_messages = []
175
+
176
+ # End sessions for all other instances
177
+ for instance_ref in list(self._instances):
178
+ instance = instance_ref()
179
+ if instance is not None and instance is not self and not instance._session_ended:
180
+ try:
181
+ instance.end_session()
182
+ except Exception as e:
183
+ print(f"Error ending session for another instance: {str(e)}")
184
+
185
+ # Reset the flag so this instance can be used again if needed
186
+ self._session_ended = False
187
+
188
+ def get_memory_synopsis(self) -> str:
189
+ """Get a synopsis of the memory, including all session summaries."""
190
+ return "\n".join([summary["summary"] for summary in self.session_summaries])
191
+
192
+ def has_memory_changed(self) -> bool:
193
+ """Check if the memory has changed since the last update."""
194
+ summary_file = self.storage_path
195
+
196
+ if not os.path.exists(summary_file):
197
+ return False
198
+
199
+ current_mtime = os.path.getmtime(summary_file)
200
+ if current_mtime != self._last_memory_update_time:
201
+ self._last_memory_update_time = current_mtime
202
+ return True
203
+ return False
204
+
205
+ def clear_current_session(self):
206
+ """Clear the current session messages."""
207
+ self.current_session_messages = []
@@ -0,0 +1,9 @@
1
+ bedrock-agentcore
2
+ bedrock-agentcore-starter-toolkit
3
+ langchain
4
+ langchain-aws
5
+ langchain-community
6
+ langchain-mcp-adapters
7
+ langgraph
8
+ inputimeout
9
+ opentelemetry-instrumentation-langchain
@@ -0,0 +1,5 @@
1
+ bedrock-agentcore
2
+ bedrock-agentcore-starter-toolkit
3
+ strands-agents
4
+ strands-agents-tools
5
+ inputimeout