aether-cache 0.1.5__tar.gz → 0.1.7__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.7}/PKG-INFO +44 -7
- {aether_cache-0.1.5 → aether_cache-0.1.7}/README.md +43 -6
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/__init__.py +1 -1
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/engine.py +26 -1
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/server.py +9 -5
- {aether_cache-0.1.5 → aether_cache-0.1.7}/pyproject.toml +1 -1
- {aether_cache-0.1.5 → aether_cache-0.1.7}/.gitignore +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/LICENSE +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/__main__.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/cli.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/config.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/connect.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/engine/aether-engine.jar +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/javart.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/portability.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/repos.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/OFL.txt +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/index.html +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui.py +0 -0
- {aether_cache-0.1.5 → aether_cache-0.1.7}/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.7
|
|
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"])
|
|
@@ -106,12 +115,26 @@ m1 retired; m3 replaces it.
|
|
|
106
115
|
|
|
107
116
|
## Quick start
|
|
108
117
|
|
|
109
|
-
|
|
110
|
-
|
|
118
|
+
One line installs everything and runs setup. On macOS or Linux:
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
curl -fsSL https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/install.sh | sh
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
On Windows (PowerShell):
|
|
125
|
+
|
|
126
|
+
```powershell
|
|
127
|
+
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/anishchugh05/Aether-Cache-Redis-Compatible-Vector-Store/main/docs/install.ps1 | iex"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The installer ([install.sh](docs/install.sh), [install.ps1](docs/install.ps1)) gets [uv](https://docs.astral.sh/uv/) if you
|
|
131
|
+
don't have it (uv brings Python), installs Aether Cache, and runs `aether-cache setup`. Prefer your own tools? Any of
|
|
132
|
+
these works, followed by `aether-cache setup`:
|
|
111
133
|
|
|
112
134
|
```sh
|
|
113
135
|
uv tool install aether-cache
|
|
114
|
-
aether-cache
|
|
136
|
+
pipx install aether-cache
|
|
137
|
+
pip install aether-cache # Python 3.10+
|
|
115
138
|
```
|
|
116
139
|
|
|
117
140
|
`setup` starts the engine in the background, downloads the embedding model once (about 90 MB), and connects every
|
|
@@ -122,7 +145,7 @@ repo and try:
|
|
|
122
145
|
|
|
123
146
|
Then start a new session and ask how to run the tests.
|
|
124
147
|
|
|
125
|
-
The engine runs on Java 11+. If you have it, it's used. If you don't,
|
|
148
|
+
The engine runs on Java 11+. If you have it, it's used. If you don't, Aether Cache downloads a private copy (about
|
|
126
149
|
50 MB) into `~/.aether-cache/java`, checks it against its published checksum, and uses it only for Aether Cache;
|
|
127
150
|
nothing is installed system-wide, and `aether-cache uninstall` removes it.
|
|
128
151
|
|
|
@@ -203,6 +226,8 @@ A Redis-compatible server written from scratch in Java. It speaks RESP, so `redi
|
|
|
203
226
|
[CodeCrafters "Build Your Own Redis"](https://codecrafters.io/challenges/redis) challenge; the vector index,
|
|
204
227
|
persistence hardening, and the memory layer are my own additions.
|
|
205
228
|
|
|
229
|
+
[](https://app.codecrafters.io/users/anishchugh05?r=2qF)
|
|
230
|
+
|
|
206
231
|
### Throughput vs. official Redis
|
|
207
232
|
|
|
208
233
|
`redis-benchmark -t set,get`, 100K requests, 50 parallel clients, 3-byte values, same machine:
|
|
@@ -369,6 +394,18 @@ memory_mcp/calibrate.py similarity calibration for duplicate/contradiction
|
|
|
369
394
|
vector_bench.py HNSW benchmark (writes results.json)
|
|
370
395
|
crash_test.py kill -9 crash-safety test
|
|
371
396
|
```
|
|
397
|
+
|
|
398
|
+
## Releasing
|
|
399
|
+
|
|
400
|
+
Bump the version in `pyproject.toml`, `aether_cache/__init__.py`, and `server.json`, commit, then:
|
|
401
|
+
|
|
402
|
+
```sh
|
|
403
|
+
git tag v0.1.7 && git push --tags
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
The [release workflow](.github/workflows/release.yml) checks the versions match, builds and smoke-tests the package,
|
|
407
|
+
publishes it to PyPI and the MCP Registry, and creates the GitHub Release.
|
|
408
|
+
|
|
372
409
|
## License
|
|
373
410
|
|
|
374
411
|
MIT. See [LICENSE](LICENSE).
|
|
@@ -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"])
|
|
@@ -91,12 +100,26 @@ m1 retired; m3 replaces it.
|
|
|
91
100
|
|
|
92
101
|
## Quick start
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
One line installs everything and runs setup. On macOS or Linux:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
curl -fsSL https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/install.sh | sh
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
On Windows (PowerShell):
|
|
110
|
+
|
|
111
|
+
```powershell
|
|
112
|
+
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/anishchugh05/Aether-Cache-Redis-Compatible-Vector-Store/main/docs/install.ps1 | iex"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The installer ([install.sh](docs/install.sh), [install.ps1](docs/install.ps1)) gets [uv](https://docs.astral.sh/uv/) if you
|
|
116
|
+
don't have it (uv brings Python), installs Aether Cache, and runs `aether-cache setup`. Prefer your own tools? Any of
|
|
117
|
+
these works, followed by `aether-cache setup`:
|
|
96
118
|
|
|
97
119
|
```sh
|
|
98
120
|
uv tool install aether-cache
|
|
99
|
-
aether-cache
|
|
121
|
+
pipx install aether-cache
|
|
122
|
+
pip install aether-cache # Python 3.10+
|
|
100
123
|
```
|
|
101
124
|
|
|
102
125
|
`setup` starts the engine in the background, downloads the embedding model once (about 90 MB), and connects every
|
|
@@ -107,7 +130,7 @@ repo and try:
|
|
|
107
130
|
|
|
108
131
|
Then start a new session and ask how to run the tests.
|
|
109
132
|
|
|
110
|
-
The engine runs on Java 11+. If you have it, it's used. If you don't,
|
|
133
|
+
The engine runs on Java 11+. If you have it, it's used. If you don't, Aether Cache downloads a private copy (about
|
|
111
134
|
50 MB) into `~/.aether-cache/java`, checks it against its published checksum, and uses it only for Aether Cache;
|
|
112
135
|
nothing is installed system-wide, and `aether-cache uninstall` removes it.
|
|
113
136
|
|
|
@@ -188,6 +211,8 @@ A Redis-compatible server written from scratch in Java. It speaks RESP, so `redi
|
|
|
188
211
|
[CodeCrafters "Build Your Own Redis"](https://codecrafters.io/challenges/redis) challenge; the vector index,
|
|
189
212
|
persistence hardening, and the memory layer are my own additions.
|
|
190
213
|
|
|
214
|
+
[](https://app.codecrafters.io/users/anishchugh05?r=2qF)
|
|
215
|
+
|
|
191
216
|
### Throughput vs. official Redis
|
|
192
217
|
|
|
193
218
|
`redis-benchmark -t set,get`, 100K requests, 50 parallel clients, 3-byte values, same machine:
|
|
@@ -354,6 +379,18 @@ memory_mcp/calibrate.py similarity calibration for duplicate/contradiction
|
|
|
354
379
|
vector_bench.py HNSW benchmark (writes results.json)
|
|
355
380
|
crash_test.py kill -9 crash-safety test
|
|
356
381
|
```
|
|
382
|
+
|
|
383
|
+
## Releasing
|
|
384
|
+
|
|
385
|
+
Bump the version in `pyproject.toml`, `aether_cache/__init__.py`, and `server.json`, commit, then:
|
|
386
|
+
|
|
387
|
+
```sh
|
|
388
|
+
git tag v0.1.7 && git push --tags
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
The [release workflow](.github/workflows/release.yml) checks the versions match, builds and smoke-tests the package,
|
|
392
|
+
publishes it to PyPI and the MCP Registry, and creates the GitHub Release.
|
|
393
|
+
|
|
357
394
|
## License
|
|
358
395
|
|
|
359
396
|
MIT. See [LICENSE](LICENSE).
|
|
@@ -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.7}/aether_cache/ui/fonts/ibm-plex-mono-latin-400-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-mono-latin-500-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-400-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-500-normal.woff2
RENAMED
|
File without changes
|
{aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-600-normal.woff2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|