memorius 0.9.2__tar.gz → 0.9.4__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.
Files changed (128) hide show
  1. {memorius-0.9.2/memorius.egg-info → memorius-0.9.4}/PKG-INFO +4 -3
  2. {memorius-0.9.2 → memorius-0.9.4}/README.md +1 -1
  3. {memorius-0.9.2 → memorius-0.9.4}/memorius/cli/main.py +7 -1
  4. {memorius-0.9.2 → memorius-0.9.4}/memorius/mcp_server.py +2 -2
  5. {memorius-0.9.2 → memorius-0.9.4}/memorius/single_instance.py +47 -6
  6. {memorius-0.9.2 → memorius-0.9.4}/memorius/vault.py +4 -0
  7. {memorius-0.9.2 → memorius-0.9.4/memorius.egg-info}/PKG-INFO +4 -3
  8. {memorius-0.9.2 → memorius-0.9.4}/memorius.egg-info/requires.txt +1 -1
  9. {memorius-0.9.2 → memorius-0.9.4}/pyproject.toml +3 -2
  10. {memorius-0.9.2 → memorius-0.9.4}/tests/test_integration.py +19 -2
  11. {memorius-0.9.2 → memorius-0.9.4}/LICENSE +0 -0
  12. {memorius-0.9.2 → memorius-0.9.4}/MANIFEST.in +0 -0
  13. {memorius-0.9.2 → memorius-0.9.4}/examples/quickstart.py +0 -0
  14. {memorius-0.9.2 → memorius-0.9.4}/hooks/memorius-hook.sh +0 -0
  15. {memorius-0.9.2 → memorius-0.9.4}/manifest.yaml +0 -0
  16. {memorius-0.9.2 → memorius-0.9.4}/memorius/__init__.py +0 -0
  17. {memorius-0.9.2 → memorius-0.9.4}/memorius/backup.py +0 -0
  18. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/__init__.py +0 -0
  19. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase-layout.js +0 -0
  20. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase-librarian.js +0 -0
  21. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase-scene.js +0 -0
  22. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase-walk.js +0 -0
  23. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase.css +0 -0
  24. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase.html +0 -0
  25. {memorius-0.9.2 → memorius-0.9.4}/memorius/bookcase/bookcase.js +0 -0
  26. {memorius-0.9.2 → memorius-0.9.4}/memorius/cli/__init__.py +0 -0
  27. {memorius-0.9.2 → memorius-0.9.4}/memorius/cli/obsidian.py +0 -0
  28. {memorius-0.9.2 → memorius-0.9.4}/memorius/config.py +0 -0
  29. {memorius-0.9.2 → memorius-0.9.4}/memorius/consolidation.py +0 -0
  30. {memorius-0.9.2 → memorius-0.9.4}/memorius/context_inject.py +0 -0
  31. {memorius-0.9.2 → memorius-0.9.4}/memorius/data/LICENSE +0 -0
  32. {memorius-0.9.2 → memorius-0.9.4}/memorius/data/__init__.py +0 -0
  33. {memorius-0.9.2 → memorius-0.9.4}/memorius/data/examples/__init__.py +0 -0
  34. {memorius-0.9.2 → memorius-0.9.4}/memorius/data/examples/quickstart.py +0 -0
  35. {memorius-0.9.2 → memorius-0.9.4}/memorius/data/manifest.yaml +0 -0
  36. {memorius-0.9.2 → memorius-0.9.4}/memorius/data/memorius-hook.sh +0 -0
  37. {memorius-0.9.2 → memorius-0.9.4}/memorius/doctor.py +0 -0
  38. {memorius-0.9.2 → memorius-0.9.4}/memorius/embeddings.py +0 -0
  39. {memorius-0.9.2 → memorius-0.9.4}/memorius/factcheck.py +0 -0
  40. {memorius-0.9.2 → memorius-0.9.4}/memorius/graph.py +0 -0
  41. {memorius-0.9.2 → memorius-0.9.4}/memorius/graph_visualizer.py +0 -0
  42. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/__init__.py +0 -0
  43. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/__init__.py +0 -0
  44. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/base.py +0 -0
  45. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/claude_code.py +0 -0
  46. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/codex.py +0 -0
  47. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/gemini.py +0 -0
  48. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/generic.py +0 -0
  49. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/openclaude.py +0 -0
  50. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/openclaw.py +0 -0
  51. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/opencode.py +0 -0
  52. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/adapters/pi.py +0 -0
  53. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/cli.py +0 -0
  54. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/engine.py +0 -0
  55. {memorius-0.9.2 → memorius-0.9.4}/memorius/hooks/models.py +0 -0
  56. {memorius-0.9.2 → memorius-0.9.4}/memorius/learning.py +0 -0
  57. {memorius-0.9.2 → memorius-0.9.4}/memorius/llm_extract.py +0 -0
  58. {memorius-0.9.2 → memorius-0.9.4}/memorius/meta_store.py +0 -0
  59. {memorius-0.9.2 → memorius-0.9.4}/memorius/model_download.py +0 -0
  60. {memorius-0.9.2 → memorius-0.9.4}/memorius/models.py +0 -0
  61. {memorius-0.9.2 → memorius-0.9.4}/memorius/normalizers/__init__.py +0 -0
  62. {memorius-0.9.2 → memorius-0.9.4}/memorius/normalizers/cli.py +0 -0
  63. {memorius-0.9.2 → memorius-0.9.4}/memorius/obsidian.py +0 -0
  64. {memorius-0.9.2 → memorius-0.9.4}/memorius/plugin_gen/__init__.py +0 -0
  65. {memorius-0.9.2 → memorius-0.9.4}/memorius/plugin_gen/cli.py +0 -0
  66. {memorius-0.9.2 → memorius-0.9.4}/memorius/reranker.py +0 -0
  67. {memorius-0.9.2 → memorius-0.9.4}/memorius/rest_server.py +0 -0
  68. {memorius-0.9.2 → memorius-0.9.4}/memorius/search_module.py +0 -0
  69. {memorius-0.9.2 → memorius-0.9.4}/memorius/session.py +0 -0
  70. {memorius-0.9.2 → memorius-0.9.4}/memorius/sqlite_vec_store.py +0 -0
  71. {memorius-0.9.2 → memorius-0.9.4}/memorius/store_module.py +0 -0
  72. {memorius-0.9.2 → memorius-0.9.4}/memorius/temporal.py +0 -0
  73. {memorius-0.9.2 → memorius-0.9.4}/memorius/utils.py +0 -0
  74. {memorius-0.9.2 → memorius-0.9.4}/memorius/validation.py +0 -0
  75. {memorius-0.9.2 → memorius-0.9.4}/memorius/vector_store.py +0 -0
  76. {memorius-0.9.2 → memorius-0.9.4}/memorius/vector_store_base.py +0 -0
  77. {memorius-0.9.2 → memorius-0.9.4}/memorius/web_search.py +0 -0
  78. {memorius-0.9.2 → memorius-0.9.4}/memorius.egg-info/SOURCES.txt +0 -0
  79. {memorius-0.9.2 → memorius-0.9.4}/memorius.egg-info/dependency_links.txt +0 -0
  80. {memorius-0.9.2 → memorius-0.9.4}/memorius.egg-info/entry_points.txt +0 -0
  81. {memorius-0.9.2 → memorius-0.9.4}/memorius.egg-info/top_level.txt +0 -0
  82. {memorius-0.9.2 → memorius-0.9.4}/setup.cfg +0 -0
  83. {memorius-0.9.2 → memorius-0.9.4}/tests/test_bm25.py +0 -0
  84. {memorius-0.9.2 → memorius-0.9.4}/tests/test_bookcase.py +0 -0
  85. {memorius-0.9.2 → memorius-0.9.4}/tests/test_cli_json_flag.py +0 -0
  86. {memorius-0.9.2 → memorius-0.9.4}/tests/test_consolidation_daemon.py +0 -0
  87. {memorius-0.9.2 → memorius-0.9.4}/tests/test_core.py +0 -0
  88. {memorius-0.9.2 → memorius-0.9.4}/tests/test_delete.py +0 -0
  89. {memorius-0.9.2 → memorius-0.9.4}/tests/test_domain_modules.py +0 -0
  90. {memorius-0.9.2 → memorius-0.9.4}/tests/test_encoding_regression.py +0 -0
  91. {memorius-0.9.2 → memorius-0.9.4}/tests/test_episodic_semantic_segregation.py +0 -0
  92. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_backup.py +0 -0
  93. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_batch_pagination.py +0 -0
  94. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_consolidation_scaling.py +0 -0
  95. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_contradiction_edges.py +0 -0
  96. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_cors.py +0 -0
  97. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_crud.py +0 -0
  98. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_daemon.py +0 -0
  99. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_doctor.py +0 -0
  100. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_factcheck_access.py +0 -0
  101. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_graph_retrieval.py +0 -0
  102. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_prune.py +0 -0
  103. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_rerank.py +0 -0
  104. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_search_filtering.py +0 -0
  105. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_sqlite_vec.py +0 -0
  106. {memorius-0.9.2 → memorius-0.9.4}/tests/test_feature_ttl.py +0 -0
  107. {memorius-0.9.2 → memorius-0.9.4}/tests/test_features.py +0 -0
  108. {memorius-0.9.2 → memorius-0.9.4}/tests/test_graph.py +0 -0
  109. {memorius-0.9.2 → memorius-0.9.4}/tests/test_graph_temporal.py +0 -0
  110. {memorius-0.9.2 → memorius-0.9.4}/tests/test_graph_visualizer.py +0 -0
  111. {memorius-0.9.2 → memorius-0.9.4}/tests/test_heat_score.py +0 -0
  112. {memorius-0.9.2 → memorius-0.9.4}/tests/test_hooks_engine_mine_dir.py +0 -0
  113. {memorius-0.9.2 → memorius-0.9.4}/tests/test_hybrid_retrieval.py +0 -0
  114. {memorius-0.9.2 → memorius-0.9.4}/tests/test_knowledge_graph_typing.py +0 -0
  115. {memorius-0.9.2 → memorius-0.9.4}/tests/test_learning.py +0 -0
  116. {memorius-0.9.2 → memorius-0.9.4}/tests/test_mcp_stats_graph_keys.py +0 -0
  117. {memorius-0.9.2 → memorius-0.9.4}/tests/test_neuroscience_consolidation.py +0 -0
  118. {memorius-0.9.2 → memorius-0.9.4}/tests/test_polish_regressions.py +0 -0
  119. {memorius-0.9.2 → memorius-0.9.4}/tests/test_regression_bugs.py +0 -0
  120. {memorius-0.9.2 → memorius-0.9.4}/tests/test_repair_vector_meta_drift.py +0 -0
  121. {memorius-0.9.2 → memorius-0.9.4}/tests/test_serve_single_instance.py +0 -0
  122. {memorius-0.9.2 → memorius-0.9.4}/tests/test_single_instance.py +0 -0
  123. {memorius-0.9.2 → memorius-0.9.4}/tests/test_spreading_activation.py +0 -0
  124. {memorius-0.9.2 → memorius-0.9.4}/tests/test_store_module.py +0 -0
  125. {memorius-0.9.2 → memorius-0.9.4}/tests/test_temporal.py +0 -0
  126. {memorius-0.9.2 → memorius-0.9.4}/tests/test_token_efficient_index.py +0 -0
  127. {memorius-0.9.2 → memorius-0.9.4}/tests/test_validation.py +0 -0
  128. {memorius-0.9.2 → memorius-0.9.4}/tests/test_web_search.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorius
3
- Version: 0.9.2
3
+ Version: 0.9.4
4
4
  Summary: Self-contained memory vault for any AI agent — vector search, session diaries, and agent-agnostic hooks.
5
5
  Author-email: dimonapatrick243 <dimona.patrick@gmail.com>
6
6
  License-Expression: MIT
@@ -13,12 +13,13 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
16
17
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
18
  Requires-Python: >=3.11
18
19
  Description-Content-Type: text/markdown
19
20
  License-File: LICENSE
20
21
  Requires-Dist: pyyaml>=6.0.1
21
- Requires-Dist: chromadb>=0.4.22
22
+ Requires-Dist: chromadb<1.0.0,>=0.4.22
22
23
  Requires-Dist: httpx>=0.25.0
23
24
  Requires-Dist: fastapi>=0.104.1
24
25
  Requires-Dist: uvicorn[standard]>=0.24.0
@@ -45,7 +46,7 @@ Dynamic: license-file
45
46
  <a href="https://github.com/Dream-Pixels-Forge/memorius/actions/workflows/release.yml"><img src="https://github.com/Dream-Pixels-Forge/memorius/actions/workflows/release.yml/badge.svg" alt="PyPI publish"></a>
46
47
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
47
48
  <a href="https://python.org"><img src="https://img.shields.io/badge/python-3.11%20%7C%203.12-blue" alt="Python 3.11 | 3.12"></a>
48
- <a href="https://github.com/Dream-Pixels-Forge/memorius/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v0.9.2-green" alt="Changelog"></a>
49
+ <a href="https://github.com/Dream-Pixels-Forge/memorius/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v0.9.3-green" alt="Changelog"></a>
49
50
  </p>
50
51
 
51
52
  > **Works with Claude Code, Codex CLI, Gemini CLI, OpenClaude, OpenCode, Pi, OpenClaw, and any MCP-compatible agent.**
@@ -11,7 +11,7 @@
11
11
  <a href="https://github.com/Dream-Pixels-Forge/memorius/actions/workflows/release.yml"><img src="https://github.com/Dream-Pixels-Forge/memorius/actions/workflows/release.yml/badge.svg" alt="PyPI publish"></a>
12
12
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
13
13
  <a href="https://python.org"><img src="https://img.shields.io/badge/python-3.11%20%7C%203.12-blue" alt="Python 3.11 | 3.12"></a>
14
- <a href="https://github.com/Dream-Pixels-Forge/memorius/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v0.9.2-green" alt="Changelog"></a>
14
+ <a href="https://github.com/Dream-Pixels-Forge/memorius/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v0.9.3-green" alt="Changelog"></a>
15
15
  </p>
16
16
 
17
17
  > **Works with Claude Code, Codex CLI, Gemini CLI, OpenClaude, OpenCode, Pi, OpenClaw, and any MCP-compatible agent.**
@@ -125,6 +125,11 @@ def main():
125
125
 
126
126
  serve_p = subparsers.add_parser("serve", help="Start MCP server (stdio)")
127
127
  serve_p.add_argument("--port", type=int, default=8911, help="Not used for stdio")
128
+ serve_p.add_argument(
129
+ "--reclaim",
130
+ action="store_true",
131
+ help="Reclaim the lock from an orphaned memorius serve instance",
132
+ )
128
133
 
129
134
  serve_rest_p = subparsers.add_parser("serve-rest", help="Start REST API server")
130
135
  serve_rest_p.add_argument("--port", type=int, default=None, help="Port")
@@ -347,7 +352,7 @@ def main():
347
352
  )
348
353
 
349
354
  try:
350
- _serve_lock = acquire_serve_lock(config)
355
+ _serve_lock = acquire_serve_lock(config, reclaim=getattr(args, "reclaim", False))
351
356
  except ServeAlreadyRunningError as exc:
352
357
  print(
353
358
  f"memorius: {exc}",
@@ -355,6 +360,7 @@ def main():
355
360
  )
356
361
  print(
357
362
  f" Stop that instance (kill {exc.pid} or stop its MCP host) and retry,\n"
363
+ f" or rerun with `memorius serve --reclaim` to take over an orphaned instance,\n"
358
364
  f" or point this instance at a different storage path via MEMORIUS_STORAGE_PATH.",
359
365
  file=sys.stderr,
360
366
  )
@@ -133,7 +133,7 @@ class McpServer:
133
133
  "properties": {
134
134
  "vault": {"type": "string", "description": "Filter by vault (default: all)"},
135
135
  "similarity_threshold": {"type": "number", "description": "Similarity threshold 0-1 (default: 0.80)", "default": 0.80},
136
- "dry_run": {"type": "boolean", "description": "Preview without changes (default: false)", "default": False},
136
+ "dry_run": {"type": "boolean", "description": "Preview without changes (default: true)", "default": True},
137
137
  },
138
138
  },
139
139
  },
@@ -620,7 +620,7 @@ class McpServer:
620
620
  result = self._engine.consolidate(
621
621
  vault=args.get("vault"),
622
622
  similarity_threshold=args.get("similarity_threshold", 0.80),
623
- dry_run=args.get("dry_run", False),
623
+ dry_run=args.get("dry_run", True),
624
624
  )
625
625
  return {
626
626
  "clusters_found": result.clusters_found,
@@ -106,10 +106,12 @@ def _pid_alive(pid: int) -> bool:
106
106
  return True
107
107
 
108
108
 
109
- def acquire_serve_lock(config: dict[str, Any]) -> ServeLock:
109
+ def acquire_serve_lock(config: dict[str, Any], reclaim: bool = False) -> ServeLock:
110
110
  """Acquire the single-instance guard lock for the configured storage dir.
111
111
 
112
- Raises ``ServeAlreadyRunningError`` when a live incumbent holds it.
112
+ Raises ``ServeAlreadyRunningError`` when a live incumbent holds it and
113
+ ``reclaim`` is false. When ``reclaim`` is true, an orphaned live holder
114
+ is terminated and the lock is taken over.
113
115
  On platforms without ``fcntl`` returns an unlocked no-op handle after
114
116
  logging a warning (the guard is unavailable, but serve still works).
115
117
  """
@@ -132,10 +134,15 @@ def acquire_serve_lock(config: dict[str, Any]) -> ServeLock:
132
134
  os.close(fd)
133
135
  last_pid = _read_lock_pid(lock_path)
134
136
  # A dead holder's flock was already released by the kernel:
135
- # retry and steal. A live holder: fail with its PID.
136
- if last_pid is not None and _pid_alive(last_pid):
137
- raise ServeAlreadyRunningError(last_pid, lock_path) from None
138
- continue
137
+ # retry and steal.
138
+ if last_pid is None or not _pid_alive(last_pid):
139
+ continue
140
+ # Live holder: reclaim if requested (orphaned memorius serve),
141
+ # otherwise fail.
142
+ if reclaim and _is_memorius_serve(last_pid):
143
+ _reclaim_lock(last_pid)
144
+ continue
145
+ raise ServeAlreadyRunningError(last_pid, lock_path) from None
139
146
  except OSError:
140
147
  os.close(fd)
141
148
  raise
@@ -151,3 +158,37 @@ def acquire_serve_lock(config: dict[str, Any]) -> ServeLock:
151
158
  raise ServeAlreadyRunningError(
152
159
  last_pid if last_pid is not None else os.getpid(), lock_path
153
160
  )
161
+
162
+
163
+ def _is_memorius_serve(pid: int) -> bool:
164
+ """True when /proc/<pid>/cmdline indicates a `memorius serve` process."""
165
+ try:
166
+ cmdline = Path(f"/proc/{pid}/cmdline").read_bytes().replace(b"\x00", b" ")
167
+ except OSError:
168
+ return False
169
+ return b"memorius" in cmdline and b"serve" in cmdline
170
+
171
+
172
+ def _reclaim_lock(pid: int) -> None:
173
+ """Terminate an orphaned `memorius serve` holder so the lock can be taken."""
174
+ import signal
175
+ import time
176
+
177
+ logger.warning(
178
+ "reclaiming serve lock held by orphaned memorius serve (PID %d)", pid
179
+ )
180
+ try:
181
+ os.kill(pid, signal.SIGTERM)
182
+ except OSError:
183
+ return # already gone
184
+ # Wait up to ~3s for the kernel to release the flock on exit.
185
+ for _ in range(30):
186
+ try:
187
+ os.kill(pid, 0)
188
+ except OSError:
189
+ return # gone
190
+ time.sleep(0.1)
191
+ try:
192
+ os.kill(pid, signal.SIGKILL)
193
+ except OSError:
194
+ pass
@@ -42,6 +42,10 @@ class VaultEngine:
42
42
  """
43
43
 
44
44
  def __init__(self, config: dict[str, Any] | None = None):
45
+ # Class-level default so close()/__del__ on a half-initialized
46
+ # engine (e.g. EmbeddingFactory raising in __init__) can't crash
47
+ # with AttributeError and mask the real error.
48
+ self._consolidation_daemon = None
45
49
  self._config = config or load_config()
46
50
  embed_cfg = self._config.get("embeddings", {})
47
51
  storage_cfg = self._config.get("storage", {})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memorius
3
- Version: 0.9.2
3
+ Version: 0.9.4
4
4
  Summary: Self-contained memory vault for any AI agent — vector search, session diaries, and agent-agnostic hooks.
5
5
  Author-email: dimonapatrick243 <dimona.patrick@gmail.com>
6
6
  License-Expression: MIT
@@ -13,12 +13,13 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
16
17
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
18
  Requires-Python: >=3.11
18
19
  Description-Content-Type: text/markdown
19
20
  License-File: LICENSE
20
21
  Requires-Dist: pyyaml>=6.0.1
21
- Requires-Dist: chromadb>=0.4.22
22
+ Requires-Dist: chromadb<1.0.0,>=0.4.22
22
23
  Requires-Dist: httpx>=0.25.0
23
24
  Requires-Dist: fastapi>=0.104.1
24
25
  Requires-Dist: uvicorn[standard]>=0.24.0
@@ -45,7 +46,7 @@ Dynamic: license-file
45
46
  <a href="https://github.com/Dream-Pixels-Forge/memorius/actions/workflows/release.yml"><img src="https://github.com/Dream-Pixels-Forge/memorius/actions/workflows/release.yml/badge.svg" alt="PyPI publish"></a>
46
47
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
47
48
  <a href="https://python.org"><img src="https://img.shields.io/badge/python-3.11%20%7C%203.12-blue" alt="Python 3.11 | 3.12"></a>
48
- <a href="https://github.com/Dream-Pixels-Forge/memorius/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v0.9.2-green" alt="Changelog"></a>
49
+ <a href="https://github.com/Dream-Pixels-Forge/memorius/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v0.9.3-green" alt="Changelog"></a>
49
50
  </p>
50
51
 
51
52
  > **Works with Claude Code, Codex CLI, Gemini CLI, OpenClaude, OpenCode, Pi, OpenClaw, and any MCP-compatible agent.**
@@ -1,5 +1,5 @@
1
1
  pyyaml>=6.0.1
2
- chromadb>=0.4.22
2
+ chromadb<1.0.0,>=0.4.22
3
3
  httpx>=0.25.0
4
4
  fastapi>=0.104.1
5
5
  uvicorn[standard]>=0.24.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "memorius"
3
- version = "0.9.2"
3
+ version = "0.9.4"
4
4
  description = "Self-contained memory vault for any AI agent — vector search, session diaries, and agent-agnostic hooks."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -15,12 +15,13 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3",
16
16
  "Programming Language :: Python :: 3.11",
17
17
  "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
18
19
  "Topic :: Scientific/Engineering :: Artificial Intelligence",
19
20
  ]
20
21
 
21
22
  dependencies = [
22
23
  "pyyaml>=6.0.1",
23
- "chromadb>=0.4.22",
24
+ "chromadb>=0.4.22,<1.0.0",
24
25
  "httpx>=0.25.0",
25
26
  "fastapi>=0.104.1",
26
27
  "uvicorn[standard]>=0.24.0",
@@ -3,6 +3,7 @@
3
3
  import json
4
4
  import os
5
5
  import shutil
6
+ import site
6
7
  import subprocess
7
8
  import sys
8
9
  import tempfile
@@ -11,6 +12,11 @@ from pathlib import Path
11
12
 
12
13
  import pytest
13
14
 
15
+ # Resolve the real user site-packages BEFORE any fixture overrides HOME —
16
+ # once HOME points at a temp dir, site.getusersitepackages() returns the
17
+ # (useless) fake path and deps installed in ~/.local become unimportable.
18
+ _USER_SITE = site.getusersitepackages()
19
+
14
20
 
15
21
  def _safe_rmtree(path):
16
22
  """rmtree tolerant of Windows file locks.
@@ -40,6 +46,18 @@ def isolated_env():
40
46
  # Sandbox HOME so memorius init writes to ~/.memorius inside tmpdir
41
47
  fake_home = Path(tmpdir) / "home"
42
48
  fake_home.mkdir()
49
+ # chromadb's default ONNX embedding function hardcodes its cache at
50
+ # ~/.cache/chroma/onnx_models (no env override), and memorius's own
51
+ # pre-download checks ~/.cache/memorius/onnx_models — a sandboxed
52
+ # HOME makes both miss and re-download ~80MB from S3 per test.
53
+ # Reuse the developer's real (read-only, immutable) caches when
54
+ # present; on CI they don't exist and chromadb downloads as before.
55
+ for rel in (".cache/chroma/onnx_models", ".cache/memorius/onnx_models"):
56
+ real_cache = Path(old_home) / rel
57
+ if real_cache.is_dir():
58
+ link_parent = fake_home / Path(rel).parent
59
+ link_parent.mkdir(parents=True)
60
+ (link_parent / Path(rel).name).symlink_to(real_cache)
43
61
  os.environ["HOME"] = str(fake_home)
44
62
  os.environ["MEMORIUS_STORAGE_PATH"] = str(Path(tmpdir) / "data")
45
63
 
@@ -64,8 +82,7 @@ def run_memorius(*args, env=None, input_text=None, timeout=180):
64
82
  # When HOME is overridden in tests, Python's user site-packages shifts
65
83
  # to the fake HOME, breaking imports of dependencies like chromadb.
66
84
  src_dir = str(Path(__file__).resolve().parent.parent)
67
- import site
68
- user_site = site.getusersitepackages()
85
+ user_site = _USER_SITE
69
86
  merged_env = {**os.environ, **(env or {})}
70
87
  existing_pp = merged_env.get("PYTHONPATH", "")
71
88
  extra = os.pathsep.join([src_dir, user_site])
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
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
File without changes