memwal 0.1.8.dev2__tar.gz → 0.1.9.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/CHANGELOG.md +6 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/PKG-INFO +1 -1
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/__init__.py +1 -1
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/client.py +11 -1
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/pyproject.toml +1 -1
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_client.py +86 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/.gitignore +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/README.md +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/examples/.env.example +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/examples/.gitignore +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/examples/async_remember_demo.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/examples/interactive_demo.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/examples/verify_credentials.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/compatibility.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/middleware.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/mock.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/types.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/memwal/utils.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/notebooks/walrus_memory_python_sdk.ipynb +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/run_tests.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/__init__.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_auth_rejected_message.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_env_presets.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_integration.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_middleware.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_mock.py +0 -0
- {memwal-0.1.8.dev2 → memwal-0.1.9.dev0}/tests/test_signing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: memwal
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9.dev0
|
|
4
4
|
Summary: Python SDK for Walrus Memory — Privacy-first AI memory with Ed25519 signing
|
|
5
5
|
Project-URL: Homepage, https://memory.walrus.xyz
|
|
6
6
|
Project-URL: Documentation, https://memory.walrus.xyz
|
|
@@ -463,6 +463,9 @@ class MemWal:
|
|
|
463
463
|
capped at ``MAX_REMEMBER_TEXT_BYTES`` (= 64 KiB).
|
|
464
464
|
"""
|
|
465
465
|
|
|
466
|
+
if not items:
|
|
467
|
+
raise ValueError("remember_bulk_async: items must be a non-empty array")
|
|
468
|
+
|
|
466
469
|
payload_items: List[Dict[str, Any]] = [
|
|
467
470
|
{
|
|
468
471
|
"text": item.text,
|
|
@@ -476,8 +479,15 @@ class MemWal:
|
|
|
476
479
|
{"items": payload_items},
|
|
477
480
|
accepted_statuses=(200, 202),
|
|
478
481
|
)
|
|
482
|
+
job_ids = data.get("job_ids")
|
|
483
|
+
returned = len(job_ids) if job_ids else 0
|
|
484
|
+
if not job_ids or returned != len(payload_items):
|
|
485
|
+
raise ValueError(
|
|
486
|
+
f"remember_bulk_async: server returned {returned} job_ids for "
|
|
487
|
+
f"{len(payload_items)} items"
|
|
488
|
+
)
|
|
479
489
|
return RememberBulkAcceptedResult(
|
|
480
|
-
job_ids=list(
|
|
490
|
+
job_ids=list(job_ids),
|
|
481
491
|
total=int(data.get("total", len(payload_items))),
|
|
482
492
|
status=data.get("status", "pending"),
|
|
483
493
|
)
|
|
@@ -27,6 +27,8 @@ from memwal.client import (
|
|
|
27
27
|
from memwal.types import (
|
|
28
28
|
RecallManualOptions,
|
|
29
29
|
RecallParams,
|
|
30
|
+
RememberBulkAcceptedResult,
|
|
31
|
+
RememberBulkItem,
|
|
30
32
|
RememberManualOptions,
|
|
31
33
|
ScoringWeights,
|
|
32
34
|
)
|
|
@@ -343,6 +345,90 @@ class TestRemember:
|
|
|
343
345
|
assert result.status == "pending"
|
|
344
346
|
|
|
345
347
|
|
|
348
|
+
# ============================================================
|
|
349
|
+
# remember_bulk_async() tests
|
|
350
|
+
# ============================================================
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
class TestRememberBulkAsync:
|
|
354
|
+
@respx.mock
|
|
355
|
+
async def test_empty_items_raises_without_http(self, memwal_client: MemWal) -> None:
|
|
356
|
+
mock_seal_session_prereqs()
|
|
357
|
+
route = respx.post(f"{_TEST_SERVER}/api/remember/bulk").mock(
|
|
358
|
+
return_value=httpx.Response(
|
|
359
|
+
202,
|
|
360
|
+
json={"job_ids": [], "total": 0, "status": "pending"},
|
|
361
|
+
)
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
with pytest.raises(
|
|
365
|
+
ValueError,
|
|
366
|
+
match="remember_bulk_async: items must be a non-empty array",
|
|
367
|
+
):
|
|
368
|
+
await memwal_client.remember_bulk_async([])
|
|
369
|
+
|
|
370
|
+
assert not route.called
|
|
371
|
+
|
|
372
|
+
@respx.mock
|
|
373
|
+
async def test_mismatched_job_ids_raises(self, memwal_client: MemWal) -> None:
|
|
374
|
+
mock_seal_session_prereqs()
|
|
375
|
+
respx.post(f"{_TEST_SERVER}/api/remember/bulk").mock(
|
|
376
|
+
return_value=httpx.Response(
|
|
377
|
+
202,
|
|
378
|
+
json={
|
|
379
|
+
"job_ids": ["job-1"],
|
|
380
|
+
"total": 1,
|
|
381
|
+
"status": "pending",
|
|
382
|
+
},
|
|
383
|
+
)
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
with pytest.raises(
|
|
387
|
+
ValueError,
|
|
388
|
+
match="remember_bulk_async: server returned 1 job_ids for 2 items",
|
|
389
|
+
):
|
|
390
|
+
await memwal_client.remember_bulk_async(
|
|
391
|
+
[
|
|
392
|
+
RememberBulkItem(text="I love coffee"),
|
|
393
|
+
RememberBulkItem(text="I live in Tokyo"),
|
|
394
|
+
]
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
@respx.mock
|
|
398
|
+
async def test_matching_job_ids_returns_accepted(
|
|
399
|
+
self, memwal_client: MemWal
|
|
400
|
+
) -> None:
|
|
401
|
+
mock_seal_session_prereqs()
|
|
402
|
+
route = respx.post(f"{_TEST_SERVER}/api/remember/bulk").mock(
|
|
403
|
+
return_value=httpx.Response(
|
|
404
|
+
202,
|
|
405
|
+
json={
|
|
406
|
+
"job_ids": ["job-1", "job-2"],
|
|
407
|
+
"total": 2,
|
|
408
|
+
"status": "pending",
|
|
409
|
+
},
|
|
410
|
+
)
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
result = await memwal_client.remember_bulk_async(
|
|
414
|
+
[
|
|
415
|
+
RememberBulkItem(text="I love coffee"),
|
|
416
|
+
RememberBulkItem(text="I live in Tokyo", namespace="profile"),
|
|
417
|
+
]
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
assert route.called
|
|
421
|
+
body = json.loads(route.calls[0].request.content)
|
|
422
|
+
assert body["items"] == [
|
|
423
|
+
{"text": "I love coffee", "namespace": "default"},
|
|
424
|
+
{"text": "I live in Tokyo", "namespace": "profile"},
|
|
425
|
+
]
|
|
426
|
+
assert isinstance(result, RememberBulkAcceptedResult)
|
|
427
|
+
assert result.job_ids == ["job-1", "job-2"]
|
|
428
|
+
assert result.total == 2
|
|
429
|
+
assert result.status == "pending"
|
|
430
|
+
|
|
431
|
+
|
|
346
432
|
# ============================================================
|
|
347
433
|
# recall() tests
|
|
348
434
|
# ============================================================
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|