memgraph-context-graph 0.8.0__tar.gz → 0.9.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.
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/PKG-INFO +33 -4
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/README.md +32 -3
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/command-hooks.md +11 -10
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/pyproject.toml +1 -1
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/_identity.py +42 -4
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/cli.py +73 -74
- memgraph_context_graph-0.9.0/src/memgraph_context_graph/connectors.py +71 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/hooks/cli.py +6 -3
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/hooks/runner.py +18 -105
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/agents.py +24 -2
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/cli.py +40 -1
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/engine.py +6 -4
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/tool.py +29 -12
- memgraph_context_graph-0.9.0/src/memgraph_context_graph/setup/update.py +124 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/conftest.py +24 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/fake_agent_cli.py +6 -1
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_capture_log.py +5 -2
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_config_cli.py +22 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_hook_cli.py +37 -4
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_identity.py +32 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_setup.py +114 -4
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_tools.py +2 -1
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/.gitignore +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/CONTEXT.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/LICENSE +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/adr/0001-runtime-adapter-terminology.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/adr/0002-config-file-only-hook-resolution.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/adr/0003-config-path-override.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/adr/0004-user-id-in-session-start-event.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/adr/0005-config-file-covers-llm-key-and-subprocess-env.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/adr/0006-memory-tool-writes-explicit-memory.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/docs/research/2026-10-codex-memory.md +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/__init__.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/__init__.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/_opencode_plugin.js +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/_spec.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/agent_mcp.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/agent_memory.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/antigravity_cli.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/claude.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/claude_code.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/claude_code_memory.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/codex.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/codex_memory.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/copilot_cli.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/cursor.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/grok.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/openai.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/adapters/opencode.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/capture_log.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/events.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/hooks/__init__.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/hooks/runtime_plugin.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/link.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/mcp_server.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/memory_backend.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/protocols.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/__init__.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/memgraph.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/prompts.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/setup/uninstall.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/spaces.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/terminal.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/tools.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/__init__.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_agent_memory_wiring.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_antigravity_cli_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_claude_code_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_codex_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_context_before_tool.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_copilot_cli_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_cursor_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_dev_scripts.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_events.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_grok_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_link.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_opencode_adapter.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_plugin_hooks.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_runner_sessions_graph_connector.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_runtime_plugin.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_setup_docker.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_spaces.py +0 -0
- {memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/tests/test_terminal.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: memgraph-context-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Connect agent SDKs to context-graph components (actions-graph, skills-graph, etc.)
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -202,6 +202,7 @@ memgraph-context-graph setup # interactive on a terminal; pl
|
|
|
202
202
|
memgraph-context-graph setup claude-code codex # just these agents
|
|
203
203
|
memgraph-context-graph setup cursor --project-dir ~/work/billing
|
|
204
204
|
memgraph-context-graph setup --plan # print the plan, change nothing
|
|
205
|
+
memgraph-context-graph update [runtime ...] # upgrade the package, refresh the wiring and the schema
|
|
205
206
|
memgraph-context-graph uninstall [runtime ...] # remove the wiring; the graph and config stay
|
|
206
207
|
```
|
|
207
208
|
|
|
@@ -211,6 +212,15 @@ wires each agent, and runs `doctor`'s checks. Every step checks before it acts,
|
|
|
211
212
|
missing. The TUI starts only when stdin and stdout are both terminals; the plugins' `scripts/bootstrap.sh`
|
|
212
213
|
runs `setup <runtime> --no-tui`.
|
|
213
214
|
|
|
215
|
+
**Updating.** Upgrading the package moves the code hooks and the MCP server run, but what setup wrote once stays
|
|
216
|
+
as it was. `update` upgrades the uv tool and its connectors, then, with the new release, refreshes everything
|
|
217
|
+
that is wired: Claude Code's and Codex's plugin (marketplace refreshed, plugin updated), each per-project agent's
|
|
218
|
+
hook file in `--project-dir` (default: the current directory) and its MCP registration, and the graph's indexes
|
|
219
|
+
and constraints. It then runs `doctor`'s checks. Name runtimes to refresh only those; `--no-upgrade` skips the
|
|
220
|
+
package step. Your own hooks, the config and the graph's data are untouched, and running it again changes nothing.
|
|
221
|
+
Running agent sessions keep the hooks they loaded: restart them. Outside the uv tool (a virtualenv, say) the
|
|
222
|
+
package step only warns, and you upgrade it yourself first.
|
|
223
|
+
|
|
214
224
|
**Identity and connection.** setup writes `~/.config/context-graph/config.toml`; hooks read their configuration from that file at runtime (see [Configuration](#configuration) — env vars are **not** read at hook time). To change your identity later:
|
|
215
225
|
|
|
216
226
|
```bash
|
|
@@ -268,6 +278,10 @@ database = "memgraph"
|
|
|
268
278
|
[llm]
|
|
269
279
|
openai_api_key = ""
|
|
270
280
|
anthropic_api_key = ""
|
|
281
|
+
derive_model = "claude-sonnet-5-5"
|
|
282
|
+
|
|
283
|
+
[capture]
|
|
284
|
+
connectors = "skills-graph, actions-graph, sessions-graph"
|
|
271
285
|
|
|
272
286
|
[reconcile]
|
|
273
287
|
auto_reconcile = true
|
|
@@ -275,12 +289,21 @@ auto_reconcile = true
|
|
|
275
289
|
[recall]
|
|
276
290
|
embedding_model = "BAAI/bge-small-en-v1.5"
|
|
277
291
|
turns_k = "8"
|
|
292
|
+
|
|
293
|
+
[extraction]
|
|
294
|
+
model = "fastino/gliner2.5-base-v1"
|
|
295
|
+
entity_threshold = "0.3"
|
|
278
296
|
```
|
|
279
297
|
|
|
280
298
|
`[reconcile]` turns on sessions-graph's auto-trigger reconciliation (see
|
|
281
299
|
[sessions-graph § reconciliation](../sessions-graph/README.md#session-reconciliation)),
|
|
282
300
|
which needs no LLM. `[llm]` is optional: a key only lets reconciliation learn
|
|
283
|
-
the user's own ontology (`sessions-graph derive`)
|
|
301
|
+
the user's own ontology (`sessions-graph derive`), and `derive_model` picks
|
|
302
|
+
the model it calls (default `claude-sonnet-5-5` with Anthropic, `gpt-5` with OpenAI).
|
|
303
|
+
`[capture] connectors` is which graph connectors a hook enables when its
|
|
304
|
+
command names no `--connector`, from `skills-graph`, `actions-graph`,
|
|
305
|
+
`sessions-graph` and `resources-graph`; unset means the first three, and
|
|
306
|
+
an empty value enables none. Setup installs the ones it names.
|
|
284
307
|
`[reconcile]` is omitted entirely from a file setup wrote — absent
|
|
285
308
|
means "never configured," distinct from an explicit `auto_reconcile = false`.
|
|
286
309
|
`[recall]` is optional too: without it, recall runs with the widths the
|
|
@@ -288,6 +311,10 @@ benchmark measured; see [Recall](#recall-memory-for-the-harnesss-model).
|
|
|
288
311
|
`[ontology]` is optional as well: `path` names a schema file the user's
|
|
289
312
|
sessions are extracted under and `derive` is `extend` (the default) or
|
|
290
313
|
`off`; see sessions-graph's [Ontology versions](../sessions-graph/README.md#ontology-versions).
|
|
314
|
+
`[extraction]` tunes how reconciliation, re-extraction and derivation read
|
|
315
|
+
sessions, all optional: `model` (a GLiNER2 checkpoint), `entity_threshold` and
|
|
316
|
+
`relation_threshold` (drop extractions below that confidence, 0 to 1), and
|
|
317
|
+
`chunk_size`/`chunk_overlap` (words per window); unset keys keep GLiNER2's defaults.
|
|
291
318
|
|
|
292
319
|
Manage it with:
|
|
293
320
|
|
|
@@ -296,8 +323,9 @@ memgraph-context-graph config show
|
|
|
296
323
|
memgraph-context-graph config get memgraph.url
|
|
297
324
|
memgraph-context-graph config set <key> <value>
|
|
298
325
|
# keys: identity.user_id, memgraph.{url,user,password,database},
|
|
299
|
-
# llm.{openai_api_key,anthropic_api_key},
|
|
300
|
-
# recall.embedding_model, ontology.{path,derive}, memory.backend
|
|
326
|
+
# llm.{openai_api_key,anthropic_api_key,derive_model}, capture.connectors,
|
|
327
|
+
# reconcile.auto_reconcile, recall.embedding_model, ontology.{path,derive}, memory.backend
|
|
328
|
+
# [recall] widths and [extraction] are edited in the file.
|
|
301
329
|
```
|
|
302
330
|
|
|
303
331
|
Hooks never read environment variables for these values, and neither does setup: it writes only
|
|
@@ -355,6 +383,7 @@ from the tool call, so a model can only read its own user's sessions.
|
|
|
355
383
|
| `facts_k`, `fact_turns_k` | `15`, `8` | Facts matched, and the messages they were read from |
|
|
356
384
|
| `user_fact_types`, `user_facts_k` | `2`, `30` | Relation types gathered whole, for counting questions |
|
|
357
385
|
| `turn_chars` | `1500` | Characters shown per message |
|
|
386
|
+
| `query_instruction` | per model | Prefix embedded with the question; bge's English models get their retrieval instruction, other models none |
|
|
358
387
|
|
|
359
388
|
Recall needs Memgraph with MAGE (`memgraph/memgraph-mage`) for its vector lanes;
|
|
360
389
|
without it, it answers from text search and says so. `doctor` checks both
|
|
@@ -177,6 +177,7 @@ memgraph-context-graph setup # interactive on a terminal; pl
|
|
|
177
177
|
memgraph-context-graph setup claude-code codex # just these agents
|
|
178
178
|
memgraph-context-graph setup cursor --project-dir ~/work/billing
|
|
179
179
|
memgraph-context-graph setup --plan # print the plan, change nothing
|
|
180
|
+
memgraph-context-graph update [runtime ...] # upgrade the package, refresh the wiring and the schema
|
|
180
181
|
memgraph-context-graph uninstall [runtime ...] # remove the wiring; the graph and config stay
|
|
181
182
|
```
|
|
182
183
|
|
|
@@ -186,6 +187,15 @@ wires each agent, and runs `doctor`'s checks. Every step checks before it acts,
|
|
|
186
187
|
missing. The TUI starts only when stdin and stdout are both terminals; the plugins' `scripts/bootstrap.sh`
|
|
187
188
|
runs `setup <runtime> --no-tui`.
|
|
188
189
|
|
|
190
|
+
**Updating.** Upgrading the package moves the code hooks and the MCP server run, but what setup wrote once stays
|
|
191
|
+
as it was. `update` upgrades the uv tool and its connectors, then, with the new release, refreshes everything
|
|
192
|
+
that is wired: Claude Code's and Codex's plugin (marketplace refreshed, plugin updated), each per-project agent's
|
|
193
|
+
hook file in `--project-dir` (default: the current directory) and its MCP registration, and the graph's indexes
|
|
194
|
+
and constraints. It then runs `doctor`'s checks. Name runtimes to refresh only those; `--no-upgrade` skips the
|
|
195
|
+
package step. Your own hooks, the config and the graph's data are untouched, and running it again changes nothing.
|
|
196
|
+
Running agent sessions keep the hooks they loaded: restart them. Outside the uv tool (a virtualenv, say) the
|
|
197
|
+
package step only warns, and you upgrade it yourself first.
|
|
198
|
+
|
|
189
199
|
**Identity and connection.** setup writes `~/.config/context-graph/config.toml`; hooks read their configuration from that file at runtime (see [Configuration](#configuration) — env vars are **not** read at hook time). To change your identity later:
|
|
190
200
|
|
|
191
201
|
```bash
|
|
@@ -243,6 +253,10 @@ database = "memgraph"
|
|
|
243
253
|
[llm]
|
|
244
254
|
openai_api_key = ""
|
|
245
255
|
anthropic_api_key = ""
|
|
256
|
+
derive_model = "claude-sonnet-5-5"
|
|
257
|
+
|
|
258
|
+
[capture]
|
|
259
|
+
connectors = "skills-graph, actions-graph, sessions-graph"
|
|
246
260
|
|
|
247
261
|
[reconcile]
|
|
248
262
|
auto_reconcile = true
|
|
@@ -250,12 +264,21 @@ auto_reconcile = true
|
|
|
250
264
|
[recall]
|
|
251
265
|
embedding_model = "BAAI/bge-small-en-v1.5"
|
|
252
266
|
turns_k = "8"
|
|
267
|
+
|
|
268
|
+
[extraction]
|
|
269
|
+
model = "fastino/gliner2.5-base-v1"
|
|
270
|
+
entity_threshold = "0.3"
|
|
253
271
|
```
|
|
254
272
|
|
|
255
273
|
`[reconcile]` turns on sessions-graph's auto-trigger reconciliation (see
|
|
256
274
|
[sessions-graph § reconciliation](../sessions-graph/README.md#session-reconciliation)),
|
|
257
275
|
which needs no LLM. `[llm]` is optional: a key only lets reconciliation learn
|
|
258
|
-
the user's own ontology (`sessions-graph derive`)
|
|
276
|
+
the user's own ontology (`sessions-graph derive`), and `derive_model` picks
|
|
277
|
+
the model it calls (default `claude-sonnet-5-5` with Anthropic, `gpt-5` with OpenAI).
|
|
278
|
+
`[capture] connectors` is which graph connectors a hook enables when its
|
|
279
|
+
command names no `--connector`, from `skills-graph`, `actions-graph`,
|
|
280
|
+
`sessions-graph` and `resources-graph`; unset means the first three, and
|
|
281
|
+
an empty value enables none. Setup installs the ones it names.
|
|
259
282
|
`[reconcile]` is omitted entirely from a file setup wrote — absent
|
|
260
283
|
means "never configured," distinct from an explicit `auto_reconcile = false`.
|
|
261
284
|
`[recall]` is optional too: without it, recall runs with the widths the
|
|
@@ -263,6 +286,10 @@ benchmark measured; see [Recall](#recall-memory-for-the-harnesss-model).
|
|
|
263
286
|
`[ontology]` is optional as well: `path` names a schema file the user's
|
|
264
287
|
sessions are extracted under and `derive` is `extend` (the default) or
|
|
265
288
|
`off`; see sessions-graph's [Ontology versions](../sessions-graph/README.md#ontology-versions).
|
|
289
|
+
`[extraction]` tunes how reconciliation, re-extraction and derivation read
|
|
290
|
+
sessions, all optional: `model` (a GLiNER2 checkpoint), `entity_threshold` and
|
|
291
|
+
`relation_threshold` (drop extractions below that confidence, 0 to 1), and
|
|
292
|
+
`chunk_size`/`chunk_overlap` (words per window); unset keys keep GLiNER2's defaults.
|
|
266
293
|
|
|
267
294
|
Manage it with:
|
|
268
295
|
|
|
@@ -271,8 +298,9 @@ memgraph-context-graph config show
|
|
|
271
298
|
memgraph-context-graph config get memgraph.url
|
|
272
299
|
memgraph-context-graph config set <key> <value>
|
|
273
300
|
# keys: identity.user_id, memgraph.{url,user,password,database},
|
|
274
|
-
# llm.{openai_api_key,anthropic_api_key},
|
|
275
|
-
# recall.embedding_model, ontology.{path,derive}, memory.backend
|
|
301
|
+
# llm.{openai_api_key,anthropic_api_key,derive_model}, capture.connectors,
|
|
302
|
+
# reconcile.auto_reconcile, recall.embedding_model, ontology.{path,derive}, memory.backend
|
|
303
|
+
# [recall] widths and [extraction] are edited in the file.
|
|
276
304
|
```
|
|
277
305
|
|
|
278
306
|
Hooks never read environment variables for these values, and neither does setup: it writes only
|
|
@@ -330,6 +358,7 @@ from the tool call, so a model can only read its own user's sessions.
|
|
|
330
358
|
| `facts_k`, `fact_turns_k` | `15`, `8` | Facts matched, and the messages they were read from |
|
|
331
359
|
| `user_fact_types`, `user_facts_k` | `2`, `30` | Relation types gathered whole, for counting questions |
|
|
332
360
|
| `turn_chars` | `1500` | Characters shown per message |
|
|
361
|
+
| `query_instruction` | per model | Prefix embedded with the question; bge's English models get their retrieval instruction, other models none |
|
|
333
362
|
|
|
334
363
|
Recall needs Memgraph with MAGE (`memgraph/memgraph-mage`) for its vector lanes;
|
|
335
364
|
without it, it answers from text search and says so. `doctor` checks both
|
|
@@ -5,12 +5,13 @@ Protocol, then routes those events to graph connectors. The installed command
|
|
|
5
5
|
is the same for every runtime:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
memgraph-context-graph hook run <runtime>
|
|
9
|
-
--connector skills-graph \
|
|
10
|
-
--connector actions-graph \
|
|
11
|
-
--connector sessions-graph
|
|
8
|
+
memgraph-context-graph hook run <runtime>
|
|
12
9
|
```
|
|
13
10
|
|
|
11
|
+
It enables the graph connectors the config file's `[capture] connectors`
|
|
12
|
+
names (unset: `skills-graph`, `actions-graph`, `sessions-graph`). Repeated
|
|
13
|
+
`--connector` flags override that for one hook command.
|
|
14
|
+
|
|
14
15
|
Runtime registrations are discovered through the
|
|
15
16
|
`memgraph_context_graph.runtimes` Python entry-point group.
|
|
16
17
|
|
|
@@ -36,8 +37,9 @@ memgraph-context-graph hook init antigravity-cli
|
|
|
36
37
|
memgraph-context-graph hook init grok
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
`hook init`
|
|
40
|
-
`--connector` flags
|
|
40
|
+
`hook init` writes hook commands without `--connector` flags, so they enable
|
|
41
|
+
`[capture] connectors`. Repeated `--connector` flags pin a set into the
|
|
42
|
+
generated commands instead. Existing Copilot, Cursor, Antigravity, and Grok
|
|
41
43
|
JSON documents are merged without removing unrelated settings or hooks.
|
|
42
44
|
OpenCode's generated plugin is replaced only with `--force`.
|
|
43
45
|
|
|
@@ -246,12 +248,11 @@ memgraph-context-graph setup antigravity-cli --project-dir "$PWD"
|
|
|
246
248
|
Smoke-test a registration and its configured connectors:
|
|
247
249
|
|
|
248
250
|
```bash
|
|
249
|
-
memgraph-context-graph doctor --runtime cursor
|
|
250
|
-
--connector skills-graph \
|
|
251
|
-
--connector actions-graph \
|
|
252
|
-
--connector sessions-graph
|
|
251
|
+
memgraph-context-graph doctor --runtime cursor
|
|
253
252
|
```
|
|
254
253
|
|
|
254
|
+
`doctor` checks the `[capture] connectors` set unless `--connector` flags name others.
|
|
255
|
+
|
|
255
256
|
Each runtime provides its own native probe payload; `doctor` does not assume
|
|
256
257
|
that every runtime calls its session-end event `Stop`.
|
|
257
258
|
|
|
@@ -85,6 +85,11 @@ class HookConfig:
|
|
|
85
85
|
memgraph_database: str = _MEMGRAPH_DEFAULTS["database"]
|
|
86
86
|
openai_api_key: str = _LLM_DEFAULTS["openai_api_key"]
|
|
87
87
|
anthropic_api_key: str = _LLM_DEFAULTS["anthropic_api_key"]
|
|
88
|
+
#: ``[llm] derive_model``: the model ontology derivation calls; None means the provider's default.
|
|
89
|
+
derive_model: str | None = None
|
|
90
|
+
#: ``[capture] connectors``: the graph connectors a hook enables when its command names none;
|
|
91
|
+
#: None (never set) means memgraph_context_graph.connectors.DEFAULT_CONNECTORS.
|
|
92
|
+
connectors: tuple[str, ...] | None = None
|
|
88
93
|
auto_reconcile: bool | None = None
|
|
89
94
|
#: The model recall embeds with; None means the consumer's own default.
|
|
90
95
|
embedding_model: str | None = None
|
|
@@ -95,6 +100,9 @@ class HookConfig:
|
|
|
95
100
|
ontology_path: str | None = None
|
|
96
101
|
#: ``[ontology] derive``: "extend" (the default) or "off"; see sessions-graph's ontology module.
|
|
97
102
|
ontology_derive: str | None = None
|
|
103
|
+
#: ``[extraction]`` keys (GLiNER2 checkpoint, thresholds, chunking), as written: sessions-graph
|
|
104
|
+
#: validates them, this module only keeps them across rewrites.
|
|
105
|
+
extraction_settings: dict[str, str] = field(default_factory=dict)
|
|
98
106
|
#: ``[github] token``: overrides the ``gh`` login resources-graph's Sweep otherwise fetches with.
|
|
99
107
|
github_token: str | None = None
|
|
100
108
|
#: ``[memory] backend``: ``"context-graph"`` when the user has handed their
|
|
@@ -186,7 +194,7 @@ def resolve_auto_reconcile() -> bool:
|
|
|
186
194
|
"""Resolve whether sessions-graph should auto-trigger reconciliation on SESSION_END.
|
|
187
195
|
|
|
188
196
|
Config file only (ADR 0002); never configured means ``False``, matching
|
|
189
|
-
``SessionsGraphConnector``'s default
|
|
197
|
+
``SessionsGraphConnector``'s default.
|
|
190
198
|
"""
|
|
191
199
|
return bool(load_config().auto_reconcile)
|
|
192
200
|
|
|
@@ -196,6 +204,16 @@ def resolve_embedding_model() -> str | None:
|
|
|
196
204
|
return load_config().embedding_model
|
|
197
205
|
|
|
198
206
|
|
|
207
|
+
def resolve_extraction() -> dict[str, str]:
|
|
208
|
+
"""The configured ``[extraction]`` keys, as written; sessions-graph owns their meaning."""
|
|
209
|
+
return dict(load_config().extraction_settings)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def resolve_derive_model() -> str | None:
|
|
213
|
+
"""The configured ``[llm] derive_model``, or None to leave the provider's default."""
|
|
214
|
+
return load_config().derive_model
|
|
215
|
+
|
|
216
|
+
|
|
199
217
|
def resolve_ontology() -> tuple[str | None, str | None]:
|
|
200
218
|
"""The configured ``[ontology]`` (path, derive), each None when unset; sessions-graph owns their meaning."""
|
|
201
219
|
config = load_config()
|
|
@@ -219,6 +237,8 @@ def write_config(
|
|
|
219
237
|
memgraph_database: str | None = None,
|
|
220
238
|
openai_api_key: str | None = None,
|
|
221
239
|
anthropic_api_key: str | None = None,
|
|
240
|
+
derive_model: str | None = None,
|
|
241
|
+
connectors: tuple[str, ...] | None = None,
|
|
222
242
|
auto_reconcile: bool | None = None,
|
|
223
243
|
embedding_model: str | None = None,
|
|
224
244
|
ontology_path: str | None = None,
|
|
@@ -241,6 +261,8 @@ def write_config(
|
|
|
241
261
|
"memgraph_database": memgraph_database,
|
|
242
262
|
"openai_api_key": openai_api_key,
|
|
243
263
|
"anthropic_api_key": anthropic_api_key,
|
|
264
|
+
"derive_model": derive_model,
|
|
265
|
+
"connectors": connectors,
|
|
244
266
|
"auto_reconcile": auto_reconcile,
|
|
245
267
|
"embedding_model": embedding_model,
|
|
246
268
|
"ontology_path": ontology_path,
|
|
@@ -266,8 +288,8 @@ def write_full_config(
|
|
|
266
288
|
) -> Path:
|
|
267
289
|
"""Write a complete config file, resetting identity, Memgraph and LLM settings to what is given.
|
|
268
290
|
|
|
269
|
-
Every other section (``[
|
|
270
|
-
``[session_start]``) and the edition are kept from the existing file, since only ``config set`` or a hand edit ever sets them.
|
|
291
|
+
Every other section (``[capture]``, ``[reconcile]``, ``[recall]``, ``[ontology]``, ``[extraction]``,
|
|
292
|
+
``[github]``, ``[memory]``, ``[session_start]``), ``[llm] derive_model`` and the edition are kept from the existing file, since only ``config set`` or a hand edit ever sets them.
|
|
271
293
|
``auto_reconcile`` is kept likewise unless given here. :func:`write_config` is the partial update.
|
|
272
294
|
"""
|
|
273
295
|
existing = _read_config_file()
|
|
@@ -313,9 +335,11 @@ def _read_config_file() -> HookConfig:
|
|
|
313
335
|
identity = sections.get("identity", {})
|
|
314
336
|
memgraph = sections.get("memgraph", {})
|
|
315
337
|
llm = sections.get("llm", {})
|
|
338
|
+
capture = sections.get("capture", {})
|
|
316
339
|
reconcile = sections.get("reconcile", {})
|
|
317
340
|
recall = sections.get("recall", {})
|
|
318
341
|
ontology = sections.get("ontology", {})
|
|
342
|
+
extraction = sections.get("extraction", {})
|
|
319
343
|
github = sections.get("github", {})
|
|
320
344
|
memory = sections.get("memory", {})
|
|
321
345
|
session_start = sections.get("session_start", {})
|
|
@@ -330,11 +354,14 @@ def _read_config_file() -> HookConfig:
|
|
|
330
354
|
memgraph_database=memgraph.get("database") or _MEMGRAPH_DEFAULTS["database"],
|
|
331
355
|
openai_api_key=llm.get("openai_api_key", _LLM_DEFAULTS["openai_api_key"]),
|
|
332
356
|
anthropic_api_key=llm.get("anthropic_api_key", _LLM_DEFAULTS["anthropic_api_key"]),
|
|
357
|
+
derive_model=llm.get("derive_model") or None,
|
|
358
|
+
connectors=_parse_list(capture["connectors"]) if "connectors" in capture else None,
|
|
333
359
|
auto_reconcile=parse_bool_flag(auto_reconcile_raw) if auto_reconcile_raw is not None else None,
|
|
334
360
|
embedding_model=recall.get("embedding_model") or None,
|
|
335
361
|
recall_settings={key: value for key, value in recall.items() if key != "embedding_model"},
|
|
336
362
|
ontology_path=ontology.get("path") or None,
|
|
337
363
|
ontology_derive=ontology.get("derive") or None,
|
|
364
|
+
extraction_settings=dict(extraction),
|
|
338
365
|
github_token=github.get("token") or None,
|
|
339
366
|
memory_backend=memory.get("backend") or None,
|
|
340
367
|
session_resume=parse_bool_flag(session_start["resume"]) if session_start.get("resume") else None,
|
|
@@ -348,6 +375,11 @@ def _read_config_file() -> HookConfig:
|
|
|
348
375
|
)
|
|
349
376
|
|
|
350
377
|
|
|
378
|
+
def _parse_list(value: str) -> tuple[str, ...]:
|
|
379
|
+
"""A comma-separated value (``"a, b"``) as its non-blank items; the parser has no arrays."""
|
|
380
|
+
return tuple(item.strip() for item in value.split(",") if item.strip())
|
|
381
|
+
|
|
382
|
+
|
|
351
383
|
def _parse_toml(path: Path, problems: list[str] | None = None) -> dict[str, dict[str, str]]:
|
|
352
384
|
"""Minimal TOML parser — handles [section] and key = "value" pairs.
|
|
353
385
|
|
|
@@ -387,7 +419,8 @@ def _render_config(config: HookConfig) -> str:
|
|
|
387
419
|
|
|
388
420
|
``[reconcile]`` is omitted while ``auto_reconcile`` is ``None`` so a re-read keeps "never configured"
|
|
389
421
|
distinct from an explicit ``false``, and ``[session_start]`` likewise while ``session_resume`` is;
|
|
390
|
-
``[recall]``, ``[ontology]``, ``[
|
|
422
|
+
``[capture]`` likewise while ``connectors`` is; ``[recall]``, ``[ontology]``, ``[extraction]``, ``[github]``
|
|
423
|
+
and ``[memory]`` are omitted while they hold nothing.
|
|
391
424
|
"""
|
|
392
425
|
user_id = config.user_id or ""
|
|
393
426
|
lines = [
|
|
@@ -407,7 +440,10 @@ def _render_config(config: HookConfig) -> str:
|
|
|
407
440
|
"[llm]",
|
|
408
441
|
f'openai_api_key = "{config.openai_api_key}"',
|
|
409
442
|
f'anthropic_api_key = "{config.anthropic_api_key}"',
|
|
443
|
+
*([f'derive_model = "{config.derive_model}"'] if config.derive_model else []),
|
|
410
444
|
]
|
|
445
|
+
if config.connectors is not None:
|
|
446
|
+
lines += ["", "[capture]", f'connectors = "{", ".join(config.connectors)}"']
|
|
411
447
|
if config.auto_reconcile is not None:
|
|
412
448
|
lines += ["", "[reconcile]", f"auto_reconcile = {'true' if config.auto_reconcile else 'false'}"]
|
|
413
449
|
recall = (
|
|
@@ -422,6 +458,8 @@ def _render_config(config: HookConfig) -> str:
|
|
|
422
458
|
}
|
|
423
459
|
if ontology:
|
|
424
460
|
lines += ["", "[ontology]", *(f'{key} = "{value}"' for key, value in ontology.items())]
|
|
461
|
+
if config.extraction_settings:
|
|
462
|
+
lines += ["", "[extraction]", *(f'{key} = "{value}"' for key, value in config.extraction_settings.items())]
|
|
425
463
|
if config.github_token:
|
|
426
464
|
lines += ["", "[github]", f'token = "{config.github_token}"']
|
|
427
465
|
if config.memory_backend:
|
{memgraph_context_graph-0.8.0 → memgraph_context_graph-0.9.0}/src/memgraph_context_graph/cli.py
RENAMED
|
@@ -9,10 +9,16 @@ import sys
|
|
|
9
9
|
from importlib import metadata
|
|
10
10
|
from typing import TYPE_CHECKING, Any, TypedDict, cast
|
|
11
11
|
|
|
12
|
+
from memgraph_context_graph.connectors import (
|
|
13
|
+
COMPONENTS,
|
|
14
|
+
DEFAULT_CONNECTORS,
|
|
15
|
+
configured_connectors,
|
|
16
|
+
supported_connectors,
|
|
17
|
+
)
|
|
12
18
|
from memgraph_context_graph.tools import normalize_connector_name
|
|
13
19
|
|
|
14
20
|
if TYPE_CHECKING:
|
|
15
|
-
from collections.abc import Sequence
|
|
21
|
+
from collections.abc import Callable, Sequence
|
|
16
22
|
|
|
17
23
|
_HELP = """usage: memgraph-context-graph <command> [options]
|
|
18
24
|
|
|
@@ -20,6 +26,7 @@ Commands:
|
|
|
20
26
|
setup [runtime ...] Install Context Graph for your agents (interactive on a terminal);
|
|
21
27
|
--memory-backend context-graph|native switches whose memory they use.
|
|
22
28
|
uninstall [runtime ...] Remove the agents' wiring; your graph and config stay.
|
|
29
|
+
update [runtime ...] Upgrade the package and refresh the agents' wiring and the graph's schema.
|
|
23
30
|
config Get or set persistent configuration values.
|
|
24
31
|
doctor Check runtime hook dependencies and Memgraph connectivity.
|
|
25
32
|
join <url> <login> Use an Enterprise Memgraph as <login> (edition = enterprise); --password or prompt.
|
|
@@ -54,6 +61,11 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
54
61
|
|
|
55
62
|
return uninstall_main(args[1:])
|
|
56
63
|
|
|
64
|
+
if command == "update":
|
|
65
|
+
from memgraph_context_graph.setup.cli import update_main
|
|
66
|
+
|
|
67
|
+
return update_main(args[1:])
|
|
68
|
+
|
|
57
69
|
if command == "config":
|
|
58
70
|
return _config(args[1:])
|
|
59
71
|
|
|
@@ -106,6 +118,8 @@ def _config(argv: list[str]) -> int:
|
|
|
106
118
|
"memgraph.database": "memgraph_database",
|
|
107
119
|
"llm.openai_api_key": "openai_api_key",
|
|
108
120
|
"llm.anthropic_api_key": "anthropic_api_key",
|
|
121
|
+
"llm.derive_model": "derive_model",
|
|
122
|
+
"capture.connectors": "connectors",
|
|
109
123
|
"reconcile.auto_reconcile": "auto_reconcile",
|
|
110
124
|
"recall.embedding_model": "embedding_model",
|
|
111
125
|
"ontology.path": "ontology_path",
|
|
@@ -143,6 +157,14 @@ def _config(argv: list[str]) -> int:
|
|
|
143
157
|
print(f"memgraph.database = {config.memgraph_database!r}")
|
|
144
158
|
print(f"llm.openai_api_key = {'***' if config.openai_api_key else repr('')}")
|
|
145
159
|
print(f"llm.anthropic_api_key = {'***' if config.anthropic_api_key else repr('')}")
|
|
160
|
+
if config.derive_model is None:
|
|
161
|
+
print("llm.derive_model = unset (defaults to the provider's model)")
|
|
162
|
+
else:
|
|
163
|
+
print(f"llm.derive_model = {config.derive_model!r}")
|
|
164
|
+
if config.connectors is None:
|
|
165
|
+
print(f"capture.connectors = unset (defaults to {', '.join(DEFAULT_CONNECTORS)})")
|
|
166
|
+
else:
|
|
167
|
+
print(f"capture.connectors = {', '.join(config.connectors)!r}")
|
|
146
168
|
if config.auto_reconcile is None:
|
|
147
169
|
print("reconcile.auto_reconcile = unset (defaults to false)")
|
|
148
170
|
else:
|
|
@@ -156,6 +178,8 @@ def _config(argv: list[str]) -> int:
|
|
|
156
178
|
print("ontology.derive = unset (defaults to extend)")
|
|
157
179
|
else:
|
|
158
180
|
print(f"ontology.derive = {config.ontology_derive!r}")
|
|
181
|
+
for key, value in config.extraction_settings.items():
|
|
182
|
+
print(f"extraction.{key} = {value!r}")
|
|
159
183
|
print(f"github.token = {'***' if config.github_token else 'unset'}")
|
|
160
184
|
print(
|
|
161
185
|
f"memory.backend = {config.memory_backend!r}"
|
|
@@ -189,7 +213,7 @@ def _config(argv: list[str]) -> int:
|
|
|
189
213
|
else:
|
|
190
214
|
value = argv[2]
|
|
191
215
|
|
|
192
|
-
write_value: str | bool = value
|
|
216
|
+
write_value: str | bool | tuple[str, ...] = value
|
|
193
217
|
if key in _BOOL_KEYS:
|
|
194
218
|
normalized = value.strip().lower()
|
|
195
219
|
if normalized not in TRUTHY_VALUES | FALSY_VALUES:
|
|
@@ -205,6 +229,12 @@ def _config(argv: list[str]) -> int:
|
|
|
205
229
|
if key == "ontology.derive" and value not in {"extend", "off"}:
|
|
206
230
|
print(f"Invalid value for {key}: {value!r} (expected extend/off)", file=sys.stderr)
|
|
207
231
|
return 2
|
|
232
|
+
if key == "capture.connectors":
|
|
233
|
+
try:
|
|
234
|
+
write_value = tuple(supported_connectors(value.split(",")))
|
|
235
|
+
except ValueError as exc:
|
|
236
|
+
print(f"Invalid value for {key}: {exc}", file=sys.stderr)
|
|
237
|
+
return 2
|
|
208
238
|
|
|
209
239
|
# The key/value pairing is only known at runtime (bool iff key is in
|
|
210
240
|
# _BOOL_KEYS, str otherwise); write_config's own parameters are precisely
|
|
@@ -214,6 +244,8 @@ def _config(argv: list[str]) -> int:
|
|
|
214
244
|
display_value = "***"
|
|
215
245
|
elif key in _BOOL_KEYS:
|
|
216
246
|
display_value = str(write_value).lower()
|
|
247
|
+
elif isinstance(write_value, tuple):
|
|
248
|
+
display_value = repr(", ".join(write_value))
|
|
217
249
|
else:
|
|
218
250
|
display_value = repr(write_value)
|
|
219
251
|
print(f"Wrote {key} = {display_value} to {config_path}")
|
|
@@ -236,6 +268,8 @@ def _config(argv: list[str]) -> int:
|
|
|
236
268
|
return 1
|
|
237
269
|
if key in _SECRET_KEYS:
|
|
238
270
|
print("***")
|
|
271
|
+
elif isinstance(value, tuple):
|
|
272
|
+
print(", ".join(value))
|
|
239
273
|
else:
|
|
240
274
|
print(value)
|
|
241
275
|
return 0
|
|
@@ -370,7 +404,7 @@ def _doctor(argv: list[str]) -> int:
|
|
|
370
404
|
"--connector",
|
|
371
405
|
action="append",
|
|
372
406
|
default=None,
|
|
373
|
-
help="Graph connector to
|
|
407
|
+
help="Graph connector to check, repeatable. Defaults to the config file's [capture] connectors.",
|
|
374
408
|
)
|
|
375
409
|
parser.add_argument(
|
|
376
410
|
"--json",
|
|
@@ -379,7 +413,7 @@ def _doctor(argv: list[str]) -> int:
|
|
|
379
413
|
)
|
|
380
414
|
args = parser.parse_args(argv)
|
|
381
415
|
|
|
382
|
-
checks = doctor_checks([args.runtime], args.connector or
|
|
416
|
+
checks = doctor_checks([args.runtime], args.connector or configured_connectors())
|
|
383
417
|
ok = all(check["ok"] for check in checks)
|
|
384
418
|
payload: _DoctorPayload = {"ok": ok, "checks": checks}
|
|
385
419
|
if args.json:
|
|
@@ -519,82 +553,47 @@ def _check_package(package_name: str) -> _CheckResult:
|
|
|
519
553
|
|
|
520
554
|
def _check_connector(connector_name: str) -> _CheckResult:
|
|
521
555
|
normalized = normalize_connector_name(connector_name)
|
|
522
|
-
if normalized
|
|
523
|
-
|
|
524
|
-
try:
|
|
525
|
-
from skills_graph import SkillGraph
|
|
556
|
+
if normalized not in COMPONENTS:
|
|
557
|
+
return {"name": f"connector:{connector_name}", "ok": False, "detail": "unsupported connector"}
|
|
526
558
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
return {"name": "connector:skills-graph", "ok": True, "detail": f"installed={version}; memgraph=reachable"}
|
|
530
|
-
except Exception as exc:
|
|
531
|
-
return {"name": "connector:skills-graph", "ok": False, "detail": f"{type(exc).__name__}: {exc}"}
|
|
532
|
-
finally:
|
|
533
|
-
_close(graph and graph._db)
|
|
559
|
+
from memgraph_context_graph.adapters._identity import resolve_memgraph_env
|
|
560
|
+
from memgraph_context_graph.hooks.runner import memgraph_kwargs
|
|
534
561
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
562
|
+
name = f"connector:{normalized}"
|
|
563
|
+
graph = None
|
|
564
|
+
try:
|
|
565
|
+
graph = COMPONENTS[normalized].graph()(**memgraph_kwargs(resolve_memgraph_env()))
|
|
566
|
+
detail = f"installed={_package_version(normalized)}; memgraph=reachable"
|
|
567
|
+
extra = _CONNECTOR_CHECKS.get(normalized)
|
|
568
|
+
ok, more = extra() if extra is not None else (True, "")
|
|
569
|
+
return {"name": name, "ok": ok, "detail": f"{detail}; {more}" if ok and more else more or detail}
|
|
570
|
+
except Exception as exc:
|
|
571
|
+
return {"name": name, "ok": False, "detail": f"{type(exc).__name__}: {exc}"}
|
|
572
|
+
finally:
|
|
573
|
+
_close(graph and graph._db)
|
|
539
574
|
|
|
540
|
-
graph = ActionsGraph()
|
|
541
|
-
version = _package_version("actions-graph")
|
|
542
|
-
return {"name": "connector:actions-graph", "ok": True, "detail": f"installed={version}; memgraph=reachable"}
|
|
543
|
-
except Exception as exc:
|
|
544
|
-
return {"name": "connector:actions-graph", "ok": False, "detail": f"{type(exc).__name__}: {exc}"}
|
|
545
|
-
finally:
|
|
546
|
-
_close(graph and graph._db)
|
|
547
575
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
try:
|
|
551
|
-
from sessions_graph import SessionsGraph
|
|
552
|
-
|
|
553
|
-
from memgraph_context_graph.adapters._identity import resolve_memgraph_env, resolve_user_id
|
|
554
|
-
from memgraph_context_graph.hooks.runner import memgraph_kwargs
|
|
555
|
-
|
|
556
|
-
graph = SessionsGraph(**memgraph_kwargs(resolve_memgraph_env()))
|
|
557
|
-
version = _package_version("sessions-graph")
|
|
558
|
-
user_id = resolve_user_id({})
|
|
559
|
-
if not user_id:
|
|
560
|
-
return {
|
|
561
|
-
"name": "connector:sessions-graph",
|
|
562
|
-
"ok": False,
|
|
563
|
-
"detail": "user_id not resolved — run: memgraph-context-graph config set identity.user_id <your-name>",
|
|
564
|
-
}
|
|
565
|
-
return {
|
|
566
|
-
"name": "connector:sessions-graph",
|
|
567
|
-
"ok": True,
|
|
568
|
-
"detail": f"installed={version}; memgraph=reachable; user_id={user_id!r}",
|
|
569
|
-
}
|
|
570
|
-
except Exception as exc:
|
|
571
|
-
return {"name": "connector:sessions-graph", "ok": False, "detail": f"{type(exc).__name__}: {exc}"}
|
|
572
|
-
finally:
|
|
573
|
-
_close(graph and graph._db)
|
|
576
|
+
def _check_sessions_graph() -> tuple[bool, str]:
|
|
577
|
+
from memgraph_context_graph.adapters._identity import resolve_user_id
|
|
574
578
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
from memgraph_context_graph.hooks.runner import memgraph_kwargs
|
|
580
|
-
from resources_graph import ResourcesGraph
|
|
581
|
-
|
|
582
|
-
graph = ResourcesGraph(**memgraph_kwargs(resolve_memgraph_env()))
|
|
583
|
-
version = _package_version("resources-graph")
|
|
584
|
-
# Touches are recorded without a token; the Sweep falls back to the user's gh login.
|
|
585
|
-
token = "set" if load_config().github_token else "unset (the Sweep uses the gh login)"
|
|
586
|
-
return {
|
|
587
|
-
"name": "connector:resources-graph",
|
|
588
|
-
"ok": True,
|
|
589
|
-
"detail": f"installed={version}; memgraph=reachable; github.token {token}",
|
|
590
|
-
}
|
|
591
|
-
except Exception as exc:
|
|
592
|
-
return {"name": "connector:resources-graph", "ok": False, "detail": f"{type(exc).__name__}: {exc}"}
|
|
593
|
-
finally:
|
|
594
|
-
_close(graph and graph._db)
|
|
579
|
+
user_id = resolve_user_id({})
|
|
580
|
+
if not user_id:
|
|
581
|
+
return False, "user_id not resolved — run: memgraph-context-graph config set identity.user_id <your-name>"
|
|
582
|
+
return True, f"user_id={user_id!r}"
|
|
595
583
|
|
|
596
|
-
|
|
597
|
-
|
|
584
|
+
|
|
585
|
+
def _check_resources_graph() -> tuple[bool, str]:
|
|
586
|
+
from memgraph_context_graph.adapters._identity import load_config
|
|
587
|
+
|
|
588
|
+
# Touches are recorded without a token; the Sweep falls back to the user's gh login.
|
|
589
|
+
return True, f"github.token {'set' if load_config().github_token else 'unset (the Sweep uses the gh login)'}"
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
#: What a connector needs beyond a reachable Memgraph: (ok, what its check line adds, or why it fails).
|
|
593
|
+
_CONNECTOR_CHECKS: dict[str, Callable[[], tuple[bool, str]]] = {
|
|
594
|
+
"sessions-graph": _check_sessions_graph,
|
|
595
|
+
"resources-graph": _check_resources_graph,
|
|
596
|
+
}
|
|
598
597
|
|
|
599
598
|
|
|
600
599
|
def _check_embeddings() -> _CheckResult:
|