cognee-integration-hermes-agent 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. cognee_integration_hermes_agent-1.0.0/PKG-INFO +324 -0
  2. cognee_integration_hermes_agent-1.0.0/README.md +315 -0
  3. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/__init__.py +10 -0
  4. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/_plugin_root/after-install.md +21 -0
  5. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/_plugin_root/cli.py +14 -0
  6. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/_plugin_root/plugin.yaml +14 -0
  7. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/backend.py +565 -0
  8. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/cli.py +121 -0
  9. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/config.py +205 -0
  10. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/exit_watcher.py +461 -0
  11. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/http_backend.py +549 -0
  12. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/installer.py +85 -0
  13. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/provider.py +954 -0
  14. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/schemas.py +84 -0
  15. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes/server_bootstrap.py +172 -0
  16. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes_agent.egg-info/PKG-INFO +324 -0
  17. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes_agent.egg-info/SOURCES.txt +34 -0
  18. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes_agent.egg-info/dependency_links.txt +1 -0
  19. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes_agent.egg-info/entry_points.txt +5 -0
  20. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes_agent.egg-info/requires.txt +1 -0
  21. cognee_integration_hermes_agent-1.0.0/cognee_integration_hermes_agent.egg-info/top_level.txt +1 -0
  22. cognee_integration_hermes_agent-1.0.0/pyproject.toml +41 -0
  23. cognee_integration_hermes_agent-1.0.0/setup.cfg +4 -0
  24. cognee_integration_hermes_agent-1.0.0/tests/test_config_contract.py +425 -0
  25. cognee_integration_hermes_agent-1.0.0/tests/test_dim_mismatch.py +152 -0
  26. cognee_integration_hermes_agent-1.0.0/tests/test_exit_watcher.py +493 -0
  27. cognee_integration_hermes_agent-1.0.0/tests/test_http_backend.py +735 -0
  28. cognee_integration_hermes_agent-1.0.0/tests/test_installer.py +110 -0
  29. cognee_integration_hermes_agent-1.0.0/tests/test_integration_concurrency.py +135 -0
  30. cognee_integration_hermes_agent-1.0.0/tests/test_integration_roundtrip.py +301 -0
  31. cognee_integration_hermes_agent-1.0.0/tests/test_lifecycle_contract.py +666 -0
  32. cognee_integration_hermes_agent-1.0.0/tests/test_recall_wire_contract.py +126 -0
  33. cognee_integration_hermes_agent-1.0.0/tests/test_sdk_backend.py +240 -0
  34. cognee_integration_hermes_agent-1.0.0/tests/test_server_mode.py +618 -0
  35. cognee_integration_hermes_agent-1.0.0/tests/test_smoke.py +70 -0
  36. cognee_integration_hermes_agent-1.0.0/tests/test_tool_contract.py +384 -0
@@ -0,0 +1,324 @@
1
+ Metadata-Version: 2.4
2
+ Name: cognee-integration-hermes-agent
3
+ Version: 1.0.0
4
+ Summary: Standalone Cognee memory provider plugin for Hermes Agent.
5
+ Author: Cognee team
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: cognee<=1.4.0,>=1.2.1
9
+
10
+ # Cognee Memory Plugin for Hermes Agent
11
+
12
+ Standalone Hermes memory provider backed by Cognee.
13
+
14
+ This replaces the closed in-tree Hermes PR path. Hermes no longer accepts new
15
+ providers under `plugins/memory/`; this integration is shaped as a standalone
16
+ plugin that can be installed into `~/.hermes/plugins/cognee` or distributed as a
17
+ Python package with the `hermes_agent.plugins` entry point.
18
+
19
+ ## Features
20
+
21
+ - Stores each completed Hermes turn in Cognee session memory.
22
+ - Uses `cognee_recall` for session-first recall with graph fallback.
23
+ - Exposes `cognee_remember` for durable graph memory.
24
+ - Exposes `cognee_forget` for deletion requests.
25
+ - Runs `cognee.improve()` at Hermes session end to bridge session memory into the graph.
26
+ - Mirrors explicit Hermes memory writes through `on_memory_write`.
27
+ - Supports local embedded Cognee and remote Cognee service mode.
28
+ - Closes every session out of process, the way the other cognee plugins do: a
29
+ detached worker bridges the session into the graph and only then unregisters
30
+ from the server. Exiting Hermes never waits on a graph build, and the promotion
31
+ is never cut short by the server retiring. The same worker covers an uncleanly
32
+ died Hermes, so no session is lost and no server lingers either way.
33
+
34
+ ## Quick start
35
+
36
+ ### Prerequisites
37
+
38
+ - [Hermes Agent](https://github.com/NousResearch/hermes-agent) installed
39
+ (`curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash`).
40
+ - **Local mode:** an LLM API key (e.g. OpenAI) — cognee uses it to build the
41
+ knowledge graph on your machine.
42
+ - **Cloud mode:** a Cognee Cloud tenant URL and API key from your
43
+ [Cognee Cloud dashboard](https://platform.cognee.ai/). No LLM key needed —
44
+ the tenant runs the models.
45
+
46
+ ### 1. Install the plugin
47
+
48
+ Via pip (recommended):
49
+
50
+ ```bash
51
+ pip install cognee-integration-hermes-agent
52
+ cognee-hermes-install
53
+ ```
54
+
55
+ Hermes discovers plugins by scanning `~/.hermes/plugins/`, so the second
56
+ command copies the plugin there — `pip install` alone is not enough, and after
57
+ a `pip install -U` you re-run `cognee-hermes-install` to update the copy
58
+ (`hermes cognee status` reminds you when the two drift).
59
+
60
+ Or from a checkout of this repository:
61
+
62
+ ```bash
63
+ git clone https://github.com/topoteretes/cognee-integrations.git
64
+ mkdir -p ~/.hermes/plugins/cognee
65
+ cp -R cognee-integrations/integrations/hermes-agent/. ~/.hermes/plugins/cognee/
66
+ ```
67
+
68
+ ### 2a. Connect locally (default)
69
+
70
+ ```bash
71
+ hermes memory setup
72
+ ```
73
+
74
+ Select `cognee` in the provider picker, choose **Mode: local**, and paste your
75
+ LLM API key when asked. That's the whole setup — the wizard writes non-secrets
76
+ to `~/.hermes/cognee.json` and secrets to `~/.hermes/.env`.
77
+
78
+ On your next `hermes` session the plugin starts a cognee server on
79
+ `127.0.0.1:8011` — or attaches to one that a sibling cognee plugin (Claude
80
+ Code, Codex, OpenClaw) already runs — with storage in `~/.cognee`. The very
81
+ first boot runs database migrations and can take a couple of minutes; after
82
+ that it's instant.
83
+
84
+ Verify it's connected:
85
+
86
+ ```bash
87
+ hermes cognee status # shows mode, dataset, service URL
88
+ curl -s http://127.0.0.1:8011/health # the server answers
89
+ ```
90
+
91
+ Then, in a `hermes` chat: *"Remember that my favorite editor is Helix"* — the
92
+ agent should call `cognee_remember`. Start a fresh conversation (`/new`) and
93
+ ask *"What's my favorite editor?"* — it should recall it via `cognee_recall`.
94
+
95
+ ### 2b. Connect to Cognee Cloud
96
+
97
+ Grab your tenant URL (`https://tenant-xxx.aws.cognee.ai`) and an API key from
98
+ the [Cognee Cloud dashboard](https://platform.cognee.ai/), then run the same
99
+ wizard and choose **Mode: remote**:
100
+
101
+ ```bash
102
+ hermes memory setup # cognee -> Mode: remote -> tenant URL + API key
103
+ ```
104
+
105
+ Verify: `hermes cognee status` shows your tenant URL, and the same
106
+ remember-`/new`-recall chat round trip works. Nothing runs locally in this
107
+ mode — no server is spawned and no LLM key is used; every request goes to the
108
+ tenant, authenticated with your API key via `X-Api-Key`.
109
+
110
+ > **Switching modes? Re-run the wizard.** Values in `~/.hermes/cognee.json`
111
+ > take precedence over environment variables, and a local setup records
112
+ > `"service_url": ""` there — so *only* exporting `COGNEE_BASE_URL` will not
113
+ > move an existing local install to the cloud. `hermes memory setup` (or
114
+ > `hermes cognee setup`) rewrites both files consistently.
115
+
116
+ ## How the pip install works
117
+
118
+ Hermes has no entry-point plugin discovery (yet) — it scans
119
+ `$HERMES_HOME/plugins/` for directories with a `plugin.yaml`. The wheel
120
+ therefore ships the plugin-root files as package data and provides the
121
+ `cognee-hermes-install` console script, which materializes the exact directory
122
+ shape the scanner expects. Because Hermes runs that *copy*, upgrading is always
123
+ two steps: `pip install -U cognee-integration-hermes-agent`, then
124
+ `cognee-hermes-install` again.
125
+
126
+ The package also declares the entry point Hermes would use if it grows native
127
+ discovery, at which point the copy step becomes unnecessary:
128
+
129
+ ```toml
130
+ [project.entry-points."hermes_agent.plugins"]
131
+ cognee = "cognee_integration_hermes"
132
+ ```
133
+
134
+ Releases are published from CI on `hermes-agent-v*` tags
135
+ (`.github/workflows/hermes-agent-publish.yml`).
136
+
137
+ ## Configuration
138
+
139
+ The quick start above covers the common cases; this section is the full
140
+ reference. Configuration comes from two places: `$HERMES_HOME/.env` (secrets
141
+ and environment variables — Hermes loads it for every session) and
142
+ `$HERMES_HOME/cognee.json` (non-secret settings). The setup wizard writes both.
143
+ When a key appears in both places, **the JSON file wins** — which is why mode
144
+ switches should go through the wizard rather than editing the environment
145
+ alone.
146
+
147
+ ### Modes
148
+
149
+ The provider connects to cognee in one of three modes. It picks the mode
150
+ automatically from your config:
151
+
152
+ | Mode | When it's used | How it talks to cognee |
153
+ | --- | --- | --- |
154
+ | **local-server** (default) | no `COGNEE_BASE_URL`, `COGNEE_EMBEDDED` unset | ensures a local cognee server is running and connects as a thin client |
155
+ | **remote** | `COGNEE_BASE_URL` is set | thin client to your managed / cloud cognee |
156
+ | **embedded** | `COGNEE_EMBEDDED=true` | runs cognee in-process |
157
+
158
+ **Why local-server is the default.** cognee's local stores (SQLite, Kuzu/Ladybug,
159
+ LanceDB) are single-writer. Driving them in-process from the agent's background
160
+ threads — or from a second Hermes process sharing the same `data_root` — risks
161
+ `database is locked` errors and corruption. A local cognee server is the single
162
+ owner that serializes all access, so the agent just makes HTTP calls. This is the
163
+ same design the Claude Code and Codex plugins use. **`embedded` is opt-in and is
164
+ safe for single-process / offline use only.**
165
+
166
+ **No silent fallbacks.** The provider never downgrades modes behind your back. If
167
+ `COGNEE_BASE_URL` is set but unreachable, or the local server fails to start,
168
+ initialization raises rather than quietly switching to a different mode — silent
169
+ fallback would either mask a config error (remote → local data divergence) or
170
+ reintroduce the very DB-lock risk this design removes (local-server → embedded).
171
+ To accept the single-process trade-off, set `COGNEE_EMBEDDED=true` explicitly.
172
+ And if initialization does fail, memory stays *off*: Hermes logs the error and
173
+ starts anyway, so the provider refuses every call rather than operating a
174
+ half-connected backend.
175
+
176
+ ### Transports
177
+
178
+ Mode decides *where* cognee is; the transport decides *how* the plugin talks to it.
179
+
180
+ | Transport | Selected by | What it does |
181
+ | --- | --- | --- |
182
+ | **http** (default) | nothing to set | builds requests against cognee's REST API directly, using only the standard library |
183
+ | **sdk** | `COGNEE_TRANSPORT=sdk`, or any `COGNEE_EMBEDDED=true` | drives the `cognee` Python package, via `cognee.serve()` when a server is involved |
184
+
185
+ Direct HTTP is the default because it is what the Claude Code, Codex and OpenClaw
186
+ plugins do, and because the SDK's `CloudClient` drops fields the server accepts —
187
+ most importantly `session_ids` on `improve()`, which is what promotes a session's
188
+ turns into the permanent graph. Two consequences worth knowing:
189
+
190
+ - The `cognee` package is still required. It is what the local server runs, and it
191
+ is the only way to run without a server at all (`COGNEE_EMBEDDED=true`).
192
+ - Over HTTP, a `cognee_remember` write cannot be linked to the session it came
193
+ from — `/api/v1/remember` has no field for it. Session-to-graph bridging is
194
+ unaffected. The plugin logs this once rather than dropping it silently.
195
+
196
+ > **Upgrading from 0.1.x — three defaults moved to match the other cognee
197
+ > plugins.** The local port changed from 8000 to 8011 (leaving cognee's own
198
+ > default of 8000 to servers you start yourself); the default dataset changed
199
+ > from `hermes` to the shared `agent_sessions`; and local storage now defaults to
200
+ > the shared `~/.cognee/{data,system}` instead of cognee's global default. Your
201
+ > old memory is not deleted, but a recall against the new dataset/roots will not
202
+ > see it — set `COGNEE_DATASET=hermes` (or migrate the data) and, if an old
203
+ > plugin-started server is still listening on 8000, **stop it**: two servers
204
+ > sharing one data directory is exactly the single-writer contention this mode
205
+ > exists to avoid. `COGNEE_LOCAL_PORT=8000` restores the old port.
206
+
207
+ ### One brain across agents
208
+
209
+ By default this plugin joins the same memory the Claude Code, Codex and OpenClaw
210
+ cognee plugins share: the same dataset (`agent_sessions`), the same local storage
211
+ (`~/.cognee/{data,system}`), the same server port (8011) and the same minted API
212
+ key (`~/.cognee-plugin/api_key.json`). Whichever plugin boots the server first,
213
+ the rest attach to it — and a fact remembered in Claude Code is recallable in
214
+ Hermes, and vice versa. To keep Hermes (or one Hermes profile) apart instead, give
215
+ it its own `COGNEE_PLUGIN_DATASET`, or for full isolation its own
216
+ `COGNEE_DATA_ROOT` / `COGNEE_SYSTEM_ROOT` *and* `COGNEE_LOCAL_PORT` — a server
217
+ belongs to whoever reaches its port first, so a private store needs a private
218
+ port.
219
+
220
+ The per-mode settings below live in `~/.hermes/.env` (the wizard puts them
221
+ there; you can also edit the file by hand).
222
+
223
+ local-server mode (default — just set your LLM creds):
224
+
225
+ ```bash
226
+ LLM_API_KEY=sk-...
227
+ LLM_MODEL=gpt-4o-mini
228
+ # COGNEE_PLUGIN_DATASET=agent_sessions # optional; the default is shared with the other plugins
229
+ # COGNEE_LOCAL_PORT=8011 # optional; the other plugins' server port
230
+ ```
231
+
232
+ Remote / cloud mode (tenant URL and API key from the
233
+ [Cognee Cloud dashboard](https://platform.cognee.ai/)):
234
+
235
+ ```bash
236
+ COGNEE_BASE_URL=https://tenant-xxx.aws.cognee.ai # canonical name
237
+ COGNEE_API_KEY=...
238
+ ```
239
+
240
+ > **`COGNEE_API_KEY` is mandatory for any remote server.** On a local server the
241
+ > plugin mints a key on first use (a one-time login as the default user); remote
242
+ > servers — Cognee Cloud included — expose no login route, so there is nothing to
243
+ > mint with. A remote `COGNEE_BASE_URL` without a key fails at startup with a
244
+ > clear error rather than a 401 on every call.
245
+
246
+ Embedded (in-process) mode — single-process / offline only:
247
+
248
+ ```bash
249
+ COGNEE_EMBEDDED=true
250
+ LLM_API_KEY=sk-...
251
+ ```
252
+
253
+ > **Embedded mode and the shared store do not mix.** Embedded drives the local
254
+ > single-writer databases from inside the Hermes process; if another plugin's
255
+ > server (or another process) is using `~/.cognee` at the same time, that is
256
+ > exactly the contention embedded mode is warned about. For embedded use, point
257
+ > `COGNEE_DATA_ROOT` / `COGNEE_SYSTEM_ROOT` at a private location.
258
+
259
+ ### Optional settings
260
+
261
+ | Setting | Env var | Default |
262
+ | --- | --- | --- |
263
+ | `dataset` | `COGNEE_PLUGIN_DATASET` (canonical) | `agent_sessions` |
264
+ | `top_k` | `COGNEE_TOP_K` | `5` |
265
+ | `auto_route` | `COGNEE_AUTO_ROUTE` | `true` |
266
+ | `improve_on_end` | `COGNEE_IMPROVE_ON_END` | `true` |
267
+ | `improve_background` | `COGNEE_IMPROVE_BACKGROUND` | auto |
268
+ | `session_prefix` | `COGNEE_SESSION_PREFIX` | `hermes` |
269
+ | `service_url` | `COGNEE_BASE_URL` (canonical) | empty |
270
+ | `embedded` | `COGNEE_EMBEDDED` | `false` |
271
+ | `local_port` | `COGNEE_LOCAL_PORT` | `8011` |
272
+ | `server_boot_timeout` | `COGNEE_SERVER_BOOT_TIMEOUT` | `600` |
273
+ | `data_root` | `COGNEE_DATA_ROOT` | `~/.cognee/data` |
274
+ | `system_root` | `COGNEE_SYSTEM_ROOT` | `~/.cognee/system` |
275
+
276
+ > **Storage is shared, and a server is per port.** The roots above are the ones
277
+ > every cognee agent plugin pins, so the store is the same no matter which plugin
278
+ > booted the server on 8011. Because the default roots live outside
279
+ > `HERMES_HOME`, `backup_paths()` reports them to `hermes backup` — a profile
280
+ > backup deliberately includes the machine's shared memory store. Roots you point
281
+ > elsewhere with `COGNEE_DATA_ROOT` / `COGNEE_SYSTEM_ROOT` are reported the same
282
+ > way (unless they sit inside `HERMES_HOME`, which `hermes backup` walks anyway).
283
+
284
+ > `COGNEE_SERVICE_URL` is a deprecated alias for `COGNEE_BASE_URL`, and
285
+ > `COGNEE_DATASET` (the 0.1.x name) a lower-precedence alias for
286
+ > `COGNEE_PLUGIN_DATASET`. Both still work; new setups should use the canonical
287
+ > names.
288
+
289
+ > **`improve_background`** decides where the session-end graph build
290
+ > (`improve()`) runs. Default `auto`: whenever a server is involved, the close is
291
+ > handed to a **detached worker** — the same process that already covers crashes —
292
+ > which runs `improve()` to completion and only then unregisters the agent
293
+ > connection. Hermes exits immediately; nothing waits on the graph build. That
294
+ > ordering is required, not stylistic: the local server runs with
295
+ > `COGNEE_AGENT_MODE=true` and retires itself within 60s of the last agent
296
+ > unregistering, so unregistering first would kill the promotion halfway. In
297
+ > `embedded` mode there is no server and no worker, so the build runs in-process
298
+ > and synchronously — it dies with the process otherwise.
299
+ >
300
+ > Setting `COGNEE_IMPROVE_BACKGROUND=true|false` opts out of the handoff and does
301
+ > the work in-process: `true` submits the build and returns (right for a
302
+ > cloud/remote server nothing here can shut down; on a local server it
303
+ > reintroduces the race above), `false` blocks Hermes' exit until the build
304
+ > finishes.
305
+
306
+ ## Hermes Commands
307
+
308
+ When Cognee is the active memory provider:
309
+
310
+ ```bash
311
+ hermes cognee status
312
+ hermes cognee setup
313
+ hermes cognee config
314
+ hermes cognee install
315
+ ```
316
+
317
+ ## Development
318
+
319
+ ```bash
320
+ cd integrations/hermes-agent
321
+ uv sync --dev
322
+ uv run pytest -q
323
+ uv run ruff check .
324
+ ```
@@ -0,0 +1,315 @@
1
+ # Cognee Memory Plugin for Hermes Agent
2
+
3
+ Standalone Hermes memory provider backed by Cognee.
4
+
5
+ This replaces the closed in-tree Hermes PR path. Hermes no longer accepts new
6
+ providers under `plugins/memory/`; this integration is shaped as a standalone
7
+ plugin that can be installed into `~/.hermes/plugins/cognee` or distributed as a
8
+ Python package with the `hermes_agent.plugins` entry point.
9
+
10
+ ## Features
11
+
12
+ - Stores each completed Hermes turn in Cognee session memory.
13
+ - Uses `cognee_recall` for session-first recall with graph fallback.
14
+ - Exposes `cognee_remember` for durable graph memory.
15
+ - Exposes `cognee_forget` for deletion requests.
16
+ - Runs `cognee.improve()` at Hermes session end to bridge session memory into the graph.
17
+ - Mirrors explicit Hermes memory writes through `on_memory_write`.
18
+ - Supports local embedded Cognee and remote Cognee service mode.
19
+ - Closes every session out of process, the way the other cognee plugins do: a
20
+ detached worker bridges the session into the graph and only then unregisters
21
+ from the server. Exiting Hermes never waits on a graph build, and the promotion
22
+ is never cut short by the server retiring. The same worker covers an uncleanly
23
+ died Hermes, so no session is lost and no server lingers either way.
24
+
25
+ ## Quick start
26
+
27
+ ### Prerequisites
28
+
29
+ - [Hermes Agent](https://github.com/NousResearch/hermes-agent) installed
30
+ (`curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash`).
31
+ - **Local mode:** an LLM API key (e.g. OpenAI) — cognee uses it to build the
32
+ knowledge graph on your machine.
33
+ - **Cloud mode:** a Cognee Cloud tenant URL and API key from your
34
+ [Cognee Cloud dashboard](https://platform.cognee.ai/). No LLM key needed —
35
+ the tenant runs the models.
36
+
37
+ ### 1. Install the plugin
38
+
39
+ Via pip (recommended):
40
+
41
+ ```bash
42
+ pip install cognee-integration-hermes-agent
43
+ cognee-hermes-install
44
+ ```
45
+
46
+ Hermes discovers plugins by scanning `~/.hermes/plugins/`, so the second
47
+ command copies the plugin there — `pip install` alone is not enough, and after
48
+ a `pip install -U` you re-run `cognee-hermes-install` to update the copy
49
+ (`hermes cognee status` reminds you when the two drift).
50
+
51
+ Or from a checkout of this repository:
52
+
53
+ ```bash
54
+ git clone https://github.com/topoteretes/cognee-integrations.git
55
+ mkdir -p ~/.hermes/plugins/cognee
56
+ cp -R cognee-integrations/integrations/hermes-agent/. ~/.hermes/plugins/cognee/
57
+ ```
58
+
59
+ ### 2a. Connect locally (default)
60
+
61
+ ```bash
62
+ hermes memory setup
63
+ ```
64
+
65
+ Select `cognee` in the provider picker, choose **Mode: local**, and paste your
66
+ LLM API key when asked. That's the whole setup — the wizard writes non-secrets
67
+ to `~/.hermes/cognee.json` and secrets to `~/.hermes/.env`.
68
+
69
+ On your next `hermes` session the plugin starts a cognee server on
70
+ `127.0.0.1:8011` — or attaches to one that a sibling cognee plugin (Claude
71
+ Code, Codex, OpenClaw) already runs — with storage in `~/.cognee`. The very
72
+ first boot runs database migrations and can take a couple of minutes; after
73
+ that it's instant.
74
+
75
+ Verify it's connected:
76
+
77
+ ```bash
78
+ hermes cognee status # shows mode, dataset, service URL
79
+ curl -s http://127.0.0.1:8011/health # the server answers
80
+ ```
81
+
82
+ Then, in a `hermes` chat: *"Remember that my favorite editor is Helix"* — the
83
+ agent should call `cognee_remember`. Start a fresh conversation (`/new`) and
84
+ ask *"What's my favorite editor?"* — it should recall it via `cognee_recall`.
85
+
86
+ ### 2b. Connect to Cognee Cloud
87
+
88
+ Grab your tenant URL (`https://tenant-xxx.aws.cognee.ai`) and an API key from
89
+ the [Cognee Cloud dashboard](https://platform.cognee.ai/), then run the same
90
+ wizard and choose **Mode: remote**:
91
+
92
+ ```bash
93
+ hermes memory setup # cognee -> Mode: remote -> tenant URL + API key
94
+ ```
95
+
96
+ Verify: `hermes cognee status` shows your tenant URL, and the same
97
+ remember-`/new`-recall chat round trip works. Nothing runs locally in this
98
+ mode — no server is spawned and no LLM key is used; every request goes to the
99
+ tenant, authenticated with your API key via `X-Api-Key`.
100
+
101
+ > **Switching modes? Re-run the wizard.** Values in `~/.hermes/cognee.json`
102
+ > take precedence over environment variables, and a local setup records
103
+ > `"service_url": ""` there — so *only* exporting `COGNEE_BASE_URL` will not
104
+ > move an existing local install to the cloud. `hermes memory setup` (or
105
+ > `hermes cognee setup`) rewrites both files consistently.
106
+
107
+ ## How the pip install works
108
+
109
+ Hermes has no entry-point plugin discovery (yet) — it scans
110
+ `$HERMES_HOME/plugins/` for directories with a `plugin.yaml`. The wheel
111
+ therefore ships the plugin-root files as package data and provides the
112
+ `cognee-hermes-install` console script, which materializes the exact directory
113
+ shape the scanner expects. Because Hermes runs that *copy*, upgrading is always
114
+ two steps: `pip install -U cognee-integration-hermes-agent`, then
115
+ `cognee-hermes-install` again.
116
+
117
+ The package also declares the entry point Hermes would use if it grows native
118
+ discovery, at which point the copy step becomes unnecessary:
119
+
120
+ ```toml
121
+ [project.entry-points."hermes_agent.plugins"]
122
+ cognee = "cognee_integration_hermes"
123
+ ```
124
+
125
+ Releases are published from CI on `hermes-agent-v*` tags
126
+ (`.github/workflows/hermes-agent-publish.yml`).
127
+
128
+ ## Configuration
129
+
130
+ The quick start above covers the common cases; this section is the full
131
+ reference. Configuration comes from two places: `$HERMES_HOME/.env` (secrets
132
+ and environment variables — Hermes loads it for every session) and
133
+ `$HERMES_HOME/cognee.json` (non-secret settings). The setup wizard writes both.
134
+ When a key appears in both places, **the JSON file wins** — which is why mode
135
+ switches should go through the wizard rather than editing the environment
136
+ alone.
137
+
138
+ ### Modes
139
+
140
+ The provider connects to cognee in one of three modes. It picks the mode
141
+ automatically from your config:
142
+
143
+ | Mode | When it's used | How it talks to cognee |
144
+ | --- | --- | --- |
145
+ | **local-server** (default) | no `COGNEE_BASE_URL`, `COGNEE_EMBEDDED` unset | ensures a local cognee server is running and connects as a thin client |
146
+ | **remote** | `COGNEE_BASE_URL` is set | thin client to your managed / cloud cognee |
147
+ | **embedded** | `COGNEE_EMBEDDED=true` | runs cognee in-process |
148
+
149
+ **Why local-server is the default.** cognee's local stores (SQLite, Kuzu/Ladybug,
150
+ LanceDB) are single-writer. Driving them in-process from the agent's background
151
+ threads — or from a second Hermes process sharing the same `data_root` — risks
152
+ `database is locked` errors and corruption. A local cognee server is the single
153
+ owner that serializes all access, so the agent just makes HTTP calls. This is the
154
+ same design the Claude Code and Codex plugins use. **`embedded` is opt-in and is
155
+ safe for single-process / offline use only.**
156
+
157
+ **No silent fallbacks.** The provider never downgrades modes behind your back. If
158
+ `COGNEE_BASE_URL` is set but unreachable, or the local server fails to start,
159
+ initialization raises rather than quietly switching to a different mode — silent
160
+ fallback would either mask a config error (remote → local data divergence) or
161
+ reintroduce the very DB-lock risk this design removes (local-server → embedded).
162
+ To accept the single-process trade-off, set `COGNEE_EMBEDDED=true` explicitly.
163
+ And if initialization does fail, memory stays *off*: Hermes logs the error and
164
+ starts anyway, so the provider refuses every call rather than operating a
165
+ half-connected backend.
166
+
167
+ ### Transports
168
+
169
+ Mode decides *where* cognee is; the transport decides *how* the plugin talks to it.
170
+
171
+ | Transport | Selected by | What it does |
172
+ | --- | --- | --- |
173
+ | **http** (default) | nothing to set | builds requests against cognee's REST API directly, using only the standard library |
174
+ | **sdk** | `COGNEE_TRANSPORT=sdk`, or any `COGNEE_EMBEDDED=true` | drives the `cognee` Python package, via `cognee.serve()` when a server is involved |
175
+
176
+ Direct HTTP is the default because it is what the Claude Code, Codex and OpenClaw
177
+ plugins do, and because the SDK's `CloudClient` drops fields the server accepts —
178
+ most importantly `session_ids` on `improve()`, which is what promotes a session's
179
+ turns into the permanent graph. Two consequences worth knowing:
180
+
181
+ - The `cognee` package is still required. It is what the local server runs, and it
182
+ is the only way to run without a server at all (`COGNEE_EMBEDDED=true`).
183
+ - Over HTTP, a `cognee_remember` write cannot be linked to the session it came
184
+ from — `/api/v1/remember` has no field for it. Session-to-graph bridging is
185
+ unaffected. The plugin logs this once rather than dropping it silently.
186
+
187
+ > **Upgrading from 0.1.x — three defaults moved to match the other cognee
188
+ > plugins.** The local port changed from 8000 to 8011 (leaving cognee's own
189
+ > default of 8000 to servers you start yourself); the default dataset changed
190
+ > from `hermes` to the shared `agent_sessions`; and local storage now defaults to
191
+ > the shared `~/.cognee/{data,system}` instead of cognee's global default. Your
192
+ > old memory is not deleted, but a recall against the new dataset/roots will not
193
+ > see it — set `COGNEE_DATASET=hermes` (or migrate the data) and, if an old
194
+ > plugin-started server is still listening on 8000, **stop it**: two servers
195
+ > sharing one data directory is exactly the single-writer contention this mode
196
+ > exists to avoid. `COGNEE_LOCAL_PORT=8000` restores the old port.
197
+
198
+ ### One brain across agents
199
+
200
+ By default this plugin joins the same memory the Claude Code, Codex and OpenClaw
201
+ cognee plugins share: the same dataset (`agent_sessions`), the same local storage
202
+ (`~/.cognee/{data,system}`), the same server port (8011) and the same minted API
203
+ key (`~/.cognee-plugin/api_key.json`). Whichever plugin boots the server first,
204
+ the rest attach to it — and a fact remembered in Claude Code is recallable in
205
+ Hermes, and vice versa. To keep Hermes (or one Hermes profile) apart instead, give
206
+ it its own `COGNEE_PLUGIN_DATASET`, or for full isolation its own
207
+ `COGNEE_DATA_ROOT` / `COGNEE_SYSTEM_ROOT` *and* `COGNEE_LOCAL_PORT` — a server
208
+ belongs to whoever reaches its port first, so a private store needs a private
209
+ port.
210
+
211
+ The per-mode settings below live in `~/.hermes/.env` (the wizard puts them
212
+ there; you can also edit the file by hand).
213
+
214
+ local-server mode (default — just set your LLM creds):
215
+
216
+ ```bash
217
+ LLM_API_KEY=sk-...
218
+ LLM_MODEL=gpt-4o-mini
219
+ # COGNEE_PLUGIN_DATASET=agent_sessions # optional; the default is shared with the other plugins
220
+ # COGNEE_LOCAL_PORT=8011 # optional; the other plugins' server port
221
+ ```
222
+
223
+ Remote / cloud mode (tenant URL and API key from the
224
+ [Cognee Cloud dashboard](https://platform.cognee.ai/)):
225
+
226
+ ```bash
227
+ COGNEE_BASE_URL=https://tenant-xxx.aws.cognee.ai # canonical name
228
+ COGNEE_API_KEY=...
229
+ ```
230
+
231
+ > **`COGNEE_API_KEY` is mandatory for any remote server.** On a local server the
232
+ > plugin mints a key on first use (a one-time login as the default user); remote
233
+ > servers — Cognee Cloud included — expose no login route, so there is nothing to
234
+ > mint with. A remote `COGNEE_BASE_URL` without a key fails at startup with a
235
+ > clear error rather than a 401 on every call.
236
+
237
+ Embedded (in-process) mode — single-process / offline only:
238
+
239
+ ```bash
240
+ COGNEE_EMBEDDED=true
241
+ LLM_API_KEY=sk-...
242
+ ```
243
+
244
+ > **Embedded mode and the shared store do not mix.** Embedded drives the local
245
+ > single-writer databases from inside the Hermes process; if another plugin's
246
+ > server (or another process) is using `~/.cognee` at the same time, that is
247
+ > exactly the contention embedded mode is warned about. For embedded use, point
248
+ > `COGNEE_DATA_ROOT` / `COGNEE_SYSTEM_ROOT` at a private location.
249
+
250
+ ### Optional settings
251
+
252
+ | Setting | Env var | Default |
253
+ | --- | --- | --- |
254
+ | `dataset` | `COGNEE_PLUGIN_DATASET` (canonical) | `agent_sessions` |
255
+ | `top_k` | `COGNEE_TOP_K` | `5` |
256
+ | `auto_route` | `COGNEE_AUTO_ROUTE` | `true` |
257
+ | `improve_on_end` | `COGNEE_IMPROVE_ON_END` | `true` |
258
+ | `improve_background` | `COGNEE_IMPROVE_BACKGROUND` | auto |
259
+ | `session_prefix` | `COGNEE_SESSION_PREFIX` | `hermes` |
260
+ | `service_url` | `COGNEE_BASE_URL` (canonical) | empty |
261
+ | `embedded` | `COGNEE_EMBEDDED` | `false` |
262
+ | `local_port` | `COGNEE_LOCAL_PORT` | `8011` |
263
+ | `server_boot_timeout` | `COGNEE_SERVER_BOOT_TIMEOUT` | `600` |
264
+ | `data_root` | `COGNEE_DATA_ROOT` | `~/.cognee/data` |
265
+ | `system_root` | `COGNEE_SYSTEM_ROOT` | `~/.cognee/system` |
266
+
267
+ > **Storage is shared, and a server is per port.** The roots above are the ones
268
+ > every cognee agent plugin pins, so the store is the same no matter which plugin
269
+ > booted the server on 8011. Because the default roots live outside
270
+ > `HERMES_HOME`, `backup_paths()` reports them to `hermes backup` — a profile
271
+ > backup deliberately includes the machine's shared memory store. Roots you point
272
+ > elsewhere with `COGNEE_DATA_ROOT` / `COGNEE_SYSTEM_ROOT` are reported the same
273
+ > way (unless they sit inside `HERMES_HOME`, which `hermes backup` walks anyway).
274
+
275
+ > `COGNEE_SERVICE_URL` is a deprecated alias for `COGNEE_BASE_URL`, and
276
+ > `COGNEE_DATASET` (the 0.1.x name) a lower-precedence alias for
277
+ > `COGNEE_PLUGIN_DATASET`. Both still work; new setups should use the canonical
278
+ > names.
279
+
280
+ > **`improve_background`** decides where the session-end graph build
281
+ > (`improve()`) runs. Default `auto`: whenever a server is involved, the close is
282
+ > handed to a **detached worker** — the same process that already covers crashes —
283
+ > which runs `improve()` to completion and only then unregisters the agent
284
+ > connection. Hermes exits immediately; nothing waits on the graph build. That
285
+ > ordering is required, not stylistic: the local server runs with
286
+ > `COGNEE_AGENT_MODE=true` and retires itself within 60s of the last agent
287
+ > unregistering, so unregistering first would kill the promotion halfway. In
288
+ > `embedded` mode there is no server and no worker, so the build runs in-process
289
+ > and synchronously — it dies with the process otherwise.
290
+ >
291
+ > Setting `COGNEE_IMPROVE_BACKGROUND=true|false` opts out of the handoff and does
292
+ > the work in-process: `true` submits the build and returns (right for a
293
+ > cloud/remote server nothing here can shut down; on a local server it
294
+ > reintroduces the race above), `false` blocks Hermes' exit until the build
295
+ > finishes.
296
+
297
+ ## Hermes Commands
298
+
299
+ When Cognee is the active memory provider:
300
+
301
+ ```bash
302
+ hermes cognee status
303
+ hermes cognee setup
304
+ hermes cognee config
305
+ hermes cognee install
306
+ ```
307
+
308
+ ## Development
309
+
310
+ ```bash
311
+ cd integrations/hermes-agent
312
+ uv sync --dev
313
+ uv run pytest -q
314
+ uv run ruff check .
315
+ ```
@@ -0,0 +1,10 @@
1
+ """Cognee memory provider plugin for Hermes Agent."""
2
+
3
+ from .provider import CogneeMemoryProvider
4
+
5
+ __all__ = ["CogneeMemoryProvider", "register"]
6
+
7
+
8
+ def register(ctx) -> None:
9
+ """Pip entry-point registration hook for Hermes Agent."""
10
+ ctx.register_memory_provider(CogneeMemoryProvider())
@@ -0,0 +1,21 @@
1
+ # Cognee Hermes Memory Plugin
2
+
3
+ The Cognee memory plugin has been installed.
4
+
5
+ Run:
6
+
7
+ ```bash
8
+ hermes memory setup
9
+ ```
10
+
11
+ Then select `cognee` and pick a mode:
12
+
13
+ - **local** — the plugin runs a cognee server on your machine (shared with the
14
+ Claude Code / Codex / OpenClaw cognee plugins, if you use them). You'll be
15
+ asked for an LLM API key, which cognee uses to build the knowledge graph.
16
+ - **remote** — connect to Cognee Cloud or a self-hosted server. You'll be asked
17
+ for the service URL and an API key (for Cognee Cloud, both come from
18
+ https://platform.cognee.ai/).
19
+
20
+ Start a new `hermes` session afterwards to activate memory, then verify with
21
+ `hermes cognee status`.
@@ -0,0 +1,14 @@
1
+ """Directory-plugin CLI shim for Hermes Agent."""
2
+
3
+ try:
4
+ from .cognee_integration_hermes.cli import cognee_command, register_cli
5
+ except ImportError: # pragma: no cover - supports direct path imports.
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ plugin_dir = Path(__file__).resolve().parent
10
+ if str(plugin_dir) not in sys.path:
11
+ sys.path.insert(0, str(plugin_dir))
12
+ from cognee_integration_hermes.cli import cognee_command, register_cli
13
+
14
+ __all__ = ["cognee_command", "register_cli"]