Skip to content

Commit c98db79

Browse files
committed
Refactor OpenMemory Sample to Use get_fast_api_app with URI Scheme
1 parent 3b4ebda commit c98db79

4 files changed

Lines changed: 103 additions & 23 deletions

File tree

contributing/samples/open_memory/README.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,24 @@ OPENMEMORY_BASE_URL=http://localhost:8080
4444

4545
## Usage
4646

47-
The sample provides an agent definition that you can use programmatically. The agent includes memory tools and auto-save functionality.
47+
### Option 1: Using `get_fast_api_app` with URI (Recommended - Easiest)
48+
49+
The simplest way to use this sample is to run the included `main.py`:
50+
51+
```bash
52+
python main.py
53+
```
54+
55+
The `main.py` file demonstrates how to:
56+
- Register the OpenMemory service factory for the `openmemory://` URI scheme
57+
- Use the `openmemory://` URI scheme with `get_fast_api_app`
58+
- Build the URI from environment variables
59+
60+
**Note:** The `adk web` CLI command won't work directly with this sample because it doesn't automatically register the OpenMemory service factory. You must use `main.py` which handles the registration.
61+
62+
### Option 2: Using `Runner` Directly
63+
64+
For programmatic usage, you can use `Runner` with OpenMemory service directly:
4865

4966
```python
5067
from google.adk_community.memory import OpenMemoryService, OpenMemoryServiceConfig
@@ -87,10 +104,21 @@ memory_service = OpenMemoryService(
87104
)
88105
```
89106

107+
## Sample Structure
108+
109+
```
110+
open_memory/
111+
├── main.py # FastAPI server using get_fast_api_app (Option 1)
112+
├── open_memory_agent/
113+
│ ├── __init__.py # Agent package initialization
114+
│ └── agent.py # Agent definition with memory tools
115+
└── README.md # This file
116+
```
117+
90118
## Sample Agent
91119

92-
The sample agent (`agent.py`) includes:
93-
- Memory tools (`load_memory_tool`, `preload_memory_tool`) for retrieving past conversations
120+
The sample agent (`open_memory_agent/agent.py`) includes:
121+
- Memory tools (`load_memory`, `preload_memory`) for retrieving past conversations
94122
- Auto-save callback that saves sessions to memory after each agent turn
95123
- Time context for the agent to use current time in responses
96124

@@ -104,6 +132,12 @@ Then in a new session
104132

105133
## Configuration Options
106134

135+
### OpenMemory URI Format
136+
137+
When using `get_fast_api_app` (Option 1), you can use the `openmemory://` URI scheme:
138+
139+
- `openmemory://localhost:8080` - API key must be set via `OPENMEMORY_API_KEY` environment variable
140+
107141
### OpenMemoryServiceConfig
108142

109143
- `search_top_k` (int, default: 10): Maximum memories to retrieve per search
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Example of using OpenMemory with get_fast_api_app."""
16+
17+
import os
18+
import uvicorn
19+
from dotenv import load_dotenv
20+
from fastapi import FastAPI
21+
from urllib.parse import urlparse
22+
from google.adk.cli.fast_api import get_fast_api_app
23+
from google.adk.cli.service_registry import get_service_registry
24+
from google.adk_community.memory import OpenMemoryService
25+
26+
# Load environment variables from .env file if it exists
27+
load_dotenv()
28+
29+
# Register OpenMemory service factory for openmemory:// URI scheme
30+
def openmemory_factory(uri: str, **kwargs):
31+
parsed = urlparse(uri)
32+
location = parsed.netloc + parsed.path
33+
base_url = location if location.startswith(('http://', 'https://')) else f'http://{location}'
34+
api_key = os.getenv('OPENMEMORY_API_KEY', '')
35+
if not api_key:
36+
raise ValueError("OpenMemory API key required. Set OPENMEMORY_API_KEY environment variable.")
37+
return OpenMemoryService(base_url=base_url, api_key=api_key)
38+
39+
get_service_registry().register_memory_service("openmemory", openmemory_factory)
40+
41+
# Build OpenMemory URI from environment variables (API key comes from env var)
42+
base_url = os.getenv('OPENMEMORY_BASE_URL', 'http://localhost:8080').replace('http://', '').replace('https://', '')
43+
MEMORY_SERVICE_URI = f"openmemory://{base_url}"
44+
45+
# Allowed origins for CORS
46+
ALLOWED_ORIGINS = ["*"]
47+
48+
# Create the FastAPI app using get_fast_api_app
49+
app: FastAPI = get_fast_api_app(
50+
agents_dir=".",
51+
memory_service_uri=MEMORY_SERVICE_URI,
52+
allow_origins=ALLOWED_ORIGINS,
53+
web=True,
54+
)
55+
56+
if __name__ == '__main__':
57+
# Use the PORT environment variable provided by Cloud Run, defaulting to 8000
58+
port = int(os.environ.get('PORT', 8000))
59+
uvicorn.run(app, host='0.0.0.0', port=port)
60+
File renamed without changes.

contributing/samples/open_memory/agent.py renamed to contributing/samples/open_memory/open_memory_agent/agent.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,25 @@
1414

1515

1616
from datetime import datetime
17-
1817
from google.adk import Agent
1918
from google.adk.agents.callback_context import CallbackContext
20-
from google.adk.tools.load_memory_tool import load_memory_tool
21-
from google.adk.tools.preload_memory_tool import preload_memory_tool
19+
from google.adk.tools import load_memory, preload_memory
2220

2321

2422
def update_current_time(callback_context: CallbackContext):
2523
callback_context.state['_time'] = datetime.now().isoformat()
2624

27-
28-
async def auto_save_session_to_memory_callback(callback_context: CallbackContext):
29-
"""Auto-saves the current session to memory after each agent turn.
30-
31-
Since there's no automatic save (saves only happen when the PATCH /memory endpoint
32-
is called), this callback is a simple workaround for testing that saves memories
33-
after each agent turn.
34-
"""
35-
if callback_context._invocation_context.memory_service:
36-
await callback_context._invocation_context.memory_service.add_session_to_memory(
37-
callback_context._invocation_context.session)
38-
39-
4025
root_agent = Agent(
4126
model='gemini-2.5-flash',
4227
name='open_memory_agent',
43-
description='agent that has access to memory tools with OpenMemory.',
28+
description='agent that has access to memory tools with OpenMemory via get_fast_api_app.',
4429
before_agent_callback=update_current_time,
45-
after_agent_callback=auto_save_session_to_memory_callback,
4630
instruction=(
4731
'You are an agent that helps user answer questions. You have access to memory tools.\n'
48-
'You can use the memory tools to look up the information in the memory. Current time: {_time}'
32+
'When the user asks a question you do not know the answer to, you MUST use the load_memory tool to search for relevant information from past conversations.\n'
33+
'If the first search does not find relevant information, try different search terms or keywords related to the question.\n'
34+
'Current time: {_time}'
4935
),
50-
tools=[load_memory_tool, preload_memory_tool],
36+
tools=[preload_memory, load_memory],
5137
)
5238

0 commit comments

Comments
 (0)