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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: audrey-memory
3
- Version: 1.2.2
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 --allow-scripts=better-sqlite3,onnxruntime-node,sharp,protobufjs
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
- Restore snapshots only into an empty Audrey store, such as a sidecar started with a fresh `AUDREY_DATA_DIR`:
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 --allow-scripts=better-sqlite3,onnxruntime-node,sharp,protobufjs
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
- Restore snapshots only into an empty Audrey store, such as a sidecar started with a fresh `AUDREY_DATA_DIR`:
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
- episodic: int | None = None
35
- semantic: int | None = None
36
- procedural: int | None = None
37
- causalLinks: int | None = None
38
- contradictions: ContradictionStatus | None = None
39
- dormant: int | None = None
40
- lastConsolidation: str | None = None
41
- totalConsolidationRuns: int | None = None
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[str, Any] | None = None
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[str, Any] | None = None
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.2.2
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 --allow-scripts=better-sqlite3,onnxruntime-node,sharp,protobufjs
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
- Restore snapshots only into an empty Audrey store, such as a sidecar started with a fresh `AUDREY_DATA_DIR`:
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