audrey-memory 1.2.2__tar.gz → 2.1.0__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.
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/PKG-INFO +15 -4
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/README.md +14 -3
- audrey_memory-2.1.0/audrey_memory/_version.py +1 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory/types.py +36 -11
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory.egg-info/PKG-INFO +15 -4
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/tests/test_client.py +49 -0
- audrey_memory-1.2.2/audrey_memory/_version.py +0 -1
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory/__init__.py +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory/client.py +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory/py.typed +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory.egg-info/SOURCES.txt +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory.egg-info/dependency_links.txt +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory.egg-info/requires.txt +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/audrey_memory.egg-info/top_level.txt +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/pyproject.toml +0 -0
- {audrey_memory-1.2.2 → audrey_memory-2.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: audrey-memory
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Typed Python client for the Audrey LLM memory server
|
|
5
5
|
Author: evilander
|
|
6
6
|
License: MIT
|
|
@@ -45,7 +45,7 @@ python -m pip install -e .
|
|
|
45
45
|
Start Audrey's REST API:
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
npm install -g audrey
|
|
48
|
+
npm install -g audrey
|
|
49
49
|
audrey serve
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -67,11 +67,22 @@ memory_id = brain.encode(
|
|
|
67
67
|
)
|
|
68
68
|
|
|
69
69
|
results = brain.recall("stripe rate limits", limit=5)
|
|
70
|
-
snapshot = brain.snapshot()
|
|
71
70
|
brain.close()
|
|
72
71
|
```
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
Context keys and values must be strings, for example `context={"project": "support"}`.
|
|
74
|
+
`brain.status()` returns the server's `episodes`, `semantics`, `procedures`, and
|
|
75
|
+
`healthy` fields along with vector-index health details.
|
|
76
|
+
|
|
77
|
+
Snapshot export and restore require the sidecar to be started with
|
|
78
|
+
`AUDREY_ENABLE_ADMIN_TOOLS=1`. With that explicitly enabled:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
with Audrey(base_url="http://127.0.0.1:7437", api_key="secret") as brain:
|
|
82
|
+
snapshot = brain.snapshot()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Snapshots cover the whole store. Restore only into an empty Audrey store, such as a sidecar started with a fresh `AUDREY_DATA_DIR` and admin tools enabled:
|
|
75
86
|
|
|
76
87
|
```python
|
|
77
88
|
restore_target = Audrey(base_url="http://127.0.0.1:7437", api_key="secret")
|
|
@@ -20,7 +20,7 @@ python -m pip install -e .
|
|
|
20
20
|
Start Audrey's REST API:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm install -g audrey
|
|
23
|
+
npm install -g audrey
|
|
24
24
|
audrey serve
|
|
25
25
|
```
|
|
26
26
|
|
|
@@ -42,11 +42,22 @@ memory_id = brain.encode(
|
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
results = brain.recall("stripe rate limits", limit=5)
|
|
45
|
-
snapshot = brain.snapshot()
|
|
46
45
|
brain.close()
|
|
47
46
|
```
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
Context keys and values must be strings, for example `context={"project": "support"}`.
|
|
49
|
+
`brain.status()` returns the server's `episodes`, `semantics`, `procedures`, and
|
|
50
|
+
`healthy` fields along with vector-index health details.
|
|
51
|
+
|
|
52
|
+
Snapshot export and restore require the sidecar to be started with
|
|
53
|
+
`AUDREY_ENABLE_ADMIN_TOOLS=1`. With that explicitly enabled:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
with Audrey(base_url="http://127.0.0.1:7437", api_key="secret") as brain:
|
|
57
|
+
snapshot = brain.snapshot()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Snapshots cover the whole store. Restore only into an empty Audrey store, such as a sidecar started with a fresh `AUDREY_DATA_DIR` and admin tools enabled:
|
|
50
61
|
|
|
51
62
|
```python
|
|
52
63
|
restore_target = Audrey(base_url="http://127.0.0.1:7437", api_key="secret")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.1.0"
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class AudreyModel(BaseModel):
|
|
@@ -31,14 +31,39 @@ class ContradictionStatus(AudreyModel):
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class StatusResponse(AudreyModel):
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
episodes: int
|
|
35
|
+
semantics: int
|
|
36
|
+
procedures: int
|
|
37
|
+
healthy: bool
|
|
38
|
+
vec_episodes: int = 0
|
|
39
|
+
vec_semantics: int = 0
|
|
40
|
+
vec_procedures: int = 0
|
|
41
|
+
searchable_episodes: int = 0
|
|
42
|
+
searchable_semantics: int = 0
|
|
43
|
+
searchable_procedures: int = 0
|
|
44
|
+
dimensions: int | None = None
|
|
45
|
+
schema_version: int | None = None
|
|
46
|
+
device: str | None = None
|
|
47
|
+
reembed_recommended: bool = False
|
|
48
|
+
pending_consolidation_count: int = 0
|
|
49
|
+
embedding_warm: bool = False
|
|
50
|
+
warmup_duration_ms: float | None = None
|
|
51
|
+
default_retrieval_mode: str | None = None
|
|
52
|
+
recall_degraded: bool = False
|
|
53
|
+
last_recall_check_at: str | None = None
|
|
54
|
+
last_recall_errors: list[dict[str, Any]] = Field(default_factory=list)
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def episodic(self) -> int:
|
|
58
|
+
return self.episodes
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def semantic(self) -> int:
|
|
62
|
+
return self.semantics
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def procedural(self) -> int:
|
|
66
|
+
return self.procedures
|
|
42
67
|
|
|
43
68
|
|
|
44
69
|
class AnalyticsRow(AudreyModel):
|
|
@@ -60,7 +85,7 @@ class EncodeRequest(AudreyModel):
|
|
|
60
85
|
source: str
|
|
61
86
|
salience: float | None = Field(default=None, ge=0, le=1)
|
|
62
87
|
tags: list[str] | None = None
|
|
63
|
-
context: dict[
|
|
88
|
+
context: dict[StrictStr, StrictStr] | None = None
|
|
64
89
|
affect: Affect | None = None
|
|
65
90
|
causal: dict[str, Any] | None = None
|
|
66
91
|
supersedes: str | None = None
|
|
@@ -75,7 +100,7 @@ class EncodeResponse(AudreyModel):
|
|
|
75
100
|
class RecallRequest(AudreyModel):
|
|
76
101
|
query: str
|
|
77
102
|
limit: int | None = Field(default=None, ge=1, le=50)
|
|
78
|
-
context: dict[
|
|
103
|
+
context: dict[StrictStr, StrictStr] | None = None
|
|
79
104
|
mood: dict[str, Any] | None = None
|
|
80
105
|
types: list[str] | None = None
|
|
81
106
|
scope: str | None = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: audrey-memory
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Typed Python client for the Audrey LLM memory server
|
|
5
5
|
Author: evilander
|
|
6
6
|
License: MIT
|
|
@@ -45,7 +45,7 @@ python -m pip install -e .
|
|
|
45
45
|
Start Audrey's REST API:
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
npm install -g audrey
|
|
48
|
+
npm install -g audrey
|
|
49
49
|
audrey serve
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -67,11 +67,22 @@ memory_id = brain.encode(
|
|
|
67
67
|
)
|
|
68
68
|
|
|
69
69
|
results = brain.recall("stripe rate limits", limit=5)
|
|
70
|
-
snapshot = brain.snapshot()
|
|
71
70
|
brain.close()
|
|
72
71
|
```
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
Context keys and values must be strings, for example `context={"project": "support"}`.
|
|
74
|
+
`brain.status()` returns the server's `episodes`, `semantics`, `procedures`, and
|
|
75
|
+
`healthy` fields along with vector-index health details.
|
|
76
|
+
|
|
77
|
+
Snapshot export and restore require the sidecar to be started with
|
|
78
|
+
`AUDREY_ENABLE_ADMIN_TOOLS=1`. With that explicitly enabled:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
with Audrey(base_url="http://127.0.0.1:7437", api_key="secret") as brain:
|
|
82
|
+
snapshot = brain.snapshot()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Snapshots cover the whole store. Restore only into an empty Audrey store, such as a sidecar started with a fresh `AUDREY_DATA_DIR` and admin tools enabled:
|
|
75
86
|
|
|
76
87
|
```python
|
|
77
88
|
restore_target = Audrey(base_url="http://127.0.0.1:7437", api_key="secret")
|
|
@@ -12,6 +12,7 @@ import unittest
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
14
|
import httpx
|
|
15
|
+
from pydantic import ValidationError
|
|
15
16
|
|
|
16
17
|
PYTHON_ROOT = Path(__file__).resolve().parents[1]
|
|
17
18
|
REPO_ROOT = PYTHON_ROOT.parent
|
|
@@ -29,6 +30,36 @@ def _free_port() -> int:
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
class AudreyClientUnitTests(unittest.TestCase):
|
|
33
|
+
def test_status_models_counts_and_health_from_status_endpoint(self) -> None:
|
|
34
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
35
|
+
self.assertEqual(request.url.path, "/v1/status")
|
|
36
|
+
return httpx.Response(200, json={
|
|
37
|
+
"episodes": 1, "semantics": 2, "procedures": 3, "healthy": True,
|
|
38
|
+
"vec_episodes": 1, "dimensions": 8, "recall_degraded": False,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
with Audrey(base_url="http://audrey.test", transport=httpx.MockTransport(handler)) as client:
|
|
42
|
+
status = client.status()
|
|
43
|
+
self.assertEqual((status.episodes, status.semantics, status.procedures), (1, 2, 3))
|
|
44
|
+
self.assertEqual(status.episodic, status.episodes)
|
|
45
|
+
self.assertTrue(status.healthy)
|
|
46
|
+
self.assertEqual(status.dimensions, 8)
|
|
47
|
+
|
|
48
|
+
def test_context_rejects_non_strings_before_sending(self) -> None:
|
|
49
|
+
requests: list[httpx.Request] = []
|
|
50
|
+
|
|
51
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
52
|
+
requests.append(request)
|
|
53
|
+
return httpx.Response(200, json={"id": "memory"})
|
|
54
|
+
|
|
55
|
+
with Audrey(base_url="http://audrey.test", transport=httpx.MockTransport(handler)) as client:
|
|
56
|
+
for value in (0, False, 1, None):
|
|
57
|
+
with self.subTest(value=value), self.assertRaises(ValidationError):
|
|
58
|
+
client.encode("Context fixture", source="told-by-user", context={"retry": value})
|
|
59
|
+
client.encode("String context", source="told-by-user", context={"project": "billing"})
|
|
60
|
+
self.assertEqual(len(requests), 1)
|
|
61
|
+
self.assertEqual(json.loads(requests[0].content)["context"], {"project": "billing"})
|
|
62
|
+
|
|
32
63
|
def test_sync_client_sends_auth_and_agent_headers(self) -> None:
|
|
33
64
|
seen: dict[str, object] = {}
|
|
34
65
|
|
|
@@ -99,6 +130,19 @@ class AudreyClientUnitTests(unittest.TestCase):
|
|
|
99
130
|
|
|
100
131
|
|
|
101
132
|
class AudreyAsyncClientUnitTests(unittest.IsolatedAsyncioTestCase):
|
|
133
|
+
async def test_status_models_counts_and_health_from_status_endpoint(self) -> None:
|
|
134
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
135
|
+
self.assertEqual(request.url.path, "/v1/status")
|
|
136
|
+
return httpx.Response(200, json={
|
|
137
|
+
"episodes": 1, "semantics": 0, "procedures": 0, "healthy": True,
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
async with AsyncAudrey(base_url="http://audrey.test", transport=httpx.MockTransport(handler)) as client:
|
|
141
|
+
status = await client.status()
|
|
142
|
+
self.assertEqual(status.episodes, 1)
|
|
143
|
+
self.assertEqual(status.episodic, 1)
|
|
144
|
+
self.assertTrue(status.healthy)
|
|
145
|
+
|
|
102
146
|
async def test_async_restore_accepts_the_server_imported_response(self) -> None:
|
|
103
147
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
104
148
|
self.assertEqual(request.url.path, "/v1/import")
|
|
@@ -242,6 +286,11 @@ class AudreyClientIntegrationTests(unittest.TestCase):
|
|
|
242
286
|
|
|
243
287
|
client.mark_used(memory_id)
|
|
244
288
|
|
|
289
|
+
status = client.status()
|
|
290
|
+
self.assertGreaterEqual(status.episodes, 1)
|
|
291
|
+
self.assertEqual(status.episodic, status.episodes)
|
|
292
|
+
self.assertTrue(status.healthy)
|
|
293
|
+
|
|
245
294
|
results = client.recall("stripe rate limits", limit=5, scope="agent")
|
|
246
295
|
self.assertGreaterEqual(len(results), 1)
|
|
247
296
|
self.assertIn("Stripe", results[0].content)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.2.2"
|
|
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
|