Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions dashscope/agentstudio/resources/memory_stores.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,14 @@ def update(
*,
path: Optional[str] = None,
content: Optional[str] = None,
content_sha256: Optional[str] = None,
precondition: Optional[Any] = None,
) -> Memory:
"""Update a memory (``POST .../memories/{id}``).

Mutate ``content``, rename via ``path``, or both — at least one
must be given. Pass the sha from the previously retrieved
memory as ``content_sha256`` for optimistic concurrency; a
mismatch returns 409 ``memory_precondition_failed_error``.
memory as ``precondition`` for optimistic concurrency (a
mismatch returns 409 ``memory_precondition_failed_error``).
"""
if path is None and content is None:
raise TypeError(
Expand All @@ -238,7 +238,7 @@ def update(
body = MemoryUpdateParams(
path=path,
content=content,
content_sha256=content_sha256,
precondition=precondition,
).to_dict()
resp = self._client.transport.request(
"POST",
Expand Down Expand Up @@ -576,7 +576,7 @@ async def update(
*,
path: Optional[str] = None,
content: Optional[str] = None,
content_sha256: Optional[str] = None,
precondition: Optional[Any] = None,
) -> Memory:
if path is None and content is None:
raise TypeError(
Expand All @@ -586,7 +586,7 @@ async def update(
body = MemoryUpdateParams(
path=path,
content=content,
content_sha256=content_sha256,
precondition=precondition,
).to_dict()
resp = await self._client.transport.request(
"POST",
Expand Down
24 changes: 20 additions & 4 deletions dashscope/agentstudio/types/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,13 +983,29 @@ class MemoryCreateParams(BaseModel):
class MemoryUpdateParams(BaseModel):
"""Request body for ``POST /memory_stores/{store_id}/memories/{memory_id}``.

At least one of ``path`` / ``content`` must be given. Passing the
current ``content_sha256`` (from the retrieved memory) enables
optimistic concurrency — a mismatch returns 409
At least one of ``path`` / ``content`` must be given. ``precondition``
is the optimistic lock: the sha string from the retrieved memory
(wrapped into the documented ``{"type": "content_sha256", ...}``
object) or the object itself — a mismatch returns 409
``memory_precondition_failed_error``.
"""

_fields = ("path", "content", "content_sha256")
_fields = ("path", "content", "precondition")

def __init__(
self,
*,
precondition: Optional[Any] = None,
**kwargs: Any,
) -> None:
if precondition is not None:
if isinstance(precondition, str):
precondition = {
"type": "content_sha256",
"content_sha256": precondition,
}
kwargs["precondition"] = precondition
super().__init__(**kwargs)


class MemoryListParams(BaseModel):
Expand Down
4 changes: 2 additions & 2 deletions samples/test_agentstudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ def test_memory_stores():
# Directory nodes ride the page's prefixes field (per page):
print(f" prefixes={page.prefixes}")

print("==> updating with optimistic lock")
print("==> updating with optimistic lock (precondition)")
updated = client.memory_stores.memories.update(
store.id,
mem.id,
content="All reports use GAAP formatting. ISO-8601 dates.",
content_sha256=mem.content_sha256,
precondition=mem.content_sha256,
)
print(f" new sha={updated.content_sha256[:12]}...")

Expand Down
25 changes: 21 additions & 4 deletions tests/unit/test_agentstudio_memory_stores.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,26 +382,43 @@ def test_store_list_page_extra_defaults_empty(client):
assert page.prefixes == []


def test_memory_update_sends_flattened_precondition(client):
def test_memory_update_sends_precondition_object(client):
mem = client.memory_stores.memories.update(
"memstore_01Hx",
"mem_01Hy",
content="CORRECTED",
content_sha256="abc123",
precondition="abc123",
)
# A sha string wraps into the documented precondition object.
assert client.transport.calls[0]["json"] == {
"content": "CORRECTED",
"content_sha256": "abc123",
"precondition": {
"type": "content_sha256",
"content_sha256": "abc123",
},
}
assert isinstance(mem, Memory)


def test_memory_update_accepts_precondition_object(client):
client.memory_stores.memories.update(
"memstore_01Hx",
"mem_01Hy",
content="CORRECTED",
precondition={"type": "content_sha256", "content_sha256": "abc"},
)
assert client.transport.calls[0]["json"]["precondition"] == {
"type": "content_sha256",
"content_sha256": "abc",
}


def test_memory_update_requires_path_or_content(client):
with pytest.raises(TypeError):
client.memory_stores.memories.update(
"memstore_01Hx",
"mem_01Hy",
content_sha256="abc123",
precondition="abc123",
)


Expand Down
Loading