hyatlas-memory 1.0.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.
- hyatlas_memory-1.0.0/CHANGELOG.md +156 -0
- hyatlas_memory-1.0.0/CONTRIBUTING.md +321 -0
- hyatlas_memory-1.0.0/LICENSE +21 -0
- hyatlas_memory-1.0.0/MANIFEST.in +32 -0
- hyatlas_memory-1.0.0/PKG-INFO +457 -0
- hyatlas_memory-1.0.0/README.md +385 -0
- hyatlas_memory-1.0.0/docs/API.md +419 -0
- hyatlas_memory-1.0.0/docs/DASHBOARD.md +270 -0
- hyatlas_memory-1.0.0/docs/LAYERS.md +230 -0
- hyatlas_memory-1.0.0/docs/TROUBLESHOOTING.md +438 -0
- hyatlas_memory-1.0.0/docs/architecture.md +160 -0
- hyatlas_memory-1.0.0/pyproject.toml +167 -0
- hyatlas_memory-1.0.0/setup.cfg +4 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/__init__.py +1147 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/__main__.py +25 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/_version.py +6 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/cli.py +423 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/client.py +217 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/context_pressure.py +821 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/embed_server.py +281 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/init_wizard.py +170 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/installer.py +187 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/patches.py +1959 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/process.py +261 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory/start.py +42 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory.egg-info/PKG-INFO +457 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory.egg-info/SOURCES.txt +33 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory.egg-info/dependency_links.txt +1 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory.egg-info/entry_points.txt +5 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory.egg-info/requires.txt +34 -0
- hyatlas_memory-1.0.0/src/hyatlas_memory.egg-info/top_level.txt +1 -0
- hyatlas_memory-1.0.0/tests/conftest.py +22 -0
- hyatlas_memory-1.0.0/tests/test_hy_memory_search.py +202 -0
- hyatlas_memory-1.0.0/tests/test_integration.py +215 -0
- hyatlas_memory-1.0.0/tests/test_standalone.py +72 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
> All notable changes to HyAtlas-Memory are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2026-06-19
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **First stable release.** PyPI package `hyatlas-memory` installable via `pip install hyatlas-memory`.
|
|
9
|
+
- `__all__` exports in `hyatlas_memory` (`HyMemoryProvider`, `__version__`).
|
|
10
|
+
- `MANIFEST.in` ensures LICENSE, README, CHANGELOG, CONTRIBUTING, docs/, and tests ship in the sdist.
|
|
11
|
+
- `hyatlas` console_scripts entry point — `pip install -e .` then `hyatlas start|--stop|--status` works from any directory.
|
|
12
|
+
- `docker-compose.yml` — one-command full stack via `docker-compose up -d`.
|
|
13
|
+
- `Dockerfile` (python:3.11-slim) and `.dockerignore`.
|
|
14
|
+
- Token-based dashboard auth when bound to `0.0.0.0` (auto-generated 32-char token, stored at `~/.hy_memory/.dashboard_token`, cookie-based session, `/api/health` exempt).
|
|
15
|
+
- `hyatlas_memory.start` module wrapping `start.py` for the entry point.
|
|
16
|
+
- **Experimental layer-as-importance scoring** (on by default, set `HYATLAS_MEMORY_IMPORTANCE=0` to disable).
|
|
17
|
+
Upstream `hy-memory` ships a 4-factor `MemoryScorer`
|
|
18
|
+
(semantic 0.50 + recency 0.30 + importance 0.15 + access 0.05). The
|
|
19
|
+
`importance` and `access` inputs were never populated by the SDK, so the
|
|
20
|
+
0.15 and 0.05 terms effectively stayed zero. HyAtlas now writes a layer-derived
|
|
21
|
+
`importance` score (l4_identity=1.0, l2_fact=0.8, l3_summary=0.6,
|
|
22
|
+
l0_basic_info=0.5, l1_raw=0.3) on each new memory, restoring the full scorer.
|
|
23
|
+
No LLM cost.
|
|
24
|
+
- **Access-count tracking** (on by default, set `HYATLAS_MEMORY_ACCESS_COUNT=0` to disable).
|
|
25
|
+
Increments `access_count` on every memory returned by a recall operation, so
|
|
26
|
+
the upstream `MemoryScorer` has a live access signal. Runs in a
|
|
27
|
+
fire-and-forget thread so it never blocks recall.
|
|
28
|
+
- Integration tests in `tests/test_integration.py` covering the full local stack: Qdrant + upstream hy-memory server + `HyMemoryProvider`. Backfilled by default-on importance/access-count tracking.
|
|
29
|
+
- `unit` and `integration` pytest markers so CI can run the fast suite without the live stack.
|
|
30
|
+
- Dashboard front-end refactor: split the monolithic `app.js` into `app.js`, `js/l5.js`, and `js/observatory.js` to isolate the L5 knowledge graph and Three.js observatory modules; `server/dashboard/dashboard.py` now serves files under `/js/`.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- **Qdrant auto-detection** — removes hardcoded `C:\qdrant\qdrant.exe`; auto-detects via `QDRANT_BIN` env var → `PATH` → common OS locations. Skips launch if already running (Docker).
|
|
34
|
+
- `pyproject.toml` — `[project.scripts]`, per-file ruff ignores, `long_description_content_type` is now auto-detected from `README.md`.
|
|
35
|
+
- README — Quick Start moved above How It Works; prerequisites table added; `hyatlas` CLI command documented; runtime vs dev install separated.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- `start.py` path resolution broken when invoked via console_scripts (double dirname on `src/` layout).
|
|
39
|
+
- README forcing dev/test deps on normal users (cleanly separated runtime vs dev).
|
|
40
|
+
- Missing `__main__` guard in entry wrapper.
|
|
41
|
+
- Startup script argv not forwarded (documented).
|
|
42
|
+
|
|
43
|
+
## [0.6.0] - 2026-06-18
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
- `start.py` — one-command startup for the full stack (Qdrant → upstream → dashboard)
|
|
47
|
+
- Sequential health checks between each service start
|
|
48
|
+
- Auto-cleanup of stale processes on occupied ports
|
|
49
|
+
- `--stop` and `--status` commands for service management
|
|
50
|
+
- Live status terminal pinned to taskbar (Windows `CREATE_NEW_CONSOLE`)
|
|
51
|
+
- Emoji status header (🧠 Hy-Memory, 📊 Dashboard, 🗄️ Qdrant)
|
|
52
|
+
- Service logs written to `logs/` directory
|
|
53
|
+
- Graceful Ctrl+C shutdown (kills all child processes in reverse order)
|
|
54
|
+
- Crash recovery — auto-restarts a service if it dies during health-check window
|
|
55
|
+
- `CREATE_NO_WINDOW` flag suppresses blank console popups from child processes
|
|
56
|
+
|
|
57
|
+
## [0.5.0] - 2026-06-18
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- Full documentation suite: `docs/DASHBOARD.md`, `docs/API.md`, `docs/LAYERS.md`, `docs/TROUBLESHOOTING.md`
|
|
61
|
+
- `CONTRIBUTING.md` — contributor guidelines
|
|
62
|
+
- `CHANGELOG.md` — this file
|
|
63
|
+
- Social preview images for the GitHub repo
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
- README updated with documentation links and dashboard quick start
|
|
67
|
+
|
|
68
|
+
## [0.4.0] - 2026-06-18
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- Memory Observatory: 3D galaxy visualization with 8 memory layers
|
|
72
|
+
- Observatory entrance animation (nodes fly from center on first load)
|
|
73
|
+
- Observatory scope-change morph animation (cubic ease between zoom levels)
|
|
74
|
+
- Cross-layer edge rendering with warm-gold color + higher opacity
|
|
75
|
+
- Density-based opacity scaling for crowded layers
|
|
76
|
+
- Initial boot screen with HyAtlas logo + progress bar
|
|
77
|
+
- Smooth page transitions (fade + slide) on navigation
|
|
78
|
+
- Galaxy seed loading animation (covers only main content area)
|
|
79
|
+
- HyAtlas branding (proper case "HyAtlas" replaces "HY-MEMORY" / "HYATLAS")
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
- Default Observatory load state: ALL layers + Last 500 scope
|
|
83
|
+
- Legend bar moved outside the 3D canvas
|
|
84
|
+
- `computeObservatoryEdges` rewritten for guaranteed cross-layer connections
|
|
85
|
+
- `computeObservatoryFitZoom` rewritten with proper geometry math
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
- Camera clipping at far plane (increased from 2000 to 8000)
|
|
89
|
+
- Galaxy oversized at large scopes (0.45x scaling for scope > 100)
|
|
90
|
+
- Stale dashboard process cleanup on startup
|
|
91
|
+
|
|
92
|
+
## [0.3.0] - 2026-06-18
|
|
93
|
+
|
|
94
|
+
### Fixed
|
|
95
|
+
- Re-entrant lock deadlock in `sync_turn` (`threading.Lock` → `threading.RLock`)
|
|
96
|
+
- 5-bug chain causing silent cross-session memory write failures
|
|
97
|
+
- `_persist_buffer_to_disk` re-entering the same lock it was already holding
|
|
98
|
+
- `register_memory_tool` crash on `ToolRegistry` with no such method
|
|
99
|
+
- Qdrant storage path mismatch after PC restart (`--config-path` requirement)
|
|
100
|
+
|
|
101
|
+
## [0.2.0] - 2026-06-16
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
- System2 writer with scheduled trigger mode
|
|
105
|
+
- Kuzu graph store for L5 knowledge, L6 schema, L7 intention layers
|
|
106
|
+
- Cross-encoder reranking for recall quality
|
|
107
|
+
- L5 pipeline: 7-step graph rebuild batch job
|
|
108
|
+
|
|
109
|
+
## [0.1.0] - 2026-06-15
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
- Initial release
|
|
113
|
+
- 7-layer memory model (L0 basic info → L7 intention)
|
|
114
|
+
- Hermes Agent plugin via `MemoryProvider` interface
|
|
115
|
+
- Local HTTP dashboard on port 8765
|
|
116
|
+
- Local upstream server on port 19527
|
|
117
|
+
- 9 carried SDK patches (LLMConfig env-loading, cross-encoder rerank, etc.)
|
|
118
|
+
- 4-tier context pressure monitor (fastpath → emergency)
|
|
119
|
+
- `hermes hy-memory` CLI subcommands: `doctor`, `add`, `search`, `list`, `init`, `install`, `reset`
|
|
120
|
+
- Coding memory subsystem (sqlite-backed)
|
|
121
|
+
- 12-test pytest suite
|
|
122
|
+
|
|
123
|
+
### Known limitations
|
|
124
|
+
- `dashboard.html` is a single 3,200-line file
|
|
125
|
+
- No auth on the dashboard (loopback only by design)
|
|
126
|
+
- No docker-compose for the full stack
|
|
127
|
+
- L7 intention layer is experimental, not part of the official Hy-Memory spec
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Versioning policy
|
|
132
|
+
|
|
133
|
+
- **Major (X.0.0)** — breaking changes to the public API (plugin interface, dashboard HTTP API, or data formats)
|
|
134
|
+
- **Minor (0.X.0)** — new features, non-breaking. Layer additions, new CLI subcommands, new dashboard pages
|
|
135
|
+
- **Patch (0.0.X)** — bug fixes, performance improvements, docs
|
|
136
|
+
|
|
137
|
+
## Release cadence
|
|
138
|
+
|
|
139
|
+
There is no fixed release schedule. Releases are cut when:
|
|
140
|
+
1. A meaningful chunk of work has accumulated (5+ merged PRs, or a major feature)
|
|
141
|
+
2. A critical bug fix needs to be pushed
|
|
142
|
+
3. The maintainer feels like it
|
|
143
|
+
|
|
144
|
+
The current maintainer is [@tuancookiez-hub](https://github.com/tuancookiez-hub). If you're a regular contributor and want release-cutter permissions, ask.
|
|
145
|
+
|
|
146
|
+
## Migration guides
|
|
147
|
+
|
|
148
|
+
When a release includes breaking changes, a migration guide is added to `docs/MIGRATION.md`. See the [README](../README.md#migration-from-in-fork-plugin) for the most recent migration from the in-fork plugin version.
|
|
149
|
+
|
|
150
|
+
## Deprecation policy
|
|
151
|
+
|
|
152
|
+
Features are deprecated through one minor release before removal:
|
|
153
|
+
1. Marked deprecated in `CHANGELOG.md` and a `DeprecationWarning` in code
|
|
154
|
+
2. Removed in the next major version
|
|
155
|
+
|
|
156
|
+
The dashboard's HTTP API follows [semver](https://semver.org/) — breaking endpoint changes bump a major version.
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Contributing to HyAtlas-Memory
|
|
2
|
+
|
|
3
|
+
> Thanks for your interest in contributing! This is a community implementation of the official [Hy-Memory framework](https://memory.hunyuan.tencent.com) by Tencent Hunyuan. All contributions are welcome — bug reports, docs, code, tests, and design feedback.
|
|
4
|
+
|
|
5
|
+
## Code of conduct
|
|
6
|
+
|
|
7
|
+
Be respectful. We're all here to build something useful. Disagreements are fine; personal attacks are not. Assume good faith. When in doubt, follow the [Contributor Covenant](https://www.contributor-covenant.org/).
|
|
8
|
+
|
|
9
|
+
## What to work on
|
|
10
|
+
|
|
11
|
+
The easiest ways to help, ordered roughly by impact:
|
|
12
|
+
|
|
13
|
+
1. **Use it and report bugs** — Install, run, hit an edge case, open an issue with reproduction steps
|
|
14
|
+
2. **Improve docs** — If something's unclear, fix it. PRs to `/docs` and `/README.md` are always welcome
|
|
15
|
+
3. **Add tests** — The `tests/` directory could use more coverage
|
|
16
|
+
4. **Add a new memory layer operation** — See "Adding a new feature" below
|
|
17
|
+
5. **Improve the dashboard** — `server/dashboard/dashboard.html` is a single file; refactors welcome
|
|
18
|
+
6. **Port a patch from upstream** — If a newer Hy-Memory SDK fixes something we patch around, port the patch
|
|
19
|
+
|
|
20
|
+
## Reporting bugs
|
|
21
|
+
|
|
22
|
+
Use [GitHub Issues](https://github.com/tuancookiez-hub/HyAtlas-Memory/issues). Include:
|
|
23
|
+
|
|
24
|
+
- **What you did** (exact commands, in order)
|
|
25
|
+
- **What you expected**
|
|
26
|
+
- **What happened** (full error message, screenshot if visual)
|
|
27
|
+
- **Environment:**
|
|
28
|
+
- OS + version
|
|
29
|
+
- Python version (`python --version`)
|
|
30
|
+
- Hermes Agent version (`hermes --version`)
|
|
31
|
+
- Package version (`pip show hyatlas-memory`)
|
|
32
|
+
|
|
33
|
+
For dashboard bugs, also include the browser + version.
|
|
34
|
+
|
|
35
|
+
## Suggesting features
|
|
36
|
+
|
|
37
|
+
Open an issue with the `enhancement` label. Describe:
|
|
38
|
+
- The use case (what you're trying to do)
|
|
39
|
+
- The proposed solution (how it should work)
|
|
40
|
+
- Alternatives you considered
|
|
41
|
+
|
|
42
|
+
If it's a large change (new layer, new store, breaking change), start a discussion first.
|
|
43
|
+
|
|
44
|
+
## Development setup
|
|
45
|
+
|
|
46
|
+
### Prerequisites
|
|
47
|
+
|
|
48
|
+
- Python 3.10+ (3.11+ recommended)
|
|
49
|
+
- [uv](https://github.com/astral-sh/uv) (fast pip alternative) or pip
|
|
50
|
+
- [Qdrant](https://qdrant.tech/) running locally (Docker, native, or via the project's scripts)
|
|
51
|
+
- [Hermes Agent](https://github.com/NousResearch/hermes-agent) installed and on PATH
|
|
52
|
+
- Git
|
|
53
|
+
|
|
54
|
+
### Clone and install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git clone https://github.com/tuancookiez-hub/HyAtlas-Memory.git
|
|
58
|
+
cd HyAtlas-Memory
|
|
59
|
+
|
|
60
|
+
# Editable install with dev + test extras
|
|
61
|
+
uv pip install -e ".[dev,test]"
|
|
62
|
+
# or:
|
|
63
|
+
pip install -e ".[dev,test]"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Start Qdrant
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Docker (easiest)
|
|
70
|
+
docker run -d -p 6333:6333 -p 6334:6334 \
|
|
71
|
+
-v $(pwd)/qdrant_data:/qdrant/storage \
|
|
72
|
+
--name hyatlas-qdrant \
|
|
73
|
+
qdrant/qdrant
|
|
74
|
+
|
|
75
|
+
# Or use the project script (if present)
|
|
76
|
+
python scripts/start_qdrant.py
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Verify:
|
|
80
|
+
```bash
|
|
81
|
+
curl http://127.0.0.1:6333/collections
|
|
82
|
+
# Should return: {"result":{"collections":[]}}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Run tests
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# All tests
|
|
89
|
+
pytest
|
|
90
|
+
|
|
91
|
+
# With coverage
|
|
92
|
+
pytest --cov=hyatlas_memory --cov-report=term-missing
|
|
93
|
+
|
|
94
|
+
# Integration tests only (need a running server)
|
|
95
|
+
pytest -m integration
|
|
96
|
+
|
|
97
|
+
# Specific test
|
|
98
|
+
pytest tests/test_hy_memory_search.py::test_search_basic -v
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Run the linter
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
ruff check src/ tests/
|
|
105
|
+
ruff format src/ tests/ # auto-format
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Run the dashboard
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# In one terminal
|
|
112
|
+
python -m server.start_server
|
|
113
|
+
|
|
114
|
+
# In another
|
|
115
|
+
python server/dashboard/dashboard.py
|
|
116
|
+
# Open http://127.0.0.1:8765
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Run the L5 pipeline
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# This rebuilds the Kuzu graph from scratch — takes minutes
|
|
123
|
+
python server/bin/l5_full_pipeline.py
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Project structure
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
HyAtlas-Memory/
|
|
130
|
+
├── src/hyatlas_memory/ # the plugin (Python package)
|
|
131
|
+
│ ├── __init__.py # HyMemoryProvider — entry point
|
|
132
|
+
│ ├── client.py # HTTP client to upstream
|
|
133
|
+
│ ├── patches.py # 9 SDK patches (applied at import)
|
|
134
|
+
│ ├── context_pressure.py # 4-tier token budget monitor
|
|
135
|
+
│ ├── process.py # subprocess lifecycle
|
|
136
|
+
│ ├── embed_server.py # local embedder
|
|
137
|
+
│ ├── init_wizard.py # first-run setup
|
|
138
|
+
│ ├── installer.py # pip-deps installer
|
|
139
|
+
│ ├── cli.py # `hermes hy-memory ...` subcommands
|
|
140
|
+
│ └── plugin.yaml # legacy manifest
|
|
141
|
+
│
|
|
142
|
+
├── server/ # standalone server
|
|
143
|
+
│ ├── start_server.py # uvicorn launcher
|
|
144
|
+
│ ├── bin/ # L5 pipeline scripts
|
|
145
|
+
│ └── dashboard/ # web UI (port 8765)
|
|
146
|
+
│
|
|
147
|
+
├── tests/ # pytest suite
|
|
148
|
+
├── docs/ # architecture + API + troubleshooting
|
|
149
|
+
├── assets/ # screenshots, infographics
|
|
150
|
+
├── examples/ # usage examples
|
|
151
|
+
└── scripts/ # dev scripts (smoke_test, etc.)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Coding style
|
|
155
|
+
|
|
156
|
+
### Python
|
|
157
|
+
|
|
158
|
+
- **Type hints** on all public functions
|
|
159
|
+
- **Docstrings** on all public modules, classes, functions
|
|
160
|
+
- **No `any`** in type hints — use `Any` if truly needed, but prefer specific types
|
|
161
|
+
- **Imports**: stdlib first, then third-party, then local; alphabetized within each group
|
|
162
|
+
- **Line length**: 100 chars (enforced by ruff)
|
|
163
|
+
- **Quotes**: double quotes for strings, single for short dict keys
|
|
164
|
+
- **Naming**: snake_case for functions/vars, PascalCase for classes, UPPER_SNAKE for constants
|
|
165
|
+
|
|
166
|
+
### JavaScript (dashboard)
|
|
167
|
+
|
|
168
|
+
- **No frameworks** — vanilla JS + Three.js, keep it that way unless absolutely necessary
|
|
169
|
+
- **No build step** — the HTML is served as-is, you must be able to edit and refresh
|
|
170
|
+
- **ES2020+** syntax is fine (the dashboard runs in modern browsers only)
|
|
171
|
+
- **DOM access**: cache `getElementById` results, don't query in hot loops
|
|
172
|
+
- **Event handlers**: clean up on `pagehide` / `beforeunload` to avoid memory leaks
|
|
173
|
+
|
|
174
|
+
### Markdown
|
|
175
|
+
|
|
176
|
+
- **One sentence per line** in source (wraps better in diffs)
|
|
177
|
+
- **Code blocks** with language tags (`bash`, `python`, `json`, etc.)
|
|
178
|
+
- **Links** relative within the repo (`./docs/...`), absolute for external (`https://...`)
|
|
179
|
+
- **Headings**: title case, no trailing period
|
|
180
|
+
|
|
181
|
+
## Testing
|
|
182
|
+
|
|
183
|
+
### When to add a test
|
|
184
|
+
|
|
185
|
+
- New public function in `src/hyatlas_memory/` → add a unit test in `tests/`
|
|
186
|
+
- New API endpoint in `server/dashboard/dashboard.py` → add an integration test
|
|
187
|
+
- Bug fix → add a regression test that fails before your fix
|
|
188
|
+
- New CLI subcommand → add a test for the subcommand
|
|
189
|
+
|
|
190
|
+
### Test conventions
|
|
191
|
+
|
|
192
|
+
- **Test names**: `test_<unit_being_tested>_<scenario>` — e.g., `test_search_with_empty_query_returns_empty`
|
|
193
|
+
- **Use fixtures** for shared setup, not module-level globals
|
|
194
|
+
- **Mock external calls** (Qdrant, upstream server) — tests should run without those running
|
|
195
|
+
- **One assertion per test** when possible (multiple asserts are OK if testing one behavior)
|
|
196
|
+
- **Parametrize** for similar tests with different inputs
|
|
197
|
+
|
|
198
|
+
Example:
|
|
199
|
+
```python
|
|
200
|
+
import pytest
|
|
201
|
+
from hyatlas_memory import search
|
|
202
|
+
|
|
203
|
+
def test_search_returns_results_above_threshold():
|
|
204
|
+
# ...
|
|
205
|
+
results = search("TypeScript", min_score=0.5)
|
|
206
|
+
assert all(r.score >= 0.5 for r in results)
|
|
207
|
+
|
|
208
|
+
@pytest.mark.parametrize("query,expected_empty", [
|
|
209
|
+
("", True),
|
|
210
|
+
(" ", True),
|
|
211
|
+
("!@#$", False), # gibberish might match noise
|
|
212
|
+
])
|
|
213
|
+
def test_search_empty_query(query, expected_empty):
|
|
214
|
+
results = search(query)
|
|
215
|
+
assert (len(results) == 0) == expected_empty
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Adding a new feature
|
|
219
|
+
|
|
220
|
+
### Adding a new memory layer operation
|
|
221
|
+
|
|
222
|
+
1. Add the function in `src/hyatlas_memory/__init__.py` (or a new module)
|
|
223
|
+
2. Add the corresponding HTTP endpoint in `server/dashboard/dashboard.py` if it needs dashboard support
|
|
224
|
+
3. Add a test in `tests/`
|
|
225
|
+
4. Update `docs/LAYERS.md` if it changes layer semantics
|
|
226
|
+
5. Update the dashboard HTML if it needs UI representation
|
|
227
|
+
|
|
228
|
+
### Adding a new API endpoint
|
|
229
|
+
|
|
230
|
+
1. Add a new `if path == "/api/your-endpoint":` branch in `do_GET` / `do_POST`
|
|
231
|
+
2. Use `self._json(status, payload)` to send responses
|
|
232
|
+
3. Document it in `docs/API.md`
|
|
233
|
+
4. Add an integration test in `tests/test_dashboard_api.py` (create if missing)
|
|
234
|
+
|
|
235
|
+
### Adding a new dashboard page
|
|
236
|
+
|
|
237
|
+
1. Add a `<div class="page-section" id="page-yourpage">...</div>` to the HTML
|
|
238
|
+
2. Add a nav item in the sidebar
|
|
239
|
+
3. Add a `renderYourPage()` function called from `renderAll()`
|
|
240
|
+
4. Document it in `docs/DASHBOARD.md`
|
|
241
|
+
|
|
242
|
+
### Adding a new patch
|
|
243
|
+
|
|
244
|
+
Patches fix upstream SDK issues. If you're patching around something in the SDK:
|
|
245
|
+
|
|
246
|
+
1. Add the patch to `src/hyatlas_memory/patches.py`
|
|
247
|
+
2. Make it idempotent (safe to apply multiple times)
|
|
248
|
+
3. Add a comment explaining **what** it fixes and **why** (with a link to the issue if there is one)
|
|
249
|
+
4. Register it in the `patches = [...]` list at the bottom of the file
|
|
250
|
+
5. Add a test that verifies the patch is applied (or at least doesn't error)
|
|
251
|
+
|
|
252
|
+
## Pull request process
|
|
253
|
+
|
|
254
|
+
1. **Fork the repo** and create a branch:
|
|
255
|
+
```bash
|
|
256
|
+
git checkout -b fix/issue-123-search-typo
|
|
257
|
+
# or
|
|
258
|
+
git checkout -b feature/new-layer
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
2. **Make your changes** in small, focused commits:
|
|
262
|
+
```bash
|
|
263
|
+
git add -p # stage hunks, not whole files
|
|
264
|
+
git commit -m "fix(search): handle empty query without crashing
|
|
265
|
+
|
|
266
|
+
Empty queries were throwing AttributeError on .split() because the
|
|
267
|
+
upstream SDK doesn't guard against them. Added a check.
|
|
268
|
+
|
|
269
|
+
Closes #123"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
3. **Run tests + linter locally:**
|
|
273
|
+
```bash
|
|
274
|
+
pytest
|
|
275
|
+
ruff check src/ tests/
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
4. **Push and open a PR:**
|
|
279
|
+
```bash
|
|
280
|
+
git push origin your-branch
|
|
281
|
+
gh pr create --fill # or use the GitHub web UI
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
5. **PR description should include:**
|
|
285
|
+
- What changed and why
|
|
286
|
+
- How to test
|
|
287
|
+
- Screenshots/recordings for UI changes
|
|
288
|
+
- Linked issues (`Closes #123`)
|
|
289
|
+
|
|
290
|
+
6. **Wait for review.** The maintainers will respond within a few days. Be patient — this is a hobby project.
|
|
291
|
+
|
|
292
|
+
### Commit message style
|
|
293
|
+
|
|
294
|
+
Use [Conventional Commits](https://www.conventionalcommits.org/):
|
|
295
|
+
- `feat:` — new feature
|
|
296
|
+
- `fix:` — bug fix
|
|
297
|
+
- `docs:` — docs only
|
|
298
|
+
- `refactor:` — code change that doesn't add a feature or fix a bug
|
|
299
|
+
- `test:` — add or fix tests
|
|
300
|
+
- `chore:` — maintenance (deps, CI, etc.)
|
|
301
|
+
|
|
302
|
+
Scope is optional but helpful: `fix(dashboard): handle empty layer counts`
|
|
303
|
+
|
|
304
|
+
### After your PR is merged
|
|
305
|
+
|
|
306
|
+
- Your contribution will be in the next release's [CHANGELOG.md](CHANGELOG.md)
|
|
307
|
+
- You'll be added to the contributors list (or the GitHub auto-generated one)
|
|
308
|
+
|
|
309
|
+
## Release process
|
|
310
|
+
|
|
311
|
+
The maintainer (currently [@tuancookiez-hub](https://github.com/tuancookiez-hub)) cuts releases:
|
|
312
|
+
|
|
313
|
+
1. Bump version in `pyproject.toml` and `src/hyatlas_memory/_version.py`
|
|
314
|
+
2. Update `CHANGELOG.md` with the release notes
|
|
315
|
+
3. Tag the commit: `git tag -a v0.X.0 -m "Release 0.X.0"`
|
|
316
|
+
4. Push the tag: `git push origin v0.X.0`
|
|
317
|
+
5. Build and publish to PyPI: `uv build && uv publish`
|
|
318
|
+
|
|
319
|
+
## License
|
|
320
|
+
|
|
321
|
+
By contributing, you agree that your contributions will be licensed under the [MIT License](../LICENSE).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tuan Abdullah
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# HyAtlas-Memory — sdist manifest.
|
|
2
|
+
# Ensures files outside the `src/` package tree ship in the source
|
|
3
|
+
# distribution so PyPI users get a usable install (LICENSE, README,
|
|
4
|
+
# docs/, pyproject.toml itself for source installs).
|
|
5
|
+
|
|
6
|
+
include LICENSE
|
|
7
|
+
include README.md
|
|
8
|
+
include CHANGELOG.md
|
|
9
|
+
include CONTRIBUTING.md
|
|
10
|
+
include pyproject.toml
|
|
11
|
+
|
|
12
|
+
recursive-include docs *.md
|
|
13
|
+
recursive-include server/dashboard/templates *.html *.css *.js
|
|
14
|
+
recursive-include server/dashboard/static *.js *.css *.png *.svg
|
|
15
|
+
recursive-include tests *.py
|
|
16
|
+
recursive-include tests *.json
|
|
17
|
+
|
|
18
|
+
# Exclude dev-only scratch from sdist
|
|
19
|
+
exclude scripts/*.py
|
|
20
|
+
exclude .github
|
|
21
|
+
exclude .gitignore
|
|
22
|
+
exclude .dockerignore
|
|
23
|
+
exclude Dockerfile
|
|
24
|
+
exclude docker-compose.yml
|
|
25
|
+
|
|
26
|
+
global-exclude __pycache__
|
|
27
|
+
global-exclude *.pyc
|
|
28
|
+
global-exclude *.pyo
|
|
29
|
+
global-exclude *.pyd
|
|
30
|
+
global-exclude .pytest_cache
|
|
31
|
+
global-exclude .ruff_cache
|
|
32
|
+
global-exclude .mypy_cache
|