fix(python-client): async=true silently ignored on retain (#709)
* docs(claude-code): tidy configuration reference and sync README
Add missing settings (retainMode, retainToolCalls, retainTags,
retainMetadata, embedPackagePath, llmApiKeyEnv, agentName, and
several recall options) that existed in code but not in docs.
Restructure config tables with prose introductions, clearer
descriptions, and consistent layout across both files.
* refactor(claude-code): remove recallTopK setting
Unused client-side cap — Hindsight server already controls result
count via recallBudget and recallMaxTokens.
* fix(python-client): async=true was silently ignored on retain calls
The hand-written client wrapper passed `async_=retain_async` to
RetainRequest, but the generated Pydantic model uses `var_async` as the
Python field name (with `alias="async"`). The `async_` kwarg didn't
match either the field name or the alias, so Pydantic silently ignored
it — every retain call ran synchronously regardless of the flag.
This has been broken since the client was first introduced (6073ac4f),
not a regression.
Also adds unit tests that verify the async field serializes correctly
in the request JSON, preventing future regressions.
This commit is contained in:
parent
91397190c0
commit
c9ff37dcbf
2 changed files with 44 additions and 2 deletions
|
|
@ -204,7 +204,7 @@ class Hindsight:
|
||||||
|
|
||||||
request_obj = retain_request.RetainRequest(
|
request_obj = retain_request.RetainRequest(
|
||||||
items=memory_items,
|
items=memory_items,
|
||||||
async_=retain_async,
|
var_async=retain_async,
|
||||||
document_tags=document_tags,
|
document_tags=document_tags,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -618,7 +618,7 @@ class Hindsight:
|
||||||
|
|
||||||
request_obj = retain_request.RetainRequest(
|
request_obj = retain_request.RetainRequest(
|
||||||
items=memory_items,
|
items=memory_items,
|
||||||
async_=retain_async,
|
var_async=retain_async,
|
||||||
document_tags=document_tags,
|
document_tags=document_tags,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
42
hindsight-clients/python/tests/test_retain_request_async.py
Normal file
42
hindsight-clients/python/tests/test_retain_request_async.py
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
"""
|
||||||
|
Test that RetainRequest correctly serializes the async field.
|
||||||
|
|
||||||
|
Regression test for a bug where the client passed async_=True (invalid kwarg)
|
||||||
|
instead of var_async=True, causing async mode to be silently ignored.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from hindsight_client_api.models.memory_item import MemoryItem
|
||||||
|
from hindsight_client_api.models.retain_request import RetainRequest
|
||||||
|
|
||||||
|
|
||||||
|
def _make_item():
|
||||||
|
return MemoryItem(content="test content")
|
||||||
|
|
||||||
|
|
||||||
|
def test_retain_request_async_true_serialized():
|
||||||
|
"""var_async=True must appear as 'async': True in the serialized dict."""
|
||||||
|
req = RetainRequest(items=[_make_item()], var_async=True)
|
||||||
|
d = req.to_dict()
|
||||||
|
assert d["async"] is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_retain_request_async_false_serialized():
|
||||||
|
"""var_async=False (default) must appear as 'async': False."""
|
||||||
|
req = RetainRequest(items=[_make_item()], var_async=False)
|
||||||
|
d = req.to_dict()
|
||||||
|
assert d["async"] is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_retain_request_default_is_sync():
|
||||||
|
"""Omitting var_async should default to synchronous (async=False)."""
|
||||||
|
req = RetainRequest(items=[_make_item()])
|
||||||
|
d = req.to_dict()
|
||||||
|
assert d["async"] is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_retain_request_async_json_roundtrip():
|
||||||
|
"""async=True must survive a JSON serialization roundtrip."""
|
||||||
|
req = RetainRequest(items=[_make_item()], var_async=True)
|
||||||
|
json_str = req.to_json()
|
||||||
|
restored = RetainRequest.from_json(json_str)
|
||||||
|
assert restored.var_async is True
|
||||||
Loading…
Reference in a new issue