memplex 3.2.0__tar.gz → 3.2.1__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.
- memplex-3.2.1/LICENSE +21 -0
- {memplex-3.2.0 → memplex-3.2.1}/PKG-INFO +4 -2
- memplex-3.2.1/README.md +94 -0
- memplex-3.2.1/memplex/__init__.py +31 -0
- memplex-3.2.1/memplex/__main__.py +6 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/.claude-plugin/plugin.json +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/.mcp.json +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/hooks/hooks.json +4 -4
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/scripts/hook-runner.py +15 -15
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/skills/mem-explore/SKILL.md +5 -5
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/skills/mem-manage/SKILL.md +7 -7
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/skills/mem-search/SKILL.md +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/skills/mem-write/SKILL.md +5 -5
- memplex-3.2.1/memplex/adapters/__init__.py +14 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/adapters/claude_skill.py +21 -21
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/adapters/cli.py +71 -33
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/adapters/http_api.py +23 -23
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/adapters/mcp_server.py +14 -14
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/compaction.py +12 -12
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/config.py +28 -28
- memplex-3.2.1/memplex/core/__init__.py +13 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/associator/domain_classifier.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/associator/term_mapper.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/engine.py +20 -20
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/extractors/markdown.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/extractors/vision_mapper.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/__init__.py +6 -6
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/enhancer.py +8 -8
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/fallback_chain.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/injection_guard.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/provider.py +5 -5
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/providers/__init__.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/providers/anthropic.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/providers/local.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/providers/rule_based.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/__init__.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/feedback.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/misc.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/search.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/processing/graph_builder.py +5 -5
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/processing/merger/confidence_calculator.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/retrieval/dedup.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/retrieval/embedding.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/retrieval/reranker.py +4 -4
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/service.py +25 -25
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/__init__.py +7 -7
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/base.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/changelog.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/feedback.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/lite/__init__.py +1 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/lite/store.py +6 -6
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/storage/vector.py +1 -1
- memplex-3.2.1/memplex/wiki/__init__.py +11 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/wiki/community.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/wiki/compiler.py +7 -7
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/wiki/generator.py +3 -3
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/wiki/search.py +2 -2
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/worker.py +4 -4
- {memplex-3.2.0 → memplex-3.2.1}/memplex.egg-info/PKG-INFO +4 -2
- memplex-3.2.1/memplex.egg-info/SOURCES.txt +96 -0
- memplex-3.2.1/memplex.egg-info/entry_points.txt +2 -0
- {memplex-3.2.0 → memplex-3.2.1}/memplex.egg-info/requires.txt +1 -1
- memplex-3.2.1/memplex.egg-info/top_level.txt +1 -0
- {memplex-3.2.0 → memplex-3.2.1}/pyproject.toml +6 -6
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_associators.py +6 -6
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_config.py +32 -32
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_core_engine.py +3 -3
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_graph_builder.py +13 -13
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_hooks.py +30 -30
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_llm.py +6 -6
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_models.py +3 -3
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_service.py +9 -9
- {memplex-3.2.0 → memplex-3.2.1}/tests/test_storage.py +4 -4
- memplex-3.2.0/memnex/__init__.py +0 -31
- memplex-3.2.0/memnex/__main__.py +0 -6
- memplex-3.2.0/memnex/adapters/__init__.py +0 -14
- memplex-3.2.0/memnex/core/__init__.py +0 -13
- memplex-3.2.0/memnex/wiki/__init__.py +0 -11
- memplex-3.2.0/memplex.egg-info/SOURCES.txt +0 -94
- memplex-3.2.0/memplex.egg-info/entry_points.txt +0 -2
- memplex-3.2.0/memplex.egg-info/top_level.txt +0 -1
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/_plugin/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/associator/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/associator/entity_aligner.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/associator/ref_linker.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/dictionaries/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/extractors/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/extractors/docx.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/extractors/image.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/extractors/pdf.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/handlers/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/handlers/clipboard.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/handlers/file_handler.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/core/handlers/url_handler.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/llm/sanitizer.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/graph.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/memory.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/paragraph.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/source.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/models/task.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/processing/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/processing/merger/__init__.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/processing/merger/conflict_resolver.py +0 -0
- {memplex-3.2.0/memnex → memplex-3.2.1/memplex}/retrieval/__init__.py +0 -0
- {memplex-3.2.0 → memplex-3.2.1}/memplex.egg-info/dependency_links.txt +0 -0
- {memplex-3.2.0 → memplex-3.2.1}/setup.cfg +0 -0
memplex-3.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Memplex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memplex
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: Memplex - Memory Complex: multi-agent knowledge graph memory system with 3-layer retrieval
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Requires-Dist: pyyaml>=6.0
|
|
7
8
|
Requires-Dist: numpy>=1.24.0
|
|
8
9
|
Requires-Dist: requests>=2.28.0
|
|
@@ -30,8 +31,9 @@ Requires-Dist: asyncpg>=0.29.0; extra == "postgres"
|
|
|
30
31
|
Provides-Extra: neo4j
|
|
31
32
|
Requires-Dist: neo4j>=5.0.0; extra == "neo4j"
|
|
32
33
|
Provides-Extra: all
|
|
33
|
-
Requires-Dist:
|
|
34
|
+
Requires-Dist: memplex[embedding,extractors,graph,http,llm,vector]; extra == "all"
|
|
34
35
|
Provides-Extra: dev
|
|
35
36
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
36
37
|
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
37
38
|
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
memplex-3.2.1/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Memplex
|
|
2
|
+
|
|
3
|
+
**Memplex** is a persistent knowledge graph memory system for AI agents. It extracts structured knowledge from documents, URLs, and conversations, then provides 3-layer retrieval across sessions.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **4 Memory Types**: Function (procedural), Fact (declarative), Preference (user prefs), Observation (runtime events)
|
|
8
|
+
- **3-Layer Retrieval**: Search → Timeline → Get (10x token savings vs fetching everything)
|
|
9
|
+
- **5-Dim Reranker**: raw_relevance, semantic_similarity, recency_decay, source_authority, frequency
|
|
10
|
+
- **5-Stage Compaction**: Extract → Dedup → Summarize → Prune → Archive
|
|
11
|
+
- **Wiki Layer**: WikiCompiler + DualIndexSearch (FTS + vector RRF) + GraphRAG community detection
|
|
12
|
+
- **Lifecycle Hooks**: Auto-collect observations from tool usage, compact on session end
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Claude Code Plugin
|
|
17
|
+
|
|
18
|
+
**Option 1: Local plugin (for development)**
|
|
19
|
+
```bash
|
|
20
|
+
# Clone and install locally
|
|
21
|
+
cd plugin
|
|
22
|
+
/plugin install ./plugin
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Option 2: Via marketplace**
|
|
26
|
+
```bash
|
|
27
|
+
/plugin marketplace add ./marketplace.json
|
|
28
|
+
/plugin install memplex
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Option 3: pip install**
|
|
32
|
+
```bash
|
|
33
|
+
pip install memplex
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### From Source
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/articultur/memplex.git
|
|
40
|
+
cd memplex
|
|
41
|
+
pip install -e .
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Claude Code Setup
|
|
45
|
+
|
|
46
|
+
After installation, initialize Memplex:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
memplex config init
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This creates `memplex.yaml` with your configuration.
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Write content to memory
|
|
58
|
+
memplex write "Python list comprehensions are faster than loops"
|
|
59
|
+
|
|
60
|
+
# Query memory
|
|
61
|
+
memplex query "python performance"
|
|
62
|
+
|
|
63
|
+
# Run compaction
|
|
64
|
+
memplex compact
|
|
65
|
+
|
|
66
|
+
# Health check
|
|
67
|
+
memplex health
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Adapters
|
|
71
|
+
|
|
72
|
+
| Adapter | Entry Point | Description |
|
|
73
|
+
|---------|------------|-------------|
|
|
74
|
+
| CLI | `memplex` / `python -m memplex` | 9 subcommands |
|
|
75
|
+
| HTTP API | `memplex.adapters.http_api` | FastAPI with 11 REST endpoints |
|
|
76
|
+
| MCP | `memplex.adapters.mcp_server` | stdio JSON-RPC, 9 tools |
|
|
77
|
+
| Claude Skill | `plugin/skills/` | Claude Code SKILL.md files |
|
|
78
|
+
|
|
79
|
+
## Configuration
|
|
80
|
+
|
|
81
|
+
`memplex config init` creates `memplex.yaml`. Override via env vars `MEMPLEX_*`.
|
|
82
|
+
|
|
83
|
+
## Storage
|
|
84
|
+
|
|
85
|
+
- **Default**: LiteMemoryStore (in-memory + JSON persistence at `.memplex/memory.json`)
|
|
86
|
+
- **Optional**: ChromaDB (vector embeddings), SQLite/Postgres (feedback)
|
|
87
|
+
|
|
88
|
+
## Privacy
|
|
89
|
+
|
|
90
|
+
`<private>content</private>` tags prevent storage of tagged content.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Memplex -- multi-agent memory system.
|
|
2
|
+
|
|
3
|
+
Primary entry point::
|
|
4
|
+
|
|
5
|
+
from memplex import MemplexService
|
|
6
|
+
|
|
7
|
+
svc = MemplexService()
|
|
8
|
+
result = svc.query("登录函数在哪")
|
|
9
|
+
|
|
10
|
+
CLI usage::
|
|
11
|
+
|
|
12
|
+
memplex query "search text"
|
|
13
|
+
memplex write --text "content"
|
|
14
|
+
memplex health
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from memplex.core import CoreEngine
|
|
18
|
+
from memplex.service import MemplexService
|
|
19
|
+
|
|
20
|
+
__all__ = ["CoreEngine", "MemplexService", "main"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> None:
|
|
24
|
+
"""CLI entry point for ``memplex`` command.
|
|
25
|
+
|
|
26
|
+
Delegates to :func:`memplex.adapters.cli.main`.
|
|
27
|
+
"""
|
|
28
|
+
import sys
|
|
29
|
+
from memplex.adapters.cli import main as cli_main
|
|
30
|
+
|
|
31
|
+
sys.exit(cli_main())
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "articultur"
|
|
7
7
|
},
|
|
8
|
-
"repository": "https://github.com/articultur/
|
|
8
|
+
"repository": "https://github.com/articultur/Memplex",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"claude",
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
"python",
|
|
21
21
|
"fastapi"
|
|
22
22
|
],
|
|
23
|
-
"homepage": "https://github.com/articultur/
|
|
23
|
+
"homepage": "https://github.com/articultur/Memplex#readme"
|
|
24
24
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "
|
|
2
|
+
"description": "Memplex memory system hooks",
|
|
3
3
|
"hooks": {
|
|
4
4
|
"SessionStart": [
|
|
5
5
|
{
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{
|
|
9
9
|
"type": "command",
|
|
10
10
|
"shell": "bash",
|
|
11
|
-
"command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\";
|
|
11
|
+
"command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; MEMPLEX_ROOT=\"${MEMPLEX_PLUGIN_ROOT:-$(cd \"$(dirname \"$0\")/..\" && pwd)}\"; python \"$MEMPLEX_ROOT/scripts/hook-runner.py\" session-start",
|
|
12
12
|
"timeout": 30
|
|
13
13
|
}
|
|
14
14
|
]
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
{
|
|
22
22
|
"type": "command",
|
|
23
23
|
"shell": "bash",
|
|
24
|
-
"command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\";
|
|
24
|
+
"command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; MEMPLEX_ROOT=\"${MEMPLEX_PLUGIN_ROOT:-$(cd \"$(dirname \"$0\")/..\" && pwd)}\"; python \"$MEMPLEX_ROOT/scripts/hook-runner.py\" observation \"$MEMPLEX_TOOL_NAME\" \"$MEMPLEX_SESSION_ID\"",
|
|
25
25
|
"timeout": 15
|
|
26
26
|
}
|
|
27
27
|
]
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
{
|
|
34
34
|
"type": "command",
|
|
35
35
|
"shell": "bash",
|
|
36
|
-
"command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\";
|
|
36
|
+
"command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; MEMPLEX_ROOT=\"${MEMPLEX_PLUGIN_ROOT:-$(cd \"$(dirname \"$0\")/..\" && pwd)}\"; python \"$MEMPLEX_ROOT/scripts/hook-runner.py\" session-stop",
|
|
37
37
|
"timeout": 60
|
|
38
38
|
}
|
|
39
39
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""Memplex Hook Runner -- dispatches lifecycle hooks for Claude Code.
|
|
3
3
|
|
|
4
4
|
Called by plugin/hooks/hooks.json with subcommands:
|
|
5
5
|
session-start - Load project context on session start
|
|
@@ -27,13 +27,13 @@ import time
|
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
from typing import Optional
|
|
29
29
|
|
|
30
|
-
# Ensure
|
|
30
|
+
# Ensure memplex package is importable when run from plugin directory
|
|
31
31
|
_PLUGIN_DIR = Path(__file__).resolve().parent
|
|
32
32
|
_PROJECT_ROOT = _PLUGIN_DIR.parent.parent
|
|
33
33
|
if str(_PROJECT_ROOT) not in sys.path:
|
|
34
34
|
sys.path.insert(0, str(_PROJECT_ROOT))
|
|
35
35
|
|
|
36
|
-
_RATE_FILE = Path("/tmp/.
|
|
36
|
+
_RATE_FILE = Path("/tmp/.memplex_last_obs")
|
|
37
37
|
_RATE_LIMIT_SECONDS = 30
|
|
38
38
|
_PRIVATE_TAG_RE = re.compile(r"<private>.*?</private>", re.DOTALL)
|
|
39
39
|
|
|
@@ -43,22 +43,22 @@ def _strip_private_tags(text: str) -> str:
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def _get_store_path() -> Optional[Path]:
|
|
46
|
-
project_root = os.environ.get("
|
|
46
|
+
project_root = os.environ.get("MEMPLEX_PROJECT_ROOT", "")
|
|
47
47
|
if project_root:
|
|
48
|
-
p = Path(project_root) / ".
|
|
48
|
+
p = Path(project_root) / ".memplex" / "memory.json"
|
|
49
49
|
if p.parent.exists():
|
|
50
50
|
return p
|
|
51
51
|
cwd = Path.cwd()
|
|
52
|
-
p = cwd / ".
|
|
52
|
+
p = cwd / ".memplex" / "memory.json"
|
|
53
53
|
return p if p.parent.exists() else None
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
def _init_service():
|
|
57
|
-
from
|
|
58
|
-
from
|
|
57
|
+
from memplex.config import load_config
|
|
58
|
+
from memplex.service import MemplexService
|
|
59
59
|
|
|
60
60
|
cfg = load_config()
|
|
61
|
-
return
|
|
61
|
+
return MemplexService(config=cfg)
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
def cmd_session_start() -> None:
|
|
@@ -67,22 +67,22 @@ def cmd_session_start() -> None:
|
|
|
67
67
|
service = _init_service()
|
|
68
68
|
result = service.query(text="", top_k=5)
|
|
69
69
|
if result.results:
|
|
70
|
-
lines = ["[
|
|
70
|
+
lines = ["[Memplex Context] Top recent memories:"]
|
|
71
71
|
for r in result.results[:5]:
|
|
72
72
|
lines.append(f" - {r.name} (domain: {r.domain}, relevance: {r.relevance_score:.2f})")
|
|
73
73
|
output = "\n".join(lines)
|
|
74
74
|
print(output)
|
|
75
75
|
else:
|
|
76
|
-
print("[
|
|
76
|
+
print("[Memplex] No memories stored yet for this project.")
|
|
77
77
|
except Exception as e:
|
|
78
|
-
print(f"[
|
|
78
|
+
print(f"[Memplex] session-start error: {e}", file=sys.stderr)
|
|
79
79
|
sys.exit(0)
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
def cmd_observation(tool_name: str = "", session_id: str = "") -> None:
|
|
83
83
|
"""Auto-collect observation from tool usage."""
|
|
84
84
|
if not tool_name:
|
|
85
|
-
tool_name = os.environ.get("
|
|
85
|
+
tool_name = os.environ.get("MEMPLEX_TOOL_NAME", "unknown")
|
|
86
86
|
|
|
87
87
|
# Rate limit
|
|
88
88
|
if _RATE_FILE.exists():
|
|
@@ -136,9 +136,9 @@ def cmd_session_stop() -> None:
|
|
|
136
136
|
"total_memories": stats.get("total_functions", 0),
|
|
137
137
|
"total_edges": stats.get("total_edges", 0),
|
|
138
138
|
}, ensure_ascii=False)
|
|
139
|
-
print(f"[
|
|
139
|
+
print(f"[Memplex] Session ended. {summary}")
|
|
140
140
|
except Exception as e:
|
|
141
|
-
print(f"[
|
|
141
|
+
print(f"[Memplex] session-stop error: {e}", file=sys.stderr)
|
|
142
142
|
sys.exit(0)
|
|
143
143
|
|
|
144
144
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mem-explore
|
|
3
|
-
description: Explore
|
|
3
|
+
description: Explore Memplex knowledge graph. Use when user asks "what do we know about X?", "explore memories", "show related concepts", or wants to browse the knowledge base.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Memory Explore
|
|
7
7
|
|
|
8
|
-
Browse and explore the
|
|
8
|
+
Browse and explore the Memplex knowledge graph to understand related concepts and connections.
|
|
9
9
|
|
|
10
10
|
## When to Use
|
|
11
11
|
|
|
@@ -40,10 +40,10 @@ Use CLI to see overall state:
|
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
# Service health
|
|
43
|
-
|
|
43
|
+
memplex health
|
|
44
44
|
|
|
45
45
|
# Statistics (total memories, types breakdown, graph edges)
|
|
46
|
-
|
|
46
|
+
memplex stats
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
### Review Pending Conflicts
|
|
@@ -72,7 +72,7 @@ Each memory has metadata:
|
|
|
72
72
|
|
|
73
73
|
## Graph Relationships
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Memplex auto-detects three edge types:
|
|
76
76
|
|
|
77
77
|
| Edge | Meaning |
|
|
78
78
|
|------|---------|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mem-manage
|
|
3
|
-
description: Manage
|
|
3
|
+
description: Manage Memplex memory system. Use when user asks to "compact memories", "cleanup database", "memory stats", "run compaction", or perform maintenance operations.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Memory Manage
|
|
7
7
|
|
|
8
|
-
Perform maintenance and management operations on the
|
|
8
|
+
Perform maintenance and management operations on the Memplex knowledge base.
|
|
9
9
|
|
|
10
10
|
## When to Use
|
|
11
11
|
|
|
@@ -28,13 +28,13 @@ memory_health()
|
|
|
28
28
|
Or via CLI:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
|
|
31
|
+
memplex health
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
### Statistics
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
|
|
37
|
+
memplex stats
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Shows total memories, breakdown by type, graph edges, storage size.
|
|
@@ -45,10 +45,10 @@ Shows total memories, breakdown by type, graph edges, storage size.
|
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
# Compact project-level memories
|
|
48
|
-
|
|
48
|
+
memplex compact --scope project
|
|
49
49
|
|
|
50
50
|
# Compact all memories
|
|
51
|
-
|
|
51
|
+
memplex compact --scope global
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Compaction automatically:
|
|
@@ -75,7 +75,7 @@ memory_delete(memory_id="func_abc123")
|
|
|
75
75
|
Or via CLI:
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
|
-
|
|
78
|
+
memplex delete func_abc123
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
### Update Memory Fields
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mem-search
|
|
3
|
-
description: Search
|
|
3
|
+
description: Search Memplex persistent memory. Use when user asks "did we already solve this?", "how did we do X?", "recall", "lookup", or needs work from previous sessions.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Memory Search
|
|
7
7
|
|
|
8
|
-
Search
|
|
8
|
+
Search Memplex knowledge graph across all sessions. Simple workflow: search → filter → fetch.
|
|
9
9
|
|
|
10
10
|
## When to Use
|
|
11
11
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mem-write
|
|
3
|
-
description: Store knowledge into
|
|
3
|
+
description: Store knowledge into Memplex memory. Use when user says "remember this", "save this", "memorize", "store", or provides documents/URLs/content for future reference.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Memory Write
|
|
7
7
|
|
|
8
|
-
Store knowledge into
|
|
8
|
+
Store knowledge into Memplex for persistent cross-session retrieval.
|
|
9
9
|
|
|
10
10
|
## When to Use
|
|
11
11
|
|
|
@@ -41,7 +41,7 @@ memory_add(content="Steps to deploy: 1) Run tests 2) Build 3) Push to main", sou
|
|
|
41
41
|
Use the CLI:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
|
|
44
|
+
memplex write --file /path/to/document.md
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
### Store from URL
|
|
@@ -49,7 +49,7 @@ memnex write --file /path/to/document.md
|
|
|
49
49
|
Use the CLI:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
|
|
52
|
+
memplex write --url https://example.com/docs
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
### Review What Was Stored
|
|
@@ -62,7 +62,7 @@ memory_get(memory_id="func_abc123")
|
|
|
62
62
|
|
|
63
63
|
## What Gets Stored
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
Memplex extracts structured knowledge into 4 memory types:
|
|
66
66
|
|
|
67
67
|
| Type | Structure | Example |
|
|
68
68
|
|------|-----------|---------|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Memplex Agent Adapters -- protocol-specific interfaces.
|
|
2
|
+
|
|
3
|
+
Provides adapters for different consumption patterns:
|
|
4
|
+
|
|
5
|
+
- CLI: command-line interface (``memplex`` command)
|
|
6
|
+
- HTTP: REST API via FastAPI (``create_app`` factory)
|
|
7
|
+
- MCP: Model Context Protocol server over stdio JSON-RPC
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from memplex.adapters.cli import main as cli_main
|
|
11
|
+
from memplex.adapters.http_api import create_app
|
|
12
|
+
from memplex.adapters.mcp_server import MCPServer
|
|
13
|
+
|
|
14
|
+
__all__ = ["cli_main", "create_app", "MCPServer"]
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Memplex Claude Skill Adapter -- generates SKILL.md and hook scripts.
|
|
2
2
|
|
|
3
|
-
Generates files that integrate
|
|
3
|
+
Generates files that integrate Memplex into Claude Code's skill system:
|
|
4
4
|
|
|
5
5
|
- ``SKILL.md``: skill description with YAML frontmatter and trigger conditions
|
|
6
6
|
- ``hook.sh``: PostToolUse hook script that auto-collects observations
|
|
7
7
|
|
|
8
8
|
Usage::
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from memplex.adapters.claude_skill import generate_skill_md, generate_hook_sh
|
|
11
11
|
|
|
12
12
|
skill_content = generate_skill_md()
|
|
13
13
|
hook_content = generate_hook_sh()
|
|
@@ -21,11 +21,11 @@ from typing import Optional
|
|
|
21
21
|
|
|
22
22
|
_SKILL_MD_TEMPLATE = textwrap.dedent("""\
|
|
23
23
|
---
|
|
24
|
-
name:
|
|
25
|
-
description: Search and manage
|
|
24
|
+
name: memplex
|
|
25
|
+
description: Search and manage Memplex persistent memory. Use when user asks to "search memory", "recall", "remember this", "save", "lookup", or needs knowledge from previous sessions.
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
#
|
|
28
|
+
# Memplex Memory Skill
|
|
29
29
|
|
|
30
30
|
Persistent knowledge graph for multi-agent workflows. Store, query, and
|
|
31
31
|
manage knowledge that persists across sessions.
|
|
@@ -36,7 +36,7 @@ _SKILL_MD_TEMPLATE = textwrap.dedent("""\
|
|
|
36
36
|
- Asks to find or recall information from past sessions
|
|
37
37
|
- Provides content and asks to "remember" or "save" it
|
|
38
38
|
- Wants to review, correct, or update existing memories
|
|
39
|
-
- Uses keywords: "
|
|
39
|
+
- Uses keywords: "memplex", "memory", "remember", "recall", "lookup"
|
|
40
40
|
|
|
41
41
|
## 3-Layer Retrieval (ALWAYS Follow)
|
|
42
42
|
|
|
@@ -81,12 +81,12 @@ _SKILL_MD_TEMPLATE = textwrap.dedent("""\
|
|
|
81
81
|
## CLI Commands
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
memplex query "search text" # Search memories
|
|
85
|
+
memplex write --text "content" # Write memory
|
|
86
|
+
memplex get <memory_id> # Get details
|
|
87
|
+
memplex health # Health check
|
|
88
|
+
memplex stats # Statistics
|
|
89
|
+
memplex compact --scope project # Run compaction
|
|
90
90
|
```
|
|
91
91
|
""")
|
|
92
92
|
|
|
@@ -105,18 +105,18 @@ def generate_skill_md(output_path: Optional[str] = None) -> str:
|
|
|
105
105
|
|
|
106
106
|
_HOOK_SH_TEMPLATE = textwrap.dedent("""\
|
|
107
107
|
#!/usr/bin/env bash
|
|
108
|
-
#
|
|
108
|
+
# Memplex PostToolUse Hook -- auto-collect observations
|
|
109
109
|
#
|
|
110
110
|
# Register in plugin/hooks/hooks.json.
|
|
111
111
|
#
|
|
112
112
|
# Environment variables provided by Claude Code:
|
|
113
|
-
#
|
|
114
|
-
#
|
|
113
|
+
# MEMPLEX_TOOL_NAME - name of the tool that was called
|
|
114
|
+
# MEMPLEX_SESSION_ID - current session identifier
|
|
115
115
|
|
|
116
116
|
set -euo pipefail
|
|
117
117
|
|
|
118
118
|
# Rate limit: skip if last observation was less than 30 seconds ago
|
|
119
|
-
RATE_FILE="/tmp/.
|
|
119
|
+
RATE_FILE="/tmp/.memplex_last_obs_${MEMPLEX_SESSION_ID:-default}"
|
|
120
120
|
if [ -f "$RATE_FILE" ]; then
|
|
121
121
|
LAST=$(cat "$RATE_FILE" 2>/dev/null || echo 0)
|
|
122
122
|
NOW=$(date +%s)
|
|
@@ -126,8 +126,8 @@ _HOOK_SH_TEMPLATE = textwrap.dedent("""\
|
|
|
126
126
|
fi
|
|
127
127
|
fi
|
|
128
128
|
|
|
129
|
-
TOOL_NAME="${
|
|
130
|
-
TOOL_INPUT="${
|
|
129
|
+
TOOL_NAME="${MEMPLEX_TOOL_NAME:-unknown}"
|
|
130
|
+
TOOL_INPUT="${MEMPLEX_TOOL_INPUT:-}"
|
|
131
131
|
|
|
132
132
|
# Skip low-value tools
|
|
133
133
|
case "$TOOL_NAME" in
|
|
@@ -143,8 +143,8 @@ _HOOK_SH_TEMPLATE = textwrap.dedent("""\
|
|
|
143
143
|
fi
|
|
144
144
|
|
|
145
145
|
# Store observation via CLI
|
|
146
|
-
if command -v
|
|
147
|
-
|
|
146
|
+
if command -v memplex &>/dev/null; then
|
|
147
|
+
memplex write --text "$OBS_TEXT" --output json 2>/dev/null || true
|
|
148
148
|
fi
|
|
149
149
|
|
|
150
150
|
# Update rate limit timestamp
|