aether-cache 0.1.5__tar.gz → 0.1.6__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.
- {aether_cache-0.1.5 → aether_cache-0.1.6}/PKG-INFO +14 -3
- {aether_cache-0.1.5 → aether_cache-0.1.6}/README.md +13 -2
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/__init__.py +1 -1
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/engine.py +26 -1
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/server.py +9 -5
- {aether_cache-0.1.5 → aether_cache-0.1.6}/pyproject.toml +1 -1
- {aether_cache-0.1.5 → aether_cache-0.1.6}/.gitignore +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/LICENSE +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/__main__.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/cli.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/config.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/connect.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/engine/aether-engine.jar +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/javart.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/portability.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/repos.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/OFL.txt +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/index.html +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.6}/docs/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: aether-cache
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Shared memory for AI coding tools that stays true to your code.
|
|
5
5
|
Project-URL: Homepage, https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/
|
|
6
6
|
Project-URL: Repository, https://github.com/anishchugh05/Aether-Cache-Redis-Compatible-Vector-Store
|
|
@@ -13,12 +13,14 @@ Requires-Dist: mcp>=1.2
|
|
|
13
13
|
Requires-Dist: redis>=5.0
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
|
|
16
|
-
[](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)
|
|
17
17
|
|
|
18
18
|
# Aether Cache
|
|
19
19
|
|
|
20
20
|
**Shared memory for AI coding tools that stays true to your code.**
|
|
21
21
|
|
|
22
|
+
<!-- mcp-name: io.github.anishchugh05/aether-cache -->
|
|
23
|
+
|
|
22
24
|
**[Website](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)** · **[PyPI](https://pypi.org/project/aether-cache/)**
|
|
23
25
|
|
|
24
26
|
Claude Code, Cursor, and other AI tools each forget your project between sessions, and when they do remember things,
|
|
@@ -63,7 +65,14 @@ other tools ─┘ (Python: embeddings,│ memories, HNSW vector inde
|
|
|
63
65
|
|
|
64
66
|
## What it looks like
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
The dashboard (`aether-cache ui`): memories whose files changed wait for a decision, with the file versions side by side.
|
|
69
|
+
|
|
70
|
+
<picture>
|
|
71
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-dark.png">
|
|
72
|
+
<img alt="The Aether Cache dashboard showing stale memories and a possible conflict" src="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-light.png">
|
|
73
|
+
</picture>
|
|
74
|
+
|
|
75
|
+
And from your AI tool's side, a memory linked to a file, the file changes, and the next lookup catches it:
|
|
67
76
|
|
|
68
77
|
```
|
|
69
78
|
> remember("The database runs Postgres via docker compose", files=["docker-compose.yml"])
|
|
@@ -203,6 +212,8 @@ A Redis-compatible server written from scratch in Java. It speaks RESP, so `redi
|
|
|
203
212
|
[CodeCrafters "Build Your Own Redis"](https://codecrafters.io/challenges/redis) challenge; the vector index,
|
|
204
213
|
persistence hardening, and the memory layer are my own additions.
|
|
205
214
|
|
|
215
|
+
[](https://app.codecrafters.io/users/anishchugh05?r=2qF)
|
|
216
|
+
|
|
206
217
|
### Throughput vs. official Redis
|
|
207
218
|
|
|
208
219
|
`redis-benchmark -t set,get`, 100K requests, 50 parallel clients, 3-byte values, same machine:
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
[](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)
|
|
2
2
|
|
|
3
3
|
# Aether Cache
|
|
4
4
|
|
|
5
5
|
**Shared memory for AI coding tools that stays true to your code.**
|
|
6
6
|
|
|
7
|
+
<!-- mcp-name: io.github.anishchugh05/aether-cache -->
|
|
8
|
+
|
|
7
9
|
**[Website](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)** · **[PyPI](https://pypi.org/project/aether-cache/)**
|
|
8
10
|
|
|
9
11
|
Claude Code, Cursor, and other AI tools each forget your project between sessions, and when they do remember things,
|
|
@@ -48,7 +50,14 @@ other tools ─┘ (Python: embeddings,│ memories, HNSW vector inde
|
|
|
48
50
|
|
|
49
51
|
## What it looks like
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
The dashboard (`aether-cache ui`): memories whose files changed wait for a decision, with the file versions side by side.
|
|
54
|
+
|
|
55
|
+
<picture>
|
|
56
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-dark.png">
|
|
57
|
+
<img alt="The Aether Cache dashboard showing stale memories and a possible conflict" src="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-light.png">
|
|
58
|
+
</picture>
|
|
59
|
+
|
|
60
|
+
And from your AI tool's side, a memory linked to a file, the file changes, and the next lookup catches it:
|
|
52
61
|
|
|
53
62
|
```
|
|
54
63
|
> remember("The database runs Postgres via docker compose", files=["docker-compose.yml"])
|
|
@@ -188,6 +197,8 @@ A Redis-compatible server written from scratch in Java. It speaks RESP, so `redi
|
|
|
188
197
|
[CodeCrafters "Build Your Own Redis"](https://codecrafters.io/challenges/redis) challenge; the vector index,
|
|
189
198
|
persistence hardening, and the memory layer are my own additions.
|
|
190
199
|
|
|
200
|
+
[](https://app.codecrafters.io/users/anishchugh05?r=2qF)
|
|
201
|
+
|
|
191
202
|
### Throughput vs. official Redis
|
|
192
203
|
|
|
193
204
|
`redis-benchmark -t set,get`, 100K requests, 50 parallel clients, 3-byte values, same machine:
|
|
@@ -224,7 +224,7 @@ def start(wait: float = 60) -> str:
|
|
|
224
224
|
upgraded = True
|
|
225
225
|
if state == "other":
|
|
226
226
|
raise EngineError(port_taken_message())
|
|
227
|
-
java
|
|
227
|
+
java = _java_or_download()
|
|
228
228
|
note = _migrate_old_data()
|
|
229
229
|
config.DATA_DIR.mkdir(parents=True, exist_ok=True)
|
|
230
230
|
command = [java, "-Xmx1g", "-jar", str(JAR),
|
|
@@ -264,6 +264,31 @@ def start(wait: float = 60) -> str:
|
|
|
264
264
|
raise EngineError(f"The engine didn't answer within {int(wait)} seconds. See {config.LOG_FILE}.")
|
|
265
265
|
|
|
266
266
|
|
|
267
|
+
def _java_or_download() -> str:
|
|
268
|
+
"""Java for starting the engine. If there isn't any, downloads Aether Cache's private copy, so the engine
|
|
269
|
+
also starts for people whose AI tool runs the server without `aether-cache setup` having run first.
|
|
270
|
+
Called while holding the start lock, so several sessions starting at once download it only once."""
|
|
271
|
+
try:
|
|
272
|
+
return find_java()[0]
|
|
273
|
+
except EngineError as missing:
|
|
274
|
+
if os.environ.get("AETHER_NO_JAVA_DOWNLOAD"):
|
|
275
|
+
raise
|
|
276
|
+
from . import javart
|
|
277
|
+
notice = (f"{str(missing).splitlines()[0]} Downloading a private copy of Java {javart.FEATURE_VERSION} "
|
|
278
|
+
f"for Aether Cache into {javart.JAVA_DIR} (about 50 MB, only the first time).")
|
|
279
|
+
print(notice, file=sys.stderr, flush=True) # stderr: stdout carries the MCP protocol
|
|
280
|
+
try:
|
|
281
|
+
with open(config.LOG_FILE, "a") as log:
|
|
282
|
+
log.write(f"\n{time.strftime('%Y-%m-%d %H:%M:%S')} {notice}\n")
|
|
283
|
+
except OSError:
|
|
284
|
+
pass
|
|
285
|
+
try:
|
|
286
|
+
javart.download(progress=lambda done, total: None)
|
|
287
|
+
except javart.JavaDownloadError as e:
|
|
288
|
+
raise EngineError(f"{str(missing).splitlines()[0]}\n{e}")
|
|
289
|
+
return find_java()[0]
|
|
290
|
+
|
|
291
|
+
|
|
267
292
|
def ensure_running() -> None:
|
|
268
293
|
if probe() != "aether" or needs_upgrade():
|
|
269
294
|
start()
|
|
@@ -16,7 +16,7 @@ from typing import List, Optional
|
|
|
16
16
|
|
|
17
17
|
import redis
|
|
18
18
|
|
|
19
|
-
from . import config, engine
|
|
19
|
+
from . import __version__, config, engine
|
|
20
20
|
|
|
21
21
|
try:
|
|
22
22
|
from mcp.server.mcpserver import MCPServer # mcp 2.x
|
|
@@ -39,10 +39,14 @@ INSTRUCTIONS = (
|
|
|
39
39
|
"replace_memory."
|
|
40
40
|
)
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
"aether-cache",
|
|
44
|
-
|
|
45
|
-
)
|
|
42
|
+
try:
|
|
43
|
+
mcp = MCPServer("aether-cache", instructions=INSTRUCTIONS, version=__version__)
|
|
44
|
+
except Exception: # mcp 1.x has no version argument; set it on the underlying server instead
|
|
45
|
+
mcp = MCPServer("aether-cache", instructions=INSTRUCTIONS)
|
|
46
|
+
try:
|
|
47
|
+
mcp._mcp_server.version = __version__
|
|
48
|
+
except AttributeError:
|
|
49
|
+
pass
|
|
46
50
|
|
|
47
51
|
def quiet_libraries() -> None:
|
|
48
52
|
"""Hides the download libraries' request logs, warnings and progress bars, which otherwise flood the
|
|
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
|
{aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-mono-latin-400-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-mono-latin-500-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-sans-latin-400-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-sans-latin-500-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.6}/aether_cache/ui/fonts/ibm-plex-sans-latin-600-normal.woff2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|