-
Notifications
You must be signed in to change notification settings - Fork 17
Add OpenMemory service integration for ADK community #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b0a4a3b
Add OpenMemory service integration for ADK community
rakshith-git 1c31107
Update samples/open_memory/README.md
rakshith-git 29dbe6b
Update src/google/adk_community/memory/open_memory_service.py
rakshith-git 5d6cbc4
Create readme.md
hangfei 203736f
Rename samples/open_memory/README.md to contributing/samples/open_mem…
hangfei 662e3f0
Rename samples/open_memory/__init__.py to contributing/samples/open_m…
hangfei 15b3086
Rename samples/open_memory/agent.py to contributing/samples/open_memo…
hangfei 4c8bb47
Update README.md
hangfei File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| # OpenMemory Sample | ||
|
|
||
| This sample demonstrates how to use OpenMemory as a self-hosted memory backend | ||
| for ADK agents using the community package. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Python 3.9+ (Python 3.11+ recommended) | ||
| - Docker (for running OpenMemory) | ||
| - ADK and ADK Community installed | ||
|
|
||
| ## Setup | ||
|
|
||
| ### 1. Install Dependencies | ||
|
|
||
| ```bash | ||
| pip install google-adk google-adk-community | ||
| ``` | ||
|
|
||
| ### 2. Set Up OpenMemory Server | ||
|
|
||
| Follow the [OpenMemory Quick Start Guide](https://openmemory.cavira.app/docs/quick-start) to install and configure your OpenMemory server. | ||
|
|
||
| Once OpenMemory is running, you'll need: | ||
| - The OpenMemory server URL (default: `http://localhost:8080`) | ||
| - An API key for authentication by setting OM_API_KEY=<your-secret-api-key> (configured in your OpenMemory server) | ||
|
|
||
| ### 3. Configure Environment Variables for adk | ||
|
|
||
| Create a `.env` file in this directory : | ||
|
|
||
| ```bash | ||
| # Required: Google API key for the agent | ||
| GOOGLE_API_KEY=your-google-api-key | ||
|
|
||
| # Required: OpenMemory API key for authentication | ||
| OPENMEMORY_API_KEY=your-openmemory-api-key | ||
|
|
||
| # Optional: OpenMemory base URL (defaults to http://localhost:8080) | ||
| OPENMEMORY_BASE_URL=http://localhost:8080 | ||
| ``` | ||
|
|
||
| **Note:** `OPENMEMORY_API_KEY` is required for OpenMemory authentication. | ||
|
|
||
| ## Usage | ||
|
|
||
| The sample provides an agent definition that you can use programmatically. The agent includes memory tools and auto-save functionality. | ||
|
|
||
| ```python | ||
| from google.adk_community.memory import OpenMemoryService, OpenMemoryServiceConfig | ||
| from google.adk.runners import Runner | ||
|
|
||
| # Create OpenMemory service with API key (required) | ||
| memory_service = OpenMemoryService( | ||
| base_url="http://localhost:8080", # Adjust to match your OpenMemory server URL | ||
| api_key="your-api-key" # Required - get this from your OpenMemory server configuration | ||
| ) | ||
|
|
||
| # Use with runner | ||
| runner = Runner( | ||
| app_name="my_app", | ||
| agent=root_agent, | ||
| memory_service=memory_service | ||
| ) | ||
| ``` | ||
|
|
||
| ### Advanced Configuration | ||
|
|
||
| ```python | ||
| from google.adk_community.memory import OpenMemoryService, OpenMemoryServiceConfig | ||
|
|
||
| # Custom configuration | ||
| config = OpenMemoryServiceConfig( | ||
| search_top_k=20, # Retrieve more memories per query | ||
| timeout=10.0, # Faster timeout for production | ||
| user_content_salience=0.9, # Higher importance for user messages | ||
| model_content_salience=0.75, # Medium importance for model responses | ||
| enable_metadata_tags=True # Add tags (session, app, author) for filtering | ||
| # When enabled, memories are tagged with session ID, app name, | ||
| # and author, allowing search queries to filter by app name | ||
| ) | ||
|
|
||
| memory_service = OpenMemoryService( | ||
| base_url="http://localhost:8080", # Adjust to match your OpenMemory server URL | ||
| api_key="your-api-key", # Required - get this from your OpenMemory server configuration | ||
| config=config | ||
| ) | ||
| ``` | ||
|
|
||
| ## Sample Agent | ||
|
|
||
| The sample agent (`agent.py`) includes: | ||
| - Memory tools (`load_memory_tool`, `preload_memory_tool`) for retrieving past conversations | ||
| - Auto-save callback that saves sessions to memory after each agent turn | ||
| - Time context for the agent to use current time in responses | ||
|
|
||
| ## Configuration Options | ||
|
|
||
| ### OpenMemoryServiceConfig | ||
|
|
||
| - `search_top_k` (int, default: 10): Maximum memories to retrieve per search | ||
| - `timeout` (float, default: 30.0): HTTP request timeout in seconds | ||
| - `user_content_salience` (float, default: 0.8): Importance for user messages | ||
| - `model_content_salience` (float, default: 0.7): Importance for model responses | ||
| - `default_salience` (float, default: 0.6): Fallback importance value | ||
| - `enable_metadata_tags` (bool, default: True): Include tags for filtering. When enabled, | ||
| memories are tagged with `session:{session_id}`, `app:{app_name}`, and `author:{author}`. | ||
| These tags are used to filter search results by app name, improving isolation between | ||
| different applications using the same OpenMemory instance. | ||
|
|
||
| ## Features | ||
|
|
||
| OpenMemory provides: | ||
|
|
||
| - **Multi-sector embeddings**: Factual, emotional, temporal, relational memory | ||
| - **Graceful decay curves**: Automatic reinforcement keeps relevant context sharp | ||
| - **Self-hosted**: Full data ownership, no vendor lock-in | ||
| - **High performance**: 2-3× faster than hosted alternatives | ||
| - **Cost-effective**: 6-10× cheaper than SaaS memory APIs | ||
|
|
||
| ## Learn More | ||
|
|
||
| - [OpenMemory Documentation](https://openmemory.cavira.app/) | ||
| - [OpenMemory API Reference](https://openmemory.cavira.app/docs/api/add-memory) | ||
| - [ADK Memory Documentation](https://google.github.io/adk-docs) | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| from . import agent | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
|
|
||
| from datetime import datetime | ||
|
|
||
| from google.adk import Agent | ||
| from google.adk.agents.callback_context import CallbackContext | ||
| from google.adk.tools.load_memory_tool import load_memory_tool | ||
| from google.adk.tools.preload_memory_tool import preload_memory_tool | ||
|
|
||
|
|
||
| def update_current_time(callback_context: CallbackContext): | ||
| callback_context.state['_time'] = datetime.now().isoformat() | ||
|
|
||
|
|
||
| async def auto_save_session_to_memory_callback(callback_context: CallbackContext): | ||
| """Auto-saves the current session to memory after each agent turn. | ||
|
|
||
| Since there's no automatic save (saves only happen when the PATCH /memory endpoint | ||
| is called), this callback is a simple workaround for testing that saves memories | ||
| after each agent turn. | ||
| """ | ||
| if callback_context._invocation_context.memory_service: | ||
| await callback_context._invocation_context.memory_service.add_session_to_memory( | ||
| callback_context._invocation_context.session) | ||
|
|
||
|
|
||
| root_agent = Agent( | ||
| model='gemini-2.5-flash', | ||
| name='open_memory_agent', | ||
| description='agent that has access to memory tools with OpenMemory.', | ||
| before_agent_callback=update_current_time, | ||
| after_agent_callback=auto_save_session_to_memory_callback, | ||
| instruction=( | ||
| 'You are an agent that helps user answer questions. You have access to memory tools.\n' | ||
| 'You can use the memory tools to look up the information in the memory. Current time: {_time}' | ||
| ), | ||
| tools=[load_memory_tool, preload_memory_tool], | ||
| ) | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """Community memory services for ADK.""" | ||
|
|
||
| from .open_memory_service import OpenMemoryService | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's do lazy loading here. @wuliang229 to help provide some guidance on what's the proper way.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's do it in a separate PR. |
||
| from .open_memory_service import OpenMemoryServiceConfig | ||
|
|
||
| __all__ = [ | ||
| "OpenMemoryService", | ||
| "OpenMemoryServiceConfig", | ||
| ] | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.