hermes-plugin-qdrant-memory 0.2.1__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.1 → hermes_plugin_qdrant_memory-0.3.0}/MANIFEST.in +3 -0
  2. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/PKG-INFO +39 -12
  3. hermes_plugin_qdrant_memory-0.2.1/hermes_plugin_qdrant_memory.egg-info/PKG-INFO → hermes_plugin_qdrant_memory-0.3.0/README.md +35 -31
  4. hermes_plugin_qdrant_memory-0.3.0/docs/local-embedding.md +152 -0
  5. hermes_plugin_qdrant_memory-0.2.1/README.md → hermes_plugin_qdrant_memory-0.3.0/hermes_plugin_qdrant_memory.egg-info/PKG-INFO +58 -10
  6. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/SOURCES.txt +22 -1
  7. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/requires.txt +4 -1
  8. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/pyproject.toml +4 -3
  9. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/config.py +14 -3
  10. {hermes_plugin_qdrant_memory-0.2.1 → 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.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/mcp_server.py +19 -6
  15. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/plugin.yaml +1 -1
  16. hermes_plugin_qdrant_memory-0.3.0/qdrant_memory/private_paths.py +26 -0
  17. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/reset.py +3 -2
  18. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/standalone.py +35 -2
  19. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/version.py +1 -1
  20. hermes_plugin_qdrant_memory-0.3.0/requirements-local.txt +1080 -0
  21. hermes_plugin_qdrant_memory-0.3.0/requirements.txt +22 -0
  22. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/scripts/demo.sh +48 -10
  23. hermes_plugin_qdrant_memory-0.3.0/tests/__init__.py +1 -0
  24. hermes_plugin_qdrant_memory-0.3.0/tests/conftest.py +39 -0
  25. hermes_plugin_qdrant_memory-0.3.0/tests/helpers.py +101 -0
  26. hermes_plugin_qdrant_memory-0.3.0/tests/local_model/test_acceptance.py +211 -0
  27. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/__init__.py +1 -0
  28. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_explicit_writes.py +109 -0
  29. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_managed_setup.py +332 -0
  30. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_public_api.py +388 -0
  31. hermes_plugin_qdrant_memory-0.3.0/tests/standalone/test_standalone.py +386 -0
  32. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_ci_gate.py +9 -5
  33. hermes_plugin_qdrant_memory-0.3.0/tests/test_host_pins.py +180 -0
  34. hermes_plugin_qdrant_memory-0.3.0/tests/test_local_embedding.py +148 -0
  35. hermes_plugin_qdrant_memory-0.3.0/tests/test_local_embedding_provider.py +151 -0
  36. hermes_plugin_qdrant_memory-0.3.0/tests/test_local_model.py +208 -0
  37. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_progress.py +4 -1
  38. hermes_plugin_qdrant_memory-0.3.0/tests/test_reset_inspection.py +55 -0
  39. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/LICENSE +0 -0
  40. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/dependency_links.txt +0 -0
  41. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/entry_points.txt +0 -0
  42. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/hermes_plugin_qdrant_memory.egg-info/top_level.txt +0 -0
  43. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/__init__.py +0 -0
  44. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/cli.py +0 -0
  45. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/config_schema.py +0 -0
  46. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/dedupe.py +0 -0
  47. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/extraction.py +0 -0
  48. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/inventory.py +0 -0
  49. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/ledger.py +0 -0
  50. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/migration.py +0 -0
  51. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/models.py +0 -0
  52. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/ownership.py +0 -0
  53. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/progress.py +0 -0
  54. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/provider.py +0 -0
  55. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/qdrant_store.py +0 -0
  56. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/retry.py +0 -0
  57. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/runtime.py +0 -0
  58. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/qdrant_memory/tools.py +0 -0
  59. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/setup.cfg +0 -0
  60. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_backend_contracts.py +0 -0
  61. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_bot_scope.py +0 -0
  62. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_bounded_recovery.py +0 -0
  63. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_checkpoint_lifecycle.py +0 -0
  64. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_cli_output.py +0 -0
  65. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_config_embedding.py +0 -0
  66. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_deletion_ordering.py +0 -0
  67. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_discovery_cli.py +0 -0
  68. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_explicit_dedupe.py +0 -0
  69. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_host_lifecycle.py +0 -0
  70. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_input_validation.py +0 -0
  71. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_inventory_export.py +0 -0
  72. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_live_metrics.py +0 -0
  73. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_maintenance.py +0 -0
  74. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_manifest_contract.py +0 -0
  75. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration.py +0 -0
  76. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_endpoints.py +0 -0
  77. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_resume.py +0 -0
  78. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_migration_superseded.py +0 -0
  79. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_profile_scope.py +0 -0
  80. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_provider.py +0 -0
  81. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_recovery_benchmark.py +0 -0
  82. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_recovery_evaluation.py +0 -0
  83. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_remote_qdrant.py +0 -0
  84. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_reset_recovery.py +0 -0
  85. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_retention.py +0 -0
  86. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_review_regressions.py +0 -0
  87. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_session_provenance.py +0 -0
  88. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_setup_contract.py +0 -0
  89. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_shutdown_contract.py +0 -0
  90. {hermes_plugin_qdrant_memory-0.2.1 → hermes_plugin_qdrant_memory-0.3.0}/tests/test_store_runtime.py +0 -0
  91. {hermes_plugin_qdrant_memory-0.2.1 → 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.1
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
@@ -16,7 +16,9 @@ Requires-Dist: qdrant-client<2,>=1.15
16
16
  Requires-Dist: httpx<1,>=0.28
17
17
  Requires-Dist: portalocker<4,>=3.2
18
18
  Provides-Extra: mcp
19
- Requires-Dist: mcp<2,>=1.30; extra == "mcp"
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,14 +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.1** provides the standalone CLI/MCP and fixes explicit writes of
32
- > distinct, highly similar texts. MCP distribution 0.1.1 pins Runtime 0.2.1.
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.
33
38
  > The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release
34
39
  > does not upgrade it. One writer per destination remains required.
35
- > See [release notes](docs/releases/0.2.1.md) and [validation](docs/validation.md).
40
+ > See [release notes](docs/releases/0.3.0.md) and [validation](docs/validation.md).
36
41
 
37
42
  [English](README.md) | [简体中文](README.zh-CN.md)
38
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
+
39
47
  Native long-term memory plugin for Hermes Agent, implemented as a `MemoryProvider`.
40
48
  Hermes performs extraction
41
49
  through its trusted `ctx.llm` facade. Qdrant stores named dense vectors and schema-v1
@@ -47,7 +55,7 @@ as a community-maintained plugin.
47
55
  ## How it works
48
56
 
49
57
  For non-Hermes users, install in a private Python 3.11+
50
- environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.1'` (omit `[mcp]`
58
+ environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.3.0'` (omit `[mcp]`
51
59
  for CLI only). `qdrant-memory` is the CLI and `mcp` is its server subcommand.
52
60
  Standalone does not require Hermes. See [setup and quick start](docs/standalone.md).
53
61
  MCP-focused agents may instead use the [metadata-only distribution](https://github.com/cnkang/qdrant-memory-mcp).
@@ -106,8 +114,8 @@ The published v0.1.0 plugin release does not include the MCP entrypoint.
106
114
 
107
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)
108
116
 
109
- The recording shows the full flow on a clean profile. It installs from the
110
- 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
111
119
  background extraction. Then it recalls the preference in a new session and
112
120
  cleans up the demo scope. All steps
113
121
  run in embedded mode. `scripts/demo.sh` reproduces the same walkthrough with
@@ -140,9 +148,28 @@ The install resolves the catalog's reviewed commit and prints the entry's declar
140
148
  tools, requirements and known issues before it clones anything.
141
149
  `hermes plugins enable` prepares the declared dependencies through Hermes PM.
142
150
 
143
- **Version-locked: install the verified Runtime 0.2.1 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.**
144
169
 
145
- This immutable source revision includes the 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
146
173
  depend on a PyPI release or a catalog update.
147
174
 
148
175
  ```bash
@@ -150,7 +177,7 @@ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
150
177
  ollama pull qwen3-embedding:4b
151
178
  # Start Ollama if it is not running. Keep its service available.
152
179
  hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
153
- --ref 8929693fcccd1efa91bfa062145e35d2369ca9cc # verified Runtime 0.2.1 source
180
+ --ref c85d2bce788b117dddd854bb124971f7de8e564c # verified Runtime 0.2.2 source
154
181
  hermes plugins enable qdrant-memory
155
182
  hermes memory setup
156
183
  hermes config set memory.provider qdrant-memory
@@ -167,7 +194,7 @@ environment. Omit `--ref` to track `main`, the development line.
167
194
  **Historical release: clone a published tag manually.**
168
195
 
169
196
  The v0.1.0 tag below predates the standalone interfaces and the explicit-write
170
- fix. Use the pinned source above for Runtime 0.2.1.
197
+ fix. Use the pinned source above for Runtime 0.3.0.
171
198
 
172
199
  ```bash
173
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.1
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<2,>=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,14 +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.1** provides the standalone CLI/MCP and fixes explicit writes of
32
- > distinct, highly similar texts. MCP distribution 0.1.1 pins Runtime 0.2.1.
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.
33
15
  > The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release
34
16
  > does not upgrade it. One writer per destination remains required.
35
- > See [release notes](docs/releases/0.2.1.md) and [validation](docs/validation.md).
17
+ > See [release notes](docs/releases/0.3.0.md) and [validation](docs/validation.md).
36
18
 
37
19
  [English](README.md) | [简体中文](README.zh-CN.md)
38
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
+
39
24
  Native long-term memory plugin for Hermes Agent, implemented as a `MemoryProvider`.
40
25
  Hermes performs extraction
41
26
  through its trusted `ctx.llm` facade. Qdrant stores named dense vectors and schema-v1
@@ -47,7 +32,7 @@ as a community-maintained plugin.
47
32
  ## How it works
48
33
 
49
34
  For non-Hermes users, install in a private Python 3.11+
50
- environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.1'` (omit `[mcp]`
35
+ environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.3.0'` (omit `[mcp]`
51
36
  for CLI only). `qdrant-memory` is the CLI and `mcp` is its server subcommand.
52
37
  Standalone does not require Hermes. See [setup and quick start](docs/standalone.md).
53
38
  MCP-focused agents may instead use the [metadata-only distribution](https://github.com/cnkang/qdrant-memory-mcp).
@@ -106,8 +91,8 @@ The published v0.1.0 plugin release does not include the MCP entrypoint.
106
91
 
107
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)
108
93
 
109
- The recording shows the full flow on a clean profile. It installs from the
110
- 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
111
96
  background extraction. Then it recalls the preference in a new session and
112
97
  cleans up the demo scope. All steps
113
98
  run in embedded mode. `scripts/demo.sh` reproduces the same walkthrough with
@@ -140,9 +125,28 @@ The install resolves the catalog's reviewed commit and prints the entry's declar
140
125
  tools, requirements and known issues before it clones anything.
141
126
  `hermes plugins enable` prepares the declared dependencies through Hermes PM.
142
127
 
143
- **Version-locked: install the verified Runtime 0.2.1 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.**
144
146
 
145
- This immutable source revision includes the 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
146
150
  depend on a PyPI release or a catalog update.
147
151
 
148
152
  ```bash
@@ -150,7 +154,7 @@ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
150
154
  ollama pull qwen3-embedding:4b
151
155
  # Start Ollama if it is not running. Keep its service available.
152
156
  hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
153
- --ref 8929693fcccd1efa91bfa062145e35d2369ca9cc # verified Runtime 0.2.1 source
157
+ --ref c85d2bce788b117dddd854bb124971f7de8e564c # verified Runtime 0.2.2 source
154
158
  hermes plugins enable qdrant-memory
155
159
  hermes memory setup
156
160
  hermes config set memory.provider qdrant-memory
@@ -167,7 +171,7 @@ environment. Omit `--ref` to track `main`, the development line.
167
171
  **Historical release: clone a published tag manually.**
168
172
 
169
173
  The v0.1.0 tag below predates the standalone interfaces and the explicit-write
170
- fix. Use the pinned source above for Runtime 0.2.1.
174
+ fix. Use the pinned source above for Runtime 0.3.0.
171
175
 
172
176
  ```bash
173
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,14 +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.1** provides the standalone CLI/MCP and fixes explicit writes of
11
- > distinct, highly similar texts. MCP distribution 0.1.1 pins Runtime 0.2.1.
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.
12
38
  > The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release
13
39
  > does not upgrade it. One writer per destination remains required.
14
- > See [release notes](docs/releases/0.2.1.md) and [validation](docs/validation.md).
40
+ > See [release notes](docs/releases/0.3.0.md) and [validation](docs/validation.md).
15
41
 
16
42
  [English](README.md) | [简体中文](README.zh-CN.md)
17
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
+
18
47
  Native long-term memory plugin for Hermes Agent, implemented as a `MemoryProvider`.
19
48
  Hermes performs extraction
20
49
  through its trusted `ctx.llm` facade. Qdrant stores named dense vectors and schema-v1
@@ -26,7 +55,7 @@ as a community-maintained plugin.
26
55
  ## How it works
27
56
 
28
57
  For non-Hermes users, install in a private Python 3.11+
29
- environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.1'` (omit `[mcp]`
58
+ environment: `pip install 'hermes-plugin-qdrant-memory[mcp]==0.3.0'` (omit `[mcp]`
30
59
  for CLI only). `qdrant-memory` is the CLI and `mcp` is its server subcommand.
31
60
  Standalone does not require Hermes. See [setup and quick start](docs/standalone.md).
32
61
  MCP-focused agents may instead use the [metadata-only distribution](https://github.com/cnkang/qdrant-memory-mcp).
@@ -85,8 +114,8 @@ The published v0.1.0 plugin release does not include the MCP entrypoint.
85
114
 
86
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)
87
116
 
88
- The recording shows the full flow on a clean profile. It installs from the
89
- 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
90
119
  background extraction. Then it recalls the preference in a new session and
91
120
  cleans up the demo scope. All steps
92
121
  run in embedded mode. `scripts/demo.sh` reproduces the same walkthrough with
@@ -119,9 +148,28 @@ The install resolves the catalog's reviewed commit and prints the entry's declar
119
148
  tools, requirements and known issues before it clones anything.
120
149
  `hermes plugins enable` prepares the declared dependencies through Hermes PM.
121
150
 
122
- **Version-locked: install the verified Runtime 0.2.1 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.**
123
169
 
124
- This immutable source revision includes the 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
125
173
  depend on a PyPI release or a catalog update.
126
174
 
127
175
  ```bash
@@ -129,7 +177,7 @@ export HERMES_HOME="/absolute/path/to/your/hermes-profile"
129
177
  ollama pull qwen3-embedding:4b
130
178
  # Start Ollama if it is not running. Keep its service available.
131
179
  hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
132
- --ref 8929693fcccd1efa91bfa062145e35d2369ca9cc # verified Runtime 0.2.1 source
180
+ --ref c85d2bce788b117dddd854bb124971f7de8e564c # verified Runtime 0.2.2 source
133
181
  hermes plugins enable qdrant-memory
134
182
  hermes memory setup
135
183
  hermes config set memory.provider qdrant-memory
@@ -146,7 +194,7 @@ environment. Omit `--ref` to track `main`, the development line.
146
194
  **Historical release: clone a published tag manually.**
147
195
 
148
196
  The v0.1.0 tag below predates the standalone interfaces and the explicit-write
149
- fix. Use the pinned source above for Runtime 0.2.1.
197
+ fix. Use the pinned source above for Runtime 0.3.0.
150
198
 
151
199
  ```bash
152
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
- mcp<2,>=1.30
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.1"
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"
@@ -16,7 +16,8 @@ dependencies = ["qdrant-client>=1.15,<2", "httpx>=0.28,<1", "portalocker>=3.2,<4
16
16
  qdrant-memory = "qdrant_memory.standalone:main"
17
17
 
18
18
  [project.optional-dependencies]
19
- mcp = ["mcp>=1.30,<2"]
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"
@@ -30,7 +31,7 @@ Skill = "https://github.com/cnkang/skills/tree/main/qdrant-memory"
30
31
  qdrant-memory = "qdrant_memory:register"
31
32
 
32
33
  [dependency-groups]
33
- test = ["pytest>=8,<10", "pytest-cov>=6,<8", "ruamel.yaml>=0.18.16,<0.20", "mcp>=1.30,<2"]
34
+ test = ["pytest>=8,<10", "pytest-cov>=6,<8", "ruamel.yaml>=0.18.16,<0.20", "mcp>=1.30,<3"]
34
35
 
35
36
  [tool.setuptools.packages.find]
36
37
  include = ["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)