Skip to content

Commit 6907f89

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
feat: Add filter_groups to PurgeMemories for metadata-based filtering
PiperOrigin-RevId: 867864418
1 parent 997fcdc commit 6907f89

3 files changed

Lines changed: 96 additions & 8 deletions

File tree

tests/unit/vertexai/genai/replays/test_purge_agent_engine_memories.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ def test_purge_memories(client):
4242
scope={"user_id": "456"},
4343
config={"wait_for_completion": True},
4444
)
45+
client.agent_engines.memories.create(
46+
name=agent_engine.api_resource.name,
47+
fact="memory_fact_4",
48+
scope={"user_id": "456"},
49+
config={
50+
"wait_for_completion": True,
51+
"metadata": {"my_key": {"string_value": "my_value"}},
52+
},
53+
)
4554
operation = client.agent_engines.memories.purge(
4655
name=agent_engine.api_resource.name,
4756
filter="scope.user_id=123",
@@ -58,7 +67,7 @@ def test_purge_memories(client):
5867
)
5968
)
6069
)
61-
== 3
70+
== 4
6271
)
6372
# Now, actually purge the memories.
6473
operation = client.agent_engines.memories.purge(
@@ -69,6 +78,29 @@ def test_purge_memories(client):
6978
)
7079
assert operation.done
7180
assert operation.response.purge_count == 2
81+
assert (
82+
len(
83+
list(
84+
client.agent_engines.memories.list(
85+
name=agent_engine.api_resource.name
86+
)
87+
)
88+
)
89+
== 2
90+
)
91+
# Purge memories using filter groups.
92+
operation = client.agent_engines.memories.purge(
93+
name=agent_engine.api_resource.name,
94+
force=True,
95+
filter_groups=[
96+
{"filters": [{"key": "my_key", "value": {"string_value": "my_value"}}]}
97+
],
98+
config={
99+
"wait_for_completion": True,
100+
},
101+
)
102+
assert operation.done
103+
assert operation.response.purge_count == 1
72104
assert (
73105
len(
74106
list(

vertexai/_genai/memories.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import json
2121
import logging
2222
import typing
23-
from typing import Any, Iterator, Optional, Union
23+
from typing import Any, Iterator, List, Optional, Union
2424
from urllib.parse import urlencode
2525

2626
from google.genai import _api_module
@@ -317,6 +317,13 @@ def _PurgeAgentEngineMemoriesRequestParameters_to_vertex(
317317
if getv(from_object, ["filter"]) is not None:
318318
setv(to_object, ["filter"], getv(from_object, ["filter"]))
319319

320+
if getv(from_object, ["filter_groups"]) is not None:
321+
setv(
322+
to_object,
323+
["filterGroups"],
324+
[item for item in getv(from_object, ["filter_groups"])],
325+
)
326+
320327
if getv(from_object, ["force"]) is not None:
321328
setv(to_object, ["force"], getv(from_object, ["force"]))
322329

@@ -1072,7 +1079,8 @@ def _purge(
10721079
self,
10731080
*,
10741081
name: str,
1075-
filter: str,
1082+
filter: Optional[str] = None,
1083+
filter_groups: Optional[list[types.MemoryConjunctionFilterOrDict]] = None,
10761084
force: Optional[bool] = None,
10771085
config: Optional[types.PurgeAgentEngineMemoriesConfigOrDict] = None,
10781086
) -> types.AgentEnginePurgeMemoriesOperation:
@@ -1083,6 +1091,7 @@ def _purge(
10831091
parameter_model = types._PurgeAgentEngineMemoriesRequestParameters(
10841092
name=name,
10851093
filter=filter,
1094+
filter_groups=filter_groups,
10861095
force=force,
10871096
config=config,
10881097
)
@@ -1384,7 +1393,8 @@ def purge(
13841393
self,
13851394
*,
13861395
name: str,
1387-
filter: str,
1396+
filter: Optional[str] = None,
1397+
filter_groups: Optional[List[types.MemoryConjunctionFilter]] = None,
13881398
force: bool = False,
13891399
config: Optional[types.PurgeAgentEngineMemoriesConfigOrDict] = None,
13901400
) -> types.AgentEnginePurgeMemoriesOperation:
@@ -1394,7 +1404,11 @@ def purge(
13941404
name (str):
13951405
Required. The name of the Agent Engine to purge memories from.
13961406
filter (str):
1397-
Required. The standard list filter to determine which memories to purge.
1407+
Optional. The standard list filter to determine which memories to purge.
1408+
filter_groups (list[MemoryConjunctionFilter]):
1409+
Optional. Metadata filters that will be applied to the memories'
1410+
`metadata` using OR logic. Filters are defined using disjunctive
1411+
normal form (OR of ANDs).
13981412
force (bool):
13991413
Optional. Whether to force the purge operation. If false, the
14001414
operation will be staged but not executed.
@@ -1412,6 +1426,7 @@ def purge(
14121426
operation = self._purge(
14131427
name=name,
14141428
filter=filter,
1429+
filter_groups=filter_groups,
14151430
force=force,
14161431
config=config,
14171432
)
@@ -2042,7 +2057,8 @@ async def _purge(
20422057
self,
20432058
*,
20442059
name: str,
2045-
filter: str,
2060+
filter: Optional[str] = None,
2061+
filter_groups: Optional[list[types.MemoryConjunctionFilterOrDict]] = None,
20462062
force: Optional[bool] = None,
20472063
config: Optional[types.PurgeAgentEngineMemoriesConfigOrDict] = None,
20482064
) -> types.AgentEnginePurgeMemoriesOperation:
@@ -2053,6 +2069,7 @@ async def _purge(
20532069
parameter_model = types._PurgeAgentEngineMemoriesRequestParameters(
20542070
name=name,
20552071
filter=filter,
2072+
filter_groups=filter_groups,
20562073
force=force,
20572074
config=config,
20582075
)
@@ -2356,7 +2373,8 @@ async def purge(
23562373
self,
23572374
*,
23582375
name: str,
2359-
filter: str,
2376+
filter: Optional[str] = None,
2377+
filter_groups: Optional[List[types.MemoryConjunctionFilter]] = None,
23602378
force: bool = False,
23612379
config: Optional[types.PurgeAgentEngineMemoriesConfigOrDict] = None,
23622380
) -> types.AgentEnginePurgeMemoriesOperation:
@@ -2366,7 +2384,11 @@ async def purge(
23662384
name (str):
23672385
Required. The name of the Agent Engine to purge memories from.
23682386
filter (str):
2369-
Required. The standard list filter to determine which memories to purge.
2387+
Optional. The standard list filter to determine which memories to purge.
2388+
filter_groups (list[MemoryConjunctionFilter]):
2389+
Optional. Metadata filters that will be applied to the memories'
2390+
`metadata` using OR logic. Filters are defined using disjunctive
2391+
normal form (OR of ANDs).
23702392
force (bool):
23712393
Optional. Whether to force the purge operation. If false, the
23722394
operation will be staged but not executed.
@@ -2384,6 +2406,7 @@ async def purge(
23842406
operation = await self._purge(
23852407
name=name,
23862408
filter=filter,
2409+
filter_groups=filter_groups,
23872410
force=force,
23882411
config=config,
23892412
)

vertexai/_genai/types/common.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8447,6 +8447,23 @@ class _PurgeAgentEngineMemoriesRequestParameters(_common.BaseModel):
84478447
description="""The standard list filter to determine which memories to purge.
84488448
More detail in [AIP-160](https://google.aip.dev/160).""",
84498449
)
8450+
filter_groups: Optional[list[MemoryConjunctionFilter]] = Field(
8451+
default=None,
8452+
description="""Metadata filters that will be applied to the memories'
8453+
`metadata` using OR logic. Filters are defined using disjunctive normal
8454+
form (OR of ANDs).
8455+
8456+
For example:
8457+
`filter_groups: [{filters: [{key: "author", value: {string_value: "agent
8458+
`123"}, op: EQUAL}]}, {filters: [{key: "label", value: {string_value:
8459+
"travel"}, op: EQUAL}, {key: "author", value: {string_value: "agent 321"},
8460+
op: EQUAL}]}]`
8461+
8462+
would be equivalent to the logical expression:
8463+
`(metadata.author = "agent 123" OR (metadata.label = "travel" AND
8464+
metadata.author = "agent 321"))`.
8465+
""",
8466+
)
84508467
force: Optional[bool] = Field(
84518468
default=None,
84528469
description="""If true, the memories will actually be purged. If false, the purge request will be validated but not executed.""",
@@ -8466,6 +8483,22 @@ class _PurgeAgentEngineMemoriesRequestParametersDict(TypedDict, total=False):
84668483
"""The standard list filter to determine which memories to purge.
84678484
More detail in [AIP-160](https://google.aip.dev/160)."""
84688485

8486+
filter_groups: Optional[list[MemoryConjunctionFilterDict]]
8487+
"""Metadata filters that will be applied to the memories'
8488+
`metadata` using OR logic. Filters are defined using disjunctive normal
8489+
form (OR of ANDs).
8490+
8491+
For example:
8492+
`filter_groups: [{filters: [{key: "author", value: {string_value: "agent
8493+
`123"}, op: EQUAL}]}, {filters: [{key: "label", value: {string_value:
8494+
"travel"}, op: EQUAL}, {key: "author", value: {string_value: "agent 321"},
8495+
op: EQUAL}]}]`
8496+
8497+
would be equivalent to the logical expression:
8498+
`(metadata.author = "agent 123" OR (metadata.label = "travel" AND
8499+
metadata.author = "agent 321"))`.
8500+
"""
8501+
84698502
force: Optional[bool]
84708503
"""If true, the memories will actually be purged. If false, the purge request will be validated but not executed."""
84718504

0 commit comments

Comments
 (0)