hermes-plugin-qdrant-memory 0.2.2__tar.gz → 0.3.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.
Files changed (91) hide show
  1. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/MANIFEST.in +3 -0
  2. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/PKG-INFO +38 -13
  3. hermes_plugin_qdrant_memory-0.2.2/hermes_plugin_qdrant_memory.egg-info/PKG-INFO → hermes_plugin_qdrant_memory-0.3.0/README.md +35 -33
  4. hermes_plugin_qdrant_memory-0.3.0/docs/local-embedding.md +152 -0
  5. hermes_plugin_qdrant_memory-0.2.2/README.md → hermes_plugin_qdrant_memory-0.3.0/hermes_plugin_qdrant_memory.egg-info/PKG-INFO +58 -12
  6. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/SOURCES.txt +22 -1
  7. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/requires.txt +3 -0
  8. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/pyproject.toml +2 -1
  9. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/config.py +14 -3
  10. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/embedding.py +6 -1
  11. hermes_plugin_qdrant_memory-0.3.0/qdrant_memory/local_embedding.py +87 -0
  12. hermes_plugin_qdrant_memory-0.3.0/qdrant_memory/local_model.py +226 -0
  13. hermes_plugin_qdrant_memory-0.3.0/qdrant_memory/managed_setup.py +228 -0
  14. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/plugin.yaml +1 -1
  15. hermes_plugin_qdrant_memory-0.3.0/qdrant_memory/private_paths.py +26 -0
  16. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/reset.py +3 -2
  17. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/standalone.py +35 -2
  18. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/version.py +1 -1
  19. hermes_plugin_qdrant_memory-0.3.0/requirements-local.txt +1080 -0
  20. hermes_plugin_qdrant_memory-0.3.0/requirements.txt +22 -0
  21. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/scripts/demo.sh +48 -10
  22. hermes_plugin_qdrant_memory-0.3.0/tests/__init__.py +1 -0
  23. hermes_plugin_qdrant_memory-0.3.0/tests/conftest.py +39 -0
  24. hermes_plugin_qdrant_memory-0.3.0/tests/helpers.py +101 -0
  25. hermes_plugin_qdrant_memory-0.3.0/tests/local_model/test_acceptance.py +211 -0
  26. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/__init__.py +1 -0
  27. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_explicit_writes.py +109 -0
  28. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_managed_setup.py +332 -0
  29. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_public_api.py +388 -0
  30. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_standalone.py +386 -0
  31. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_ci_gate.py +6 -5
  32. hermes_plugin_qdrant_memory-0.3.0/tests/test_host_pins.py +180 -0
  33. hermes_plugin_qdrant_memory-0.3.0/tests/test_local_embedding.py +148 -0
  34. hermes_plugin_qdrant_memory-0.3.0/tests/test_local_embedding_provider.py +151 -0
  35. hermes_plugin_qdrant_memory-0.3.0/tests/test_local_model.py +208 -0
  36. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_progress.py +4 -1
  37. hermes_plugin_qdrant_memory-0.3.0/tests/test_reset_inspection.py +55 -0
  38. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/LICENSE +0 -0
  39. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/dependency_links.txt +0 -0
  40. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/entry_points.txt +0 -0
  41. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/top_level.txt +0 -0
  42. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/__init__.py +0 -0
  43. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/cli.py +0 -0
  44. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/config_schema.py +0 -0
  45. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/dedupe.py +0 -0
  46. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/extraction.py +0 -0
  47. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/inventory.py +0 -0
  48. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/ledger.py +0 -0
  49. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/mcp_server.py +0 -0
  50. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/migration.py +0 -0
  51. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/models.py +0 -0
  52. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/ownership.py +0 -0
  53. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/progress.py +0 -0
  54. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/provider.py +0 -0
  55. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/qdrant_store.py +0 -0
  56. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/retry.py +0 -0
  57. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/runtime.py +0 -0
  58. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/tools.py +0 -0
  59. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/setup.cfg +0 -0
  60. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_backend_contracts.py +0 -0
  61. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_bot_scope.py +0 -0
  62. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_bounded_recovery.py +0 -0
  63. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_checkpoint_lifecycle.py +0 -0
  64. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_cli_output.py +0 -0
  65. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_config_embedding.py +0 -0
  66. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_deletion_ordering.py +0 -0
  67. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_discovery_cli.py +0 -0
  68. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_explicit_dedupe.py +0 -0
  69. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_host_lifecycle.py +0 -0
  70. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_input_validation.py +0 -0
  71. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_inventory_export.py +0 -0
  72. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_live_metrics.py +0 -0
  73. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_maintenance.py +0 -0
  74. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_manifest_contract.py +0 -0
  75. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration.py +0 -0
  76. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_endpoints.py +0 -0
  77. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_resume.py +0 -0
  78. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_superseded.py +0 -0
  79. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_profile_scope.py +0 -0
  80. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_provider.py +0 -0
  81. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_recovery_benchmark.py +0 -0
  82. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_recovery_evaluation.py +0 -0
  83. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_remote_qdrant.py +0 -0
  84. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_reset_recovery.py +0 -0
  85. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_retention.py +0 -0
  86. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_review_regressions.py +0 -0
  87. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_session_provenance.py +0 -0
  88. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_setup_contract.py +0 -0
  89. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_shutdown_contract.py +0 -0
  90. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_store_runtime.py +0 -0
  91. {hermes_plugin_qdrant_memory-0.2.2 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_writer_ownership.py +0 -0
@@ -4,3 +4,6 @@ prune assets
4
4
 
5
5
  # The text demo script is small and ships with the source distribution.
6
6
  include scripts/demo.sh
7
+ include docs/local-embedding.md
8
+ include requirements.txt requirements-local.txt
9
+ recursive-include tests *.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hermes-plugin-qdrant-memory
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Durable Qdrant memory for Hermes, standalone CLI and local MCP
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/cnkang/hermes-plugin-qdrant-memory
@@ -17,6 +17,8 @@ Requires-Dist: httpx<1,>=0.28
17
17
  Requires-Dist: portalocker<4,>=3.2
18
18
  Provides-Extra: mcp
19
19
  Requires-Dist: mcp<3,>=1.30; extra == "mcp"
20
+ Provides-Extra: local
21
+ Requires-Dist: fastembed==0.9.0; extra == "local"
20
22
  Dynamic: license-file
21
23
 
22
24
  # Qdrant Memory for Hermes
@@ -28,15 +30,20 @@ Dynamic: license-file
28
30
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
29
31
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
30
32
 
31
- > **Runtime 0.2.2** supports MCP Python SDK 1.x and 2.x for the standalone
32
- > CLI/MCP. MCP distribution 0.1.2 pins Runtime 0.2.2. Explicit writes retain
33
- > canonical-text deduplication without an LLM.
33
+ > **Runtime 0.3.0** adds optional offline CPU embedding and trusted setup
34
+ > commands to the standalone CLI/MCP. It supports MCP Python SDK 1.x and 2.x.
35
+ > Explicit writes retain canonical-text deduplication without an LLM.
36
+ > MCP distribution 0.1.3 pins Runtime 0.2.2. The Runtime 0.3.0 update follows
37
+ > in the MCP repository.
34
38
  > The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release
35
39
  > does not upgrade it. One writer per destination remains required.
36
- > See [release notes](docs/releases/0.2.2.md) and [validation](docs/validation.md).
40
+ > See [release notes](docs/releases/0.3.0.md) and [validation](docs/validation.md).
37
41
 
38
42
  [English](README.md) | [简体中文](README.zh-CN.md)
39
43
 
44
+ New in 0.3.0: [optional CPU embedding and guided setup](docs/local-embedding.md)
45
+ adds explicit provider selection without changing Ollama or cloud configurations.
46
+
40
47
  Native long-term memory plugin for Hermes Agent, implemented as a `MemoryProvider`.
41
48
  Hermes performs extraction
42
49
  through its trusted `ctx.llm` facade. Qdrant stores named dense vectors and schema-v1
@@ -48,7 +55,7 @@ as a community-maintained plugin.
48
55
  ## How it works
49
56
 
50
57
  For non-Hermes users, install in a private Python 3.11+
51
- environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.2'` (omit `[mcp]`
58
+ environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.3.0'` (omit `[mcp]`
52
59
  for CLI only). `qdrant-memory` is the CLI and `mcp` is its server subcommand.
53
60
  Standalone does not require Hermes. See [setup and quick start](docs/standalone.md).
54
61
  MCP-focused agents may instead use the [metadata-only distribution](https://github.com/cnkang/qdrant-memory-mcp).
@@ -107,8 +114,8 @@ The published v0.1.0 plugin release does not include the MCP entrypoint.
107
114
 
108
115
  ![Terminal recording: install the plugin, store a preference, and recall it in a new session](https://raw.githubusercontent.com/cnkang/hermes-plugin-qdrant-memory/main/assets/demo.gif)
109
116
 
110
- The recording shows the full flow on a clean profile. It installs from the
111
- official Hermes Plugin Catalog, teaches a preference, and waits for the
117
+ The recording shows the full flow on a clean profile. It installs the
118
+ verified pinned Runtime source, teaches a preference, and waits for the
112
119
  background extraction. Then it recalls the preference in a new session and
113
120
  cleans up the demo scope. All steps
114
121
  run in embedded mode. `scripts/demo.sh` reproduces the same walkthrough with
@@ -141,10 +148,28 @@ The install resolves the catalog's reviewed commit and prints the entry's declar
141
148
  tools, requirements and known issues before it clones anything.
142
149
  `hermes plugins enable` prepares the declared dependencies through Hermes PM.
143
150
 
144
- **Version-locked: install the verified Runtime 0.2.2 source through the Hermes CLI.**
151
+ **Version-locked: install the verified Runtime 0.3.0 source through the Hermes CLI.**
152
+
153
+ This immutable source revision includes the optional CPU embedding and guided
154
+ setup. It does not depend on a PyPI release or a catalog update.
155
+
156
+ ```bash
157
+ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
158
+ ollama pull qwen3-embedding:4b
159
+ # Start Ollama if it is not running. Keep its service available.
160
+ hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
161
+ --ref 7c9e52d816b4f8e8109dbef2797f573b93e0d604 # verified Runtime 0.3.0 source
162
+ hermes plugins enable qdrant-memory
163
+ hermes memory setup
164
+ hermes config set memory.provider qdrant-memory
165
+ hermes qdrant-memory init
166
+ ```
167
+
168
+ **Previous verified source: install Runtime 0.2.2 through the Hermes CLI.**
145
169
 
146
- This immutable source revision includes MCP SDK 1.x/2.x support and the
147
- explicit-write fix. It does not
170
+ This older immutable source revision supports MCP SDK 1.x/2.x and includes the
171
+ explicit-write fix, but it predates the optional CPU embedding and guided setup.
172
+ For the current release use Runtime 0.3.0 above. It does not
148
173
  depend on a PyPI release or a catalog update.
149
174
 
150
175
  ```bash
@@ -152,7 +177,7 @@ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
152
177
  ollama pull qwen3-embedding:4b
153
178
  # Start Ollama if it is not running. Keep its service available.
154
179
  hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
155
- --ref 2fd43ad2259bd98d039394b8b714e5e89b5ab3a8 # verified Runtime 0.2.2 source
180
+ --ref c85d2bce788b117dddd854bb124971f7de8e564c # verified Runtime 0.2.2 source
156
181
  hermes plugins enable qdrant-memory
157
182
  hermes memory setup
158
183
  hermes config set memory.provider qdrant-memory
@@ -169,7 +194,7 @@ environment. Omit `--ref` to track `main`, the development line.
169
194
  **Historical release: clone a published tag manually.**
170
195
 
171
196
  The v0.1.0 tag below predates the standalone interfaces and the explicit-write
172
- fix. Use the pinned source above for Runtime 0.2.2.
197
+ fix. Use the pinned source above for Runtime 0.3.0.
173
198
 
174
199
  ```bash
175
200
  export HERMES_HOME="/absolute/path/to/your/hermes-profile"
@@ -1,24 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: hermes-plugin-qdrant-memory
3
- Version: 0.2.2
4
- Summary: Durable Qdrant memory for Hermes, standalone CLI and local MCP
5
- License-Expression: MIT
6
- Project-URL: Homepage, https://github.com/cnkang/hermes-plugin-qdrant-memory
7
- Project-URL: Repository, https://github.com/cnkang/hermes-plugin-qdrant-memory
8
- Project-URL: Issues, https://github.com/cnkang/hermes-plugin-qdrant-memory/issues
9
- Project-URL: Changelog, https://github.com/cnkang/hermes-plugin-qdrant-memory/blob/main/CHANGELOG.md
10
- Project-URL: MCP, https://github.com/cnkang/qdrant-memory-mcp
11
- Project-URL: Skill, https://github.com/cnkang/skills/tree/main/qdrant-memory
12
- Requires-Python: >=3.11
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
- Requires-Dist: qdrant-client<2,>=1.15
16
- Requires-Dist: httpx<1,>=0.28
17
- Requires-Dist: portalocker<4,>=3.2
18
- Provides-Extra: mcp
19
- Requires-Dist: mcp<3,>=1.30; extra == "mcp"
20
- Dynamic: license-file
21
-
22
1
  # Qdrant Memory for Hermes
23
2
 
24
3
  [![CI](https://github.com/cnkang/hermes-plugin-qdrant-memory/actions/workflows/ci.yml/badge.svg)](https://github.com/cnkang/hermes-plugin-qdrant-memory/actions/workflows/ci.yml)
@@ -28,15 +7,20 @@ Dynamic: license-file
28
7
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
29
8
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
30
9
 
31
- > **Runtime 0.2.2** supports MCP Python SDK 1.x and 2.x for the standalone
32
- > CLI/MCP. MCP distribution 0.1.2 pins Runtime 0.2.2. Explicit writes retain
33
- > canonical-text deduplication without an LLM.
10
+ > **Runtime 0.3.0** adds optional offline CPU embedding and trusted setup
11
+ > commands to the standalone CLI/MCP. It supports MCP Python SDK 1.x and 2.x.
12
+ > Explicit writes retain canonical-text deduplication without an LLM.
13
+ > MCP distribution 0.1.3 pins Runtime 0.2.2. The Runtime 0.3.0 update follows
14
+ > in the MCP repository.
34
15
  > The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release
35
16
  > does not upgrade it. One writer per destination remains required.
36
- > See [release notes](docs/releases/0.2.2.md) and [validation](docs/validation.md).
17
+ > See [release notes](docs/releases/0.3.0.md) and [validation](docs/validation.md).
37
18
 
38
19
  [English](README.md) | [简体中文](README.zh-CN.md)
39
20
 
21
+ New in 0.3.0: [optional CPU embedding and guided setup](docs/local-embedding.md)
22
+ adds explicit provider selection without changing Ollama or cloud configurations.
23
+
40
24
  Native long-term memory plugin for Hermes Agent, implemented as a `MemoryProvider`.
41
25
  Hermes performs extraction
42
26
  through its trusted `ctx.llm` facade. Qdrant stores named dense vectors and schema-v1
@@ -48,7 +32,7 @@ as a community-maintained plugin.
48
32
  ## How it works
49
33
 
50
34
  For non-Hermes users, install in a private Python 3.11+
51
- environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.2'` (omit `[mcp]`
35
+ environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.3.0'` (omit `[mcp]`
52
36
  for CLI only). `qdrant-memory` is the CLI and `mcp` is its server subcommand.
53
37
  Standalone does not require Hermes. See [setup and quick start](docs/standalone.md).
54
38
  MCP-focused agents may instead use the [metadata-only distribution](https://github.com/cnkang/qdrant-memory-mcp).
@@ -107,8 +91,8 @@ The published v0.1.0 plugin release does not include the MCP entrypoint.
107
91
 
108
92
  ![Terminal recording: install the plugin, store a preference, and recall it in a new session](https://raw.githubusercontent.com/cnkang/hermes-plugin-qdrant-memory/main/assets/demo.gif)
109
93
 
110
- The recording shows the full flow on a clean profile. It installs from the
111
- official Hermes Plugin Catalog, teaches a preference, and waits for the
94
+ The recording shows the full flow on a clean profile. It installs the
95
+ verified pinned Runtime source, teaches a preference, and waits for the
112
96
  background extraction. Then it recalls the preference in a new session and
113
97
  cleans up the demo scope. All steps
114
98
  run in embedded mode. `scripts/demo.sh` reproduces the same walkthrough with
@@ -141,10 +125,28 @@ The install resolves the catalog's reviewed commit and prints the entry's declar
141
125
  tools, requirements and known issues before it clones anything.
142
126
  `hermes plugins enable` prepares the declared dependencies through Hermes PM.
143
127
 
144
- **Version-locked: install the verified Runtime 0.2.2 source through the Hermes CLI.**
128
+ **Version-locked: install the verified Runtime 0.3.0 source through the Hermes CLI.**
129
+
130
+ This immutable source revision includes the optional CPU embedding and guided
131
+ setup. It does not depend on a PyPI release or a catalog update.
132
+
133
+ ```bash
134
+ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
135
+ ollama pull qwen3-embedding:4b
136
+ # Start Ollama if it is not running. Keep its service available.
137
+ hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
138
+ --ref 7c9e52d816b4f8e8109dbef2797f573b93e0d604 # verified Runtime 0.3.0 source
139
+ hermes plugins enable qdrant-memory
140
+ hermes memory setup
141
+ hermes config set memory.provider qdrant-memory
142
+ hermes qdrant-memory init
143
+ ```
144
+
145
+ **Previous verified source: install Runtime 0.2.2 through the Hermes CLI.**
145
146
 
146
- This immutable source revision includes MCP SDK 1.x/2.x support and the
147
- explicit-write fix. It does not
147
+ This older immutable source revision supports MCP SDK 1.x/2.x and includes the
148
+ explicit-write fix, but it predates the optional CPU embedding and guided setup.
149
+ For the current release use Runtime 0.3.0 above. It does not
148
150
  depend on a PyPI release or a catalog update.
149
151
 
150
152
  ```bash
@@ -152,7 +154,7 @@ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
152
154
  ollama pull qwen3-embedding:4b
153
155
  # Start Ollama if it is not running. Keep its service available.
154
156
  hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
155
- --ref 2fd43ad2259bd98d039394b8b714e5e89b5ab3a8 # verified Runtime 0.2.2 source
157
+ --ref c85d2bce788b117dddd854bb124971f7de8e564c # verified Runtime 0.2.2 source
156
158
  hermes plugins enable qdrant-memory
157
159
  hermes memory setup
158
160
  hermes config set memory.provider qdrant-memory
@@ -169,7 +171,7 @@ environment. Omit `--ref` to track `main`, the development line.
169
171
  **Historical release: clone a published tag manually.**
170
172
 
171
173
  The v0.1.0 tag below predates the standalone interfaces and the explicit-write
172
- fix. Use the pinned source above for Runtime 0.2.2.
174
+ fix. Use the pinned source above for Runtime 0.3.0.
173
175
 
174
176
  ```bash
175
177
  export HERMES_HOME="/absolute/path/to/your/hermes-profile"
@@ -0,0 +1,152 @@
1
+ # Optional local CPU embedding and guided setup
2
+
3
+ These commands ship with Runtime 0.3.0. Published Runtime 0.2.2 and MCP
4
+ distribution 0.1.3 predate them. Those packages keep their existing
5
+ configuration workflow.
6
+
7
+ ## Choose your embedding provider
8
+
9
+ The existing default remains Ollama. CPU embedding is optional and is never
10
+ selected because Ollama or a cloud service happens to be unavailable. Existing
11
+ profiles, models, fingerprints and collections are not changed by installation.
12
+
13
+ | Choice | Requirements | Model download by this Runtime |
14
+ | --- | --- | --- |
15
+ | Ollama | Running service and installed embedding model | None |
16
+ | OpenAI-compatible | Endpoint, model, dimensions and any required key | None |
17
+ | FastEmbed CPU | Optional `local` extra and explicitly prepared model cache | About 252 MB for the pinned model/tokenizer files |
18
+
19
+ The CPU model is multilingual MiniLM-L12-v2, 384 dimensions, using the
20
+ [Qdrant ONNX artifacts](https://huggingface.co/Qdrant/paraphrase-multilingual-MiniLM-L12-v2-onnx-Q)
21
+ and [FastEmbed](https://qdrant.github.io/fastembed/). The model is listed as
22
+ Apache-2.0. Files are pinned to an immutable model revision and checked against
23
+ exact sizes and SHA-256 values. Dependencies and installed environments require
24
+ additional disk space. No remote Python model code is downloaded or executed.
25
+
26
+ ## Set up a new private profile without editing JSON
27
+
28
+ For a reviewed source checkout, install the desired extras into a virtual
29
+ environment. The `mcp` extra is needed for MCP, while `local` is needed only for
30
+ CPU embedding:
31
+
32
+ ```sh
33
+ python -m pip install '.[mcp,local]'
34
+ ```
35
+
36
+ For a published package, install the same extras with the release version:
37
+
38
+ ```sh
39
+ python -m pip install 'hermes-plugin-qdrant-memory[mcp,local]==0.3.0'
40
+ ```
41
+
42
+ Choose **one** setup command and replace the profile path with a new absolute
43
+ private directory. The command writes the configuration and initializes embedded
44
+ Qdrant using the existing Runtime initialization, writer lease and validation.
45
+ It does not install Python or prepare WorkBuddy's runtime environment.
46
+
47
+ With an existing Ollama model (the `local` extra is unnecessary):
48
+
49
+ ```sh
50
+ qdrant-memory setup --profile /absolute/new-profile --embedding-provider ollama --model qwen3-embedding:4b --dimensions 2560 --agent-id workbuddy
51
+ ```
52
+
53
+ With an explicitly chosen CPU model:
54
+
55
+ ```sh
56
+ qdrant-memory setup --profile /absolute/new-profile --embedding-provider fastembed --agent-id workbuddy
57
+ ```
58
+
59
+ With an OpenAI-compatible embedding service:
60
+
61
+ ```sh
62
+ qdrant-memory setup --profile /absolute/new-profile --embedding-provider openai-compatible --base-url https://embedding.example.com/v1 --model YOUR_MODEL --dimensions YOUR_DIMENSIONS --agent-id workbuddy
63
+ ```
64
+
65
+ Replace the example endpoint/model/dimensions with the service's actual values.
66
+ Provide `EMBEDDING_API_KEY` through a private process environment or a secret
67
+ manager. Do not pass its value as a command argument. To use a different variable
68
+ name, supply `--embedding-api-key-env VARIABLE_NAME`.
69
+
70
+ Use a different profile and `--agent-id` for each client. `--user-id` defaults to
71
+ `local-user`. Self-hosted/Cloud Qdrant storage continues to use the existing
72
+ [configuration workflow](configuration.md); this setup command creates only a
73
+ new embedded destination. A remote embedding choice is distinct from remote
74
+ Qdrant storage.
75
+
76
+ Once setup succeeds, configure the client's stdio command as `qdrant-memory`
77
+ (or the installed `qdrant-memory-mcp` alias), with arguments:
78
+
79
+ ```text
80
+ --home /absolute/new-profile mcp
81
+ ```
82
+
83
+ The MCP tool catalogue remains search, add, update and delete. Model downloads
84
+ and profile creation are trusted CLI operations, not conversational tools.
85
+ WorkBuddy needs the launcher executable on its PATH or its absolute path.
86
+ This source feature alone does not establish marketplace one-click installation.
87
+
88
+ ## Prepare the CPU model separately
89
+
90
+ Installers can download the model before attempting MCP connection:
91
+
92
+ ```sh
93
+ qdrant-memory prepare-model
94
+ ```
95
+
96
+ `--cache-dir /absolute/model-cache` chooses a separate cache. Use the same cache
97
+ with `setup --model-cache-dir /absolute/model-cache`, or set the profile's
98
+ `embedding.model_cache_dir`. The default model-only cache follows platform
99
+ conventions: macOS Library/Caches, Windows LOCALAPPDATA and Linux XDG_CACHE_HOME
100
+ or `~/.cache`. It is separate from memory profiles, Qdrant data and the ledger.
101
+ Managed cache/profile paths must be canonical absolute paths without symlinks
102
+ or Windows reparse points, including intermediate directories.
103
+
104
+ Preparation requires network access and may take several minutes. Start MCP
105
+ after preparation and setup complete; do not place the download inside a
106
+ 30-second connection handshake. Normal provider startup verifies cached files
107
+ and performs no downloads. Prepared CPU inference works offline and does not
108
+ send memory/query text to an embedding service.
109
+
110
+ Downloads use a provisioning lock and a private staging directory. The complete
111
+ cache is published only after every file passes validation. Failed preparation
112
+ can be retried with the same command. A corrupt completed cache is rejected and
113
+ left untouched; it is not silently replaced. Select a new cache directory for
114
+ explicit re-preparation, preserving the old files for diagnosis or recovery.
115
+
116
+ ## Safety, limits and recovery
117
+
118
+ - Repeating the same setup request preserves memories. Setup refuses an unrelated
119
+ directory or a request changing the owned profile's configuration or scope.
120
+ - A failed initialization can be retried with the same settings after fixing its
121
+ dependency/service problem. Existing data is never reset by setup.
122
+ - CPU input is limited to **128 tokens including instruction prefixes**. Longer
123
+ input is rejected rather than silently truncated. Keep facts concise, or choose
124
+ an explicitly configured provider/model supporting longer inputs.
125
+ - Cache location does not change CPU embedding identity. Model revision,
126
+ artifact hashes, preprocessing and the pinned FastEmbed version do.
127
+ - Choosing CPU for a collection created with Ollama or another model is not a
128
+ migration. Existing incompatible collections fail compatibility checks.
129
+ - `LocalModelNotPreparedError`: run explicit preparation with the correct cache.
130
+ - `LocalModelIntegrityError`: do not bypass checks; explicitly prepare a new cache.
131
+ - `LocalEmbeddingUnavailableError`: install the reviewed `local` extra.
132
+ - `ManagedProfileConflictError`: retain the existing profile and choose a new
133
+ directory, or use the existing advanced configuration/maintenance workflow.
134
+
135
+ Ordinary clients may still send recalled text to their chat model. Local embedding
136
+ does not change the client's own data handling. No automatic conversation
137
+ extraction, new network listener or cloud credential custody is introduced.
138
+
139
+ ## Validation boundary
140
+
141
+ Real local CPU inference and offline official-MCP CRUD/restart tests are separate
142
+ from package installation and real WorkBuddy GUI acceptance. The optional local
143
+ embedding workflow tests native Linux x64, Windows x64 and macOS Apple Silicon
144
+ with Python 3.11. macOS Intel is best-effort compatibility and is not a release
145
+ gate or a formally supported CPU platform. A successful dependency resolution
146
+ alone is not a platform support claim. ARM64 variants outside macOS require
147
+ separate acceptance.
148
+
149
+ The optional CPU dependency security snapshot is pinned with artifact hashes in
150
+ `requirements-local.txt`, constrained by the existing base snapshot. CI scans
151
+ both base and optional dependency sets. It does not make CPU packages mandatory
152
+ for normal installations or replace platform/runtime installation acceptance.
@@ -1,3 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: hermes-plugin-qdrant-memory
3
+ Version: 0.3.0
4
+ Summary: Durable Qdrant memory for Hermes, standalone CLI and local MCP
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/cnkang/hermes-plugin-qdrant-memory
7
+ Project-URL: Repository, https://github.com/cnkang/hermes-plugin-qdrant-memory
8
+ Project-URL: Issues, https://github.com/cnkang/hermes-plugin-qdrant-memory/issues
9
+ Project-URL: Changelog, https://github.com/cnkang/hermes-plugin-qdrant-memory/blob/main/CHANGELOG.md
10
+ Project-URL: MCP, https://github.com/cnkang/qdrant-memory-mcp
11
+ Project-URL: Skill, https://github.com/cnkang/skills/tree/main/qdrant-memory
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: qdrant-client<2,>=1.15
16
+ Requires-Dist: httpx<1,>=0.28
17
+ Requires-Dist: portalocker<4,>=3.2
18
+ Provides-Extra: mcp
19
+ Requires-Dist: mcp<3,>=1.30; extra == "mcp"
20
+ Provides-Extra: local
21
+ Requires-Dist: fastembed==0.9.0; extra == "local"
22
+ Dynamic: license-file
23
+
1
24
  # Qdrant Memory for Hermes
2
25
 
3
26
  [![CI](https://github.com/cnkang/hermes-plugin-qdrant-memory/actions/workflows/ci.yml/badge.svg)](https://github.com/cnkang/hermes-plugin-qdrant-memory/actions/workflows/ci.yml)
@@ -7,15 +30,20 @@
7
30
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
8
31
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
9
32
 
10
- > **Runtime 0.2.2** supports MCP Python SDK 1.x and 2.x for the standalone
11
- > CLI/MCP. MCP distribution 0.1.2 pins Runtime 0.2.2. Explicit writes retain
12
- > canonical-text deduplication without an LLM.
33
+ > **Runtime 0.3.0** adds optional offline CPU embedding and trusted setup
34
+ > commands to the standalone CLI/MCP. It supports MCP Python SDK 1.x and 2.x.
35
+ > Explicit writes retain canonical-text deduplication without an LLM.
36
+ > MCP distribution 0.1.3 pins Runtime 0.2.2. The Runtime 0.3.0 update follows
37
+ > in the MCP repository.
13
38
  > The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release
14
39
  > does not upgrade it. One writer per destination remains required.
15
- > See [release notes](docs/releases/0.2.2.md) and [validation](docs/validation.md).
40
+ > See [release notes](docs/releases/0.3.0.md) and [validation](docs/validation.md).
16
41
 
17
42
  [English](README.md) | [简体中文](README.zh-CN.md)
18
43
 
44
+ New in 0.3.0: [optional CPU embedding and guided setup](docs/local-embedding.md)
45
+ adds explicit provider selection without changing Ollama or cloud configurations.
46
+
19
47
  Native long-term memory plugin for Hermes Agent, implemented as a `MemoryProvider`.
20
48
  Hermes performs extraction
21
49
  through its trusted `ctx.llm` facade. Qdrant stores named dense vectors and schema-v1
@@ -27,7 +55,7 @@ as a community-maintained plugin.
27
55
  ## How it works
28
56
 
29
57
  For non-Hermes users, install in a private Python 3.11+
30
- environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.2'` (omit `[mcp]`
58
+ environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.3.0'` (omit `[mcp]`
31
59
  for CLI only). `qdrant-memory` is the CLI and `mcp` is its server subcommand.
32
60
  Standalone does not require Hermes. See [setup and quick start](docs/standalone.md).
33
61
  MCP-focused agents may instead use the [metadata-only distribution](https://github.com/cnkang/qdrant-memory-mcp).
@@ -86,8 +114,8 @@ The published v0.1.0 plugin release does not include the MCP entrypoint.
86
114
 
87
115
  ![Terminal recording: install the plugin, store a preference, and recall it in a new session](https://raw.githubusercontent.com/cnkang/hermes-plugin-qdrant-memory/main/assets/demo.gif)
88
116
 
89
- The recording shows the full flow on a clean profile. It installs from the
90
- official Hermes Plugin Catalog, teaches a preference, and waits for the
117
+ The recording shows the full flow on a clean profile. It installs the
118
+ verified pinned Runtime source, teaches a preference, and waits for the
91
119
  background extraction. Then it recalls the preference in a new session and
92
120
  cleans up the demo scope. All steps
93
121
  run in embedded mode. `scripts/demo.sh` reproduces the same walkthrough with
@@ -120,10 +148,28 @@ The install resolves the catalog's reviewed commit and prints the entry's declar
120
148
  tools, requirements and known issues before it clones anything.
121
149
  `hermes plugins enable` prepares the declared dependencies through Hermes PM.
122
150
 
123
- **Version-locked: install the verified Runtime 0.2.2 source through the Hermes CLI.**
151
+ **Version-locked: install the verified Runtime 0.3.0 source through the Hermes CLI.**
152
+
153
+ This immutable source revision includes the optional CPU embedding and guided
154
+ setup. It does not depend on a PyPI release or a catalog update.
155
+
156
+ ```bash
157
+ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
158
+ ollama pull qwen3-embedding:4b
159
+ # Start Ollama if it is not running. Keep its service available.
160
+ hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
161
+ --ref 7c9e52d816b4f8e8109dbef2797f573b93e0d604 # verified Runtime 0.3.0 source
162
+ hermes plugins enable qdrant-memory
163
+ hermes memory setup
164
+ hermes config set memory.provider qdrant-memory
165
+ hermes qdrant-memory init
166
+ ```
167
+
168
+ **Previous verified source: install Runtime 0.2.2 through the Hermes CLI.**
124
169
 
125
- This immutable source revision includes MCP SDK 1.x/2.x support and the
126
- explicit-write fix. It does not
170
+ This older immutable source revision supports MCP SDK 1.x/2.x and includes the
171
+ explicit-write fix, but it predates the optional CPU embedding and guided setup.
172
+ For the current release use Runtime 0.3.0 above. It does not
127
173
  depend on a PyPI release or a catalog update.
128
174
 
129
175
  ```bash
@@ -131,7 +177,7 @@ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
131
177
  ollama pull qwen3-embedding:4b
132
178
  # Start Ollama if it is not running. Keep its service available.
133
179
  hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
134
- --ref 2fd43ad2259bd98d039394b8b714e5e89b5ab3a8 # verified Runtime 0.2.2 source
180
+ --ref c85d2bce788b117dddd854bb124971f7de8e564c # verified Runtime 0.2.2 source
135
181
  hermes plugins enable qdrant-memory
136
182
  hermes memory setup
137
183
  hermes config set memory.provider qdrant-memory
@@ -148,7 +194,7 @@ environment. Omit `--ref` to track `main`, the development line.
148
194
  **Historical release: clone a published tag manually.**
149
195
 
150
196
  The v0.1.0 tag below predates the standalone interfaces and the explicit-write
151
- fix. Use the pinned source above for Runtime 0.2.2.
197
+ fix. Use the pinned source above for Runtime 0.3.0.
152
198
 
153
199
  ```bash
154
200
  export HERMES_HOME="/absolute/path/to/your/hermes-profile"
@@ -2,6 +2,9 @@ LICENSE
2
2
  MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
+ requirements-local.txt
6
+ requirements.txt
7
+ docs/local-embedding.md
5
8
  hermes_plugin_qdrant_memory.egg-info/PKG-INFO
6
9
  hermes_plugin_qdrant_memory.egg-info/SOURCES.txt
7
10
  hermes_plugin_qdrant_memory.egg-info/dependency_links.txt
@@ -17,11 +20,15 @@ qdrant_memory/embedding.py
17
20
  qdrant_memory/extraction.py
18
21
  qdrant_memory/inventory.py
19
22
  qdrant_memory/ledger.py
23
+ qdrant_memory/local_embedding.py
24
+ qdrant_memory/local_model.py
25
+ qdrant_memory/managed_setup.py
20
26
  qdrant_memory/mcp_server.py
21
27
  qdrant_memory/migration.py
22
28
  qdrant_memory/models.py
23
29
  qdrant_memory/ownership.py
24
30
  qdrant_memory/plugin.yaml
31
+ qdrant_memory/private_paths.py
25
32
  qdrant_memory/progress.py
26
33
  qdrant_memory/provider.py
27
34
  qdrant_memory/qdrant_store.py
@@ -32,6 +39,9 @@ qdrant_memory/standalone.py
32
39
  qdrant_memory/tools.py
33
40
  qdrant_memory/version.py
34
41
  scripts/demo.sh
42
+ tests/__init__.py
43
+ tests/conftest.py
44
+ tests/helpers.py
35
45
  tests/test_backend_contracts.py
36
46
  tests/test_bot_scope.py
37
47
  tests/test_bounded_recovery.py
@@ -43,9 +53,13 @@ tests/test_deletion_ordering.py
43
53
  tests/test_discovery_cli.py
44
54
  tests/test_explicit_dedupe.py
45
55
  tests/test_host_lifecycle.py
56
+ tests/test_host_pins.py
46
57
  tests/test_input_validation.py
47
58
  tests/test_inventory_export.py
48
59
  tests/test_live_metrics.py
60
+ tests/test_local_embedding.py
61
+ tests/test_local_embedding_provider.py
62
+ tests/test_local_model.py
49
63
  tests/test_maintenance.py
50
64
  tests/test_manifest_contract.py
51
65
  tests/test_migration.py
@@ -58,6 +72,7 @@ tests/test_provider.py
58
72
  tests/test_recovery_benchmark.py
59
73
  tests/test_recovery_evaluation.py
60
74
  tests/test_remote_qdrant.py
75
+ tests/test_reset_inspection.py
61
76
  tests/test_reset_recovery.py
62
77
  tests/test_retention.py
63
78
  tests/test_review_regressions.py
@@ -65,4 +80,10 @@ tests/test_session_provenance.py
65
80
  tests/test_setup_contract.py
66
81
  tests/test_shutdown_contract.py
67
82
  tests/test_store_runtime.py
68
- tests/test_writer_ownership.py
83
+ tests/test_writer_ownership.py
84
+ tests/local_model/test_acceptance.py
85
+ tests/standalone/__init__.py
86
+ tests/standalone/test_explicit_writes.py
87
+ tests/standalone/test_managed_setup.py
88
+ tests/standalone/test_public_api.py
89
+ tests/standalone/test_standalone.py
@@ -2,5 +2,8 @@ qdrant-client<2,>=1.15
2
2
  httpx<1,>=0.28
3
3
  portalocker<4,>=3.2
4
4
 
5
+ [local]
6
+ fastembed==0.9.0
7
+
5
8
  [mcp]
6
9
  mcp<3,>=1.30
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hermes-plugin-qdrant-memory"
7
- version = "0.2.2"
7
+ version = "0.3.0"
8
8
  description = "Durable Qdrant memory for Hermes, standalone CLI and local MCP"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -17,6 +17,7 @@ qdrant-memory = "qdrant_memory.standalone:main"
17
17
 
18
18
  [project.optional-dependencies]
19
19
  mcp = ["mcp>=1.30,<3"]
20
+ local = ["fastembed==0.9.0"]
20
21
 
21
22
  [project.urls]
22
23
  Homepage = "https://github.com/cnkang/hermes-plugin-qdrant-memory"
@@ -139,9 +139,14 @@ def validate_embedding(cfg):
139
139
  if cfg["embedding"]["mode"] == "inherit" and not cfg["embedding"].get("inherit_fallback"):
140
140
  raise ValueError("Embedding inheritance requires an explicit fallback")
141
141
  emb = embedding_config(cfg)
142
- if emb["provider"] not in {"ollama", "openai-compatible"}:
142
+ if emb["provider"] not in {"ollama", "openai-compatible", "fastembed"}:
143
143
  raise ValueError("Unsupported embedding provider")
144
- validate_url(emb["base_url"], api_key=emb.get("api_key"))
144
+ if emb["provider"] == "fastembed":
145
+ from .local_model import validate_local_config
146
+
147
+ validate_local_config(emb)
148
+ else:
149
+ validate_url(emb["base_url"], api_key=emb.get("api_key"))
145
150
  if emb["distance"] not in {"Cosine", "Dot", "Euclid"}:
146
151
  raise ValueError("Unsupported distance metric")
147
152
  return emb
@@ -272,7 +277,13 @@ def fingerprint(emb):
272
277
  "send_dimensions",
273
278
  )
274
279
  values = {k: emb.get(k) for k in keys}
275
- if isinstance(values["base_url"], str):
280
+ if emb.get("provider") == "fastembed":
281
+ from .local_model import pipeline_identity
282
+
283
+ values.pop("base_url")
284
+ values.pop("send_dimensions")
285
+ values["local_pipeline"] = pipeline_identity()
286
+ if isinstance(values.get("base_url"), str):
276
287
  values["base_url"] = values["base_url"].rstrip("/")
277
288
  return hashlib.sha256(json.dumps(values, sort_keys=True).encode()).hexdigest()
278
289
 
@@ -111,4 +111,9 @@ def build_embedder(ctx, cfg, *, secret_reader=None):
111
111
  ):
112
112
  raise ValueError("Host embedding facade does not satisfy the plugin contract")
113
113
  return host
114
- return HTTPEmbeddingProvider(embedding_config(cfg), secret_reader=secret_reader)
114
+ selected = embedding_config(cfg)
115
+ if selected["provider"] == "fastembed":
116
+ from .local_embedding import LocalEmbeddingProvider
117
+
118
+ return LocalEmbeddingProvider(selected)
119
+ return HTTPEmbeddingProvider(selected, secret_reader=secret_reader)