Skip to content

Commit 1348052

Browse files
sararobcopybara-github
authored andcommitted
fix: Update VertexAiRagMemoryService methods to use latest RAG module
PiperOrigin-RevId: 938567500
1 parent ad5445a commit 1348052

2 files changed

Lines changed: 70 additions & 48 deletions

File tree

src/google/adk/memory/vertex_ai_rag_memory_service.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,36 +90,56 @@ def _parse_source_display_name(
9090

9191

9292
class VertexAiRagMemoryService(BaseMemoryService):
93-
"""A memory service that uses Vertex AI RAG for storage and retrieval."""
93+
"""A memory service that uses Agent Platform RAG for storage and retrieval."""
9494

9595
def __init__(
9696
self,
9797
rag_corpus: Optional[str] = None,
9898
similarity_top_k: Optional[int] = None,
9999
vector_distance_threshold: float = 10,
100+
project: Optional[str] = None,
101+
location: Optional[str] = None,
100102
):
101103
"""Initializes a VertexAiRagMemoryService.
102104
103105
Args:
104-
rag_corpus: The name of the Vertex AI RAG corpus to use. Format:
106+
rag_corpus: The name of the Agent Platform RAG corpus to use. Format:
105107
``projects/{project}/locations/{location}/ragCorpora/{rag_corpus_id}``
106108
or ``{rag_corpus_id}``
107109
similarity_top_k: The number of contexts to retrieve.
108110
vector_distance_threshold: Only returns contexts with vector distance
109111
smaller than the threshold.
112+
project: The project to use for the Agent Platform RAG corpus. If not
113+
set, the value of the GOOGLE_CLOUD_PROJECT environment variable is
114+
used.
115+
location: The location to use for the Agent Platform RAG corpus. If not
116+
set, the value of the GOOGLE_CLOUD_LOCATION environment variable is
117+
used.
110118
"""
111119
try:
112-
import vertexai # noqa: F401
120+
import agentplatform # noqa: F401
113121
except ImportError as e:
114122
from ..utils._dependency import missing_extra
115123

116124
raise missing_extra("google-cloud-aiplatform", "gcp") from e
117125

126+
self._project = project or os.environ.get("GOOGLE_CLOUD_PROJECT")
127+
self._location = location or os.environ.get("GOOGLE_CLOUD_LOCATION")
128+
129+
# Fallback: if the fully-qualified corpus name is provided, use it to
130+
# determine the project and location, if they are not already set.
131+
if (not self._project or not self._location) and (
132+
rag_corpus and rag_corpus.startswith("projects/")
133+
):
134+
parts = rag_corpus.split("/")
135+
if len(parts) >= 4 and parts[0] == "projects" and parts[2] == "locations":
136+
self._project = self._project or parts[1]
137+
self._location = self._location or parts[3]
138+
118139
self._vertex_rag_store = types.VertexRagStore(
119140
rag_resources=[
120141
types.VertexRagStoreRagResource(rag_corpus=rag_corpus),
121142
],
122-
similarity_top_k=similarity_top_k,
123143
vector_distance_threshold=vector_distance_threshold,
124144
)
125145

@@ -153,14 +173,16 @@ async def add_session_to_memory(self, session: Session) -> None:
153173
if not self._vertex_rag_store.rag_resources:
154174
raise ValueError("Rag resources must be set.")
155175

156-
from ..dependencies.vertexai import rag
176+
import agentplatform
177+
178+
client = agentplatform.Client(
179+
project=self._project, location=self._location
180+
)
157181

158182
for rag_resource in self._vertex_rag_store.rag_resources:
159-
rag.upload_file(
183+
client.rag.upload_file(
160184
corpus_name=rag_resource.rag_corpus,
161185
path=temp_file_path,
162-
# this is the temp workaround as upload file does not support
163-
# adding metadata, thus use display_name to store the session info.
164186
display_name=_build_source_display_name(
165187
session.app_name, session.user_id, session.id
166188
),
@@ -173,17 +195,22 @@ async def search_memory(
173195
self, *, app_name: str, user_id: str, query: str
174196
) -> SearchMemoryResponse:
175197
"""Searches for sessions that match the query using rag.retrieval_query."""
176-
from ..dependencies.vertexai import rag
198+
import agentplatform
199+
from agentplatform import types as agentplatform_types
200+
177201
from ..events.event import Event
178202

179-
response = rag.retrieval_query(
180-
text=query,
181-
rag_resources=self._vertex_rag_store.rag_resources,
182-
rag_corpora=self._vertex_rag_store.rag_corpora,
183-
similarity_top_k=self._vertex_rag_store.similarity_top_k,
184-
vector_distance_threshold=self._vertex_rag_store.vector_distance_threshold,
203+
client = agentplatform.Client(
204+
project=self._project, location=self._location
185205
)
186206

207+
response = client.rag.retrieve_contexts(
208+
vertex_rag_store=self._vertex_rag_store,
209+
query=agentplatform_types.RagQuery(
210+
text=query,
211+
similarity_top_k=self._vertex_rag_store.similarity_top_k,
212+
),
213+
)
187214
memory_results = []
188215
session_events_map: OrderedDict[str, list[list[Event]]] = OrderedDict()
189216
for context in response.contexts.contexts:

tests/unittests/memory/test_vertex_ai_rag_memory_service.py

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,29 @@ def _rag_context(source_display_name: str, text: str) -> SimpleNamespace:
3535
async def test_search_memory_rejects_ambiguous_legacy_display_names(mocker):
3636
"""Ensures dotted user IDs cannot match another user's legacy memory."""
3737
memory_service = VertexAiRagMemoryService(rag_corpus="unused")
38-
fake_rag = SimpleNamespace(
39-
retrieval_query=mocker.Mock(
40-
return_value=SimpleNamespace(
41-
contexts=SimpleNamespace(
42-
contexts=[
43-
_rag_context(
44-
"demo.alice.smith.session_secret",
45-
"SECRET_FROM_ALICE_SMITH",
46-
),
47-
_rag_context(
48-
_build_source_display_name(
49-
"demo", "alice", "session_ok"
50-
),
51-
"NORMAL_ALICE_MEMORY",
52-
),
53-
_rag_context(
54-
"demo.alice.legacy_session",
55-
"LEGACY_ALICE_MEMORY",
56-
),
57-
_rag_context("demo.bob.session_other", "BOB_MEMORY"),
58-
]
59-
)
60-
)
38+
39+
fake_client = mocker.Mock()
40+
fake_client.rag.retrieve_contexts.return_value = SimpleNamespace(
41+
contexts=SimpleNamespace(
42+
contexts=[
43+
_rag_context(
44+
"demo.alice.smith.session_secret",
45+
"SECRET_FROM_ALICE_SMITH",
46+
),
47+
_rag_context(
48+
_build_source_display_name("demo", "alice", "session_ok"),
49+
"NORMAL_ALICE_MEMORY",
50+
),
51+
_rag_context(
52+
"demo.alice.legacy_session",
53+
"LEGACY_ALICE_MEMORY",
54+
),
55+
_rag_context("demo.bob.session_other", "BOB_MEMORY"),
56+
]
6157
)
6258
)
63-
mocker.patch("google.adk.dependencies.vertexai.rag", fake_rag)
59+
60+
mocker.patch("agentplatform.Client", return_value=fake_client)
6461

6562
response = await memory_service.search_memory(
6663
app_name="demo", user_id="alice", query="secret"
@@ -73,9 +70,9 @@ async def test_search_memory_rejects_ambiguous_legacy_display_names(mocker):
7370
@pytest.mark.asyncio
7471
async def test_add_and_search_memory_uses_unambiguous_display_names(mocker):
7572
memory_service = VertexAiRagMemoryService(rag_corpus="unused")
76-
upload_file = mocker.Mock()
77-
fake_rag = SimpleNamespace(upload_file=upload_file)
78-
mocker.patch("google.adk.dependencies.vertexai.rag", fake_rag)
73+
74+
fake_client = mocker.Mock()
75+
mocker.patch("agentplatform.Client", return_value=fake_client)
7976

8077
await memory_service.add_session_to_memory(
8178
Session(
@@ -96,15 +93,13 @@ async def test_add_and_search_memory_uses_unambiguous_display_names(mocker):
9693
)
9794
)
9895

99-
display_name = upload_file.call_args.kwargs["display_name"]
96+
display_name = fake_client.rag.upload_file.call_args.kwargs["display_name"]
10097
assert display_name.startswith(_SOURCE_DISPLAY_NAME_PREFIX)
10198
assert display_name != "demo.app.alice.smith.session.secret"
10299

103-
fake_rag.retrieval_query = mocker.Mock(
104-
return_value=SimpleNamespace(
105-
contexts=SimpleNamespace(
106-
contexts=[_rag_context(display_name, "sensitive memory")]
107-
)
100+
fake_client.rag.retrieve_contexts.return_value = SimpleNamespace(
101+
contexts=SimpleNamespace(
102+
contexts=[_rag_context(display_name, "sensitive memory")]
108103
)
109104
)
110105

0 commit comments

Comments
 (0)