Skip to content

Commit 71856da

Browse files
foleydangclaude
andcommitted
fix(agentstudio): send the documented precondition object on memory update
The public memory-store docs (and CMA) specify the optimistic lock as a nested {"type": "content_sha256", "content_sha256": ...} object; the control controller flattens it, so the flat form also worked, but the SDK now sends the documented shape: update() takes a `precondition` argument accepting either the sha string (wrapped automatically) or the full object. Verified by e2e against the pre-release environment. Co-Authored-By: Claude Code <noreply@anthropic.com>
1 parent 6df8379 commit 71856da

4 files changed

Lines changed: 49 additions & 16 deletions

File tree

‎dashscope/agentstudio/resources/memory_stores.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ def update(
221221
*,
222222
path: Optional[str] = None,
223223
content: Optional[str] = None,
224-
content_sha256: Optional[str] = None,
224+
precondition: Optional[Any] = None,
225225
) -> Memory:
226226
"""Update a memory (``POST .../memories/{id}``).
227227
228228
Mutate ``content``, rename via ``path``, or both — at least one
229229
must be given. Pass the sha from the previously retrieved
230-
memory as ``content_sha256`` for optimistic concurrency; a
231-
mismatch returns 409 ``memory_precondition_failed_error``.
230+
memory as ``precondition`` for optimistic concurrency (a
231+
mismatch returns 409 ``memory_precondition_failed_error``).
232232
"""
233233
if path is None and content is None:
234234
raise TypeError(
@@ -238,7 +238,7 @@ def update(
238238
body = MemoryUpdateParams(
239239
path=path,
240240
content=content,
241-
content_sha256=content_sha256,
241+
precondition=precondition,
242242
).to_dict()
243243
resp = self._client.transport.request(
244244
"POST",
@@ -576,7 +576,7 @@ async def update(
576576
*,
577577
path: Optional[str] = None,
578578
content: Optional[str] = None,
579-
content_sha256: Optional[str] = None,
579+
precondition: Optional[Any] = None,
580580
) -> Memory:
581581
if path is None and content is None:
582582
raise TypeError(
@@ -586,7 +586,7 @@ async def update(
586586
body = MemoryUpdateParams(
587587
path=path,
588588
content=content,
589-
content_sha256=content_sha256,
589+
precondition=precondition,
590590
).to_dict()
591591
resp = await self._client.transport.request(
592592
"POST",

‎dashscope/agentstudio/types/params.py‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -983,13 +983,29 @@ class MemoryCreateParams(BaseModel):
983983
class MemoryUpdateParams(BaseModel):
984984
"""Request body for ``POST /memory_stores/{store_id}/memories/{memory_id}``.
985985
986-
At least one of ``path`` / ``content`` must be given. Passing the
987-
current ``content_sha256`` (from the retrieved memory) enables
988-
optimistic concurrency — a mismatch returns 409
986+
At least one of ``path`` / ``content`` must be given. ``precondition``
987+
is the optimistic lock: the sha string from the retrieved memory
988+
(wrapped into the documented ``{"type": "content_sha256", ...}``
989+
object) or the object itself — a mismatch returns 409
989990
``memory_precondition_failed_error``.
990991
"""
991992

992-
_fields = ("path", "content", "content_sha256")
993+
_fields = ("path", "content", "precondition")
994+
995+
def __init__(
996+
self,
997+
*,
998+
precondition: Optional[Any] = None,
999+
**kwargs: Any,
1000+
) -> None:
1001+
if precondition is not None:
1002+
if isinstance(precondition, str):
1003+
precondition = {
1004+
"type": "content_sha256",
1005+
"content_sha256": precondition,
1006+
}
1007+
kwargs["precondition"] = precondition
1008+
super().__init__(**kwargs)
9931009

9941010

9951011
class MemoryListParams(BaseModel):

‎samples/test_agentstudio.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ def test_memory_stores():
9191
# Directory nodes ride the page's prefixes field (per page):
9292
print(f" prefixes={page.prefixes}")
9393

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

‎tests/unit/test_agentstudio_memory_stores.py‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,26 +382,43 @@ def test_store_list_page_extra_defaults_empty(client):
382382
assert page.prefixes == []
383383

384384

385-
def test_memory_update_sends_flattened_precondition(client):
385+
def test_memory_update_sends_precondition_object(client):
386386
mem = client.memory_stores.memories.update(
387387
"memstore_01Hx",
388388
"mem_01Hy",
389389
content="CORRECTED",
390-
content_sha256="abc123",
390+
precondition="abc123",
391391
)
392+
# A sha string wraps into the documented precondition object.
392393
assert client.transport.calls[0]["json"] == {
393394
"content": "CORRECTED",
394-
"content_sha256": "abc123",
395+
"precondition": {
396+
"type": "content_sha256",
397+
"content_sha256": "abc123",
398+
},
395399
}
396400
assert isinstance(mem, Memory)
397401

398402

403+
def test_memory_update_accepts_precondition_object(client):
404+
client.memory_stores.memories.update(
405+
"memstore_01Hx",
406+
"mem_01Hy",
407+
content="CORRECTED",
408+
precondition={"type": "content_sha256", "content_sha256": "abc"},
409+
)
410+
assert client.transport.calls[0]["json"]["precondition"] == {
411+
"type": "content_sha256",
412+
"content_sha256": "abc",
413+
}
414+
415+
399416
def test_memory_update_requires_path_or_content(client):
400417
with pytest.raises(TypeError):
401418
client.memory_stores.memories.update(
402419
"memstore_01Hx",
403420
"mem_01Hy",
404-
content_sha256="abc123",
421+
precondition="abc123",
405422
)
406423

407424

0 commit comments

Comments
 (0)