pkmrag 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.
- pkmrag-0.9.0/.env.example +52 -0
- pkmrag-0.9.0/.github/workflows/ci.yml +44 -0
- pkmrag-0.9.0/.gitignore +67 -0
- pkmrag-0.9.0/.python-version +1 -0
- pkmrag-0.9.0/AGENTS.md +95 -0
- pkmrag-0.9.0/LICENSE +21 -0
- pkmrag-0.9.0/PKG-INFO +290 -0
- pkmrag-0.9.0/README.md +247 -0
- pkmrag-0.9.0/SECURITY.md +25 -0
- pkmrag-0.9.0/assets/apple-touch-icon.png +0 -0
- pkmrag-0.9.0/assets/favicon.ico +0 -0
- pkmrag-0.9.0/assets/favicon.svg +1 -0
- pkmrag-0.9.0/assets/obsidian-ribbon-icon.svg +8 -0
- pkmrag-0.9.0/assets/pkmrag-avatar-500.png +0 -0
- pkmrag-0.9.0/assets/pkmrag-icon-512.png +0 -0
- pkmrag-0.9.0/assets/pkmrag-icon.svg +1 -0
- pkmrag-0.9.0/assets/pkmrag-logo-dark.svg +1 -0
- pkmrag-0.9.0/assets/pkmrag-logo-text-dark.svg +1 -0
- pkmrag-0.9.0/assets/pkmrag-logo-text.svg +1 -0
- pkmrag-0.9.0/assets/pkmrag-logo.svg +1 -0
- pkmrag-0.9.0/assets/pkmrag-social-preview.png +0 -0
- pkmrag-0.9.0/assets/pkmrag-social-preview.svg +1 -0
- pkmrag-0.9.0/benchmarks/golden_10.json +62 -0
- pkmrag-0.9.0/benchmarks/golden_50_obsidian_help.json +352 -0
- pkmrag-0.9.0/benchmarks/vault/Concepts/Hybrid Search.md +16 -0
- pkmrag-0.9.0/benchmarks/vault/Concepts/Lexical BM25.md +10 -0
- pkmrag-0.9.0/benchmarks/vault/Concepts/Property Graphs.md +19 -0
- pkmrag-0.9.0/benchmarks/vault/Concepts/Reciprocal Rank Fusion.md +13 -0
- pkmrag-0.9.0/benchmarks/vault/Daily/2026-09-27.md +15 -0
- pkmrag-0.9.0/benchmarks/vault/Index.md +19 -0
- pkmrag-0.9.0/benchmarks/vault/Projects/FastMCP Server.md +19 -0
- pkmrag-0.9.0/benchmarks/vault/Projects/Orbit Core.md +32 -0
- pkmrag-0.9.0/benchmarks/vault/Projects/Storage Layer.md +16 -0
- pkmrag-0.9.0/benchmarks/vault/Research/GraphRAG Paradigms.md +21 -0
- pkmrag-0.9.0/benchmarks/vault/Research/Model Context Protocol.md +11 -0
- pkmrag-0.9.0/benchmarks/vault/Research/Vector Retrieval.md +12 -0
- pkmrag-0.9.0/docs/adr/0001-embedded-in-process-storage.md +34 -0
- pkmrag-0.9.0/docs/adr/0002-pluggable-dialect-strategy.md +34 -0
- pkmrag-0.9.0/docs/adr/0003-reciprocal-rank-fusion-ranking.md +35 -0
- pkmrag-0.9.0/docs/adr/0004-mcp-as-primary-interface.md +36 -0
- pkmrag-0.9.0/docs/adr/0005-openai-compatible-inference-layer.md +32 -0
- pkmrag-0.9.0/docs/adr/0006-l1-query-cache-and-on-demand-digestion.md +42 -0
- pkmrag-0.9.0/docs/architecture.md +75 -0
- pkmrag-0.9.0/docs/subsystems/benchmarks.md +90 -0
- pkmrag-0.9.0/docs/subsystems/caching.md +93 -0
- pkmrag-0.9.0/docs/subsystems/discovery.md +42 -0
- pkmrag-0.9.0/docs/subsystems/graph-engine.md +62 -0
- pkmrag-0.9.0/docs/subsystems/http-transport.md +157 -0
- pkmrag-0.9.0/docs/subsystems/hybrid-search.md +50 -0
- pkmrag-0.9.0/docs/subsystems/inference.md +51 -0
- pkmrag-0.9.0/docs/subsystems/ingestion.md +49 -0
- pkmrag-0.9.0/docs/subsystems/local-inference.md +110 -0
- pkmrag-0.9.0/docs/subsystems/mcp.md +81 -0
- pkmrag-0.9.0/docs/subsystems/observability.md +115 -0
- pkmrag-0.9.0/docs/subsystems/obsidian-plugin.md +151 -0
- pkmrag-0.9.0/docs/subsystems/search-engine.md +47 -0
- pkmrag-0.9.0/package.json +15 -0
- pkmrag-0.9.0/plugins/obsidian/esbuild.config.mjs +49 -0
- pkmrag-0.9.0/plugins/obsidian/icon.svg +8 -0
- pkmrag-0.9.0/plugins/obsidian/main.js +1752 -0
- pkmrag-0.9.0/plugins/obsidian/manifest.json +11 -0
- pkmrag-0.9.0/plugins/obsidian/package-lock.json +637 -0
- pkmrag-0.9.0/plugins/obsidian/package.json +35 -0
- pkmrag-0.9.0/plugins/obsidian/scripts/install.mjs +134 -0
- pkmrag-0.9.0/plugins/obsidian/src/client.ts +291 -0
- pkmrag-0.9.0/plugins/obsidian/src/client_events.ts +40 -0
- pkmrag-0.9.0/plugins/obsidian/src/commands.ts +97 -0
- pkmrag-0.9.0/plugins/obsidian/src/daemon.ts +255 -0
- pkmrag-0.9.0/plugins/obsidian/src/extension.ts +114 -0
- pkmrag-0.9.0/plugins/obsidian/src/main.ts +237 -0
- pkmrag-0.9.0/plugins/obsidian/src/settings.ts +217 -0
- pkmrag-0.9.0/plugins/obsidian/src/settings_llm.ts +113 -0
- pkmrag-0.9.0/plugins/obsidian/src/status_bar.ts +110 -0
- pkmrag-0.9.0/plugins/obsidian/src/types.ts +163 -0
- pkmrag-0.9.0/plugins/obsidian/src/view.ts +242 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_gaps.ts +88 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_inferences.ts +83 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_offline.ts +74 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_progress.ts +39 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_search.ts +124 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_setup_wizard.ts +77 -0
- pkmrag-0.9.0/plugins/obsidian/src/view_unindexed.ts +54 -0
- pkmrag-0.9.0/plugins/obsidian/styles.css +201 -0
- pkmrag-0.9.0/plugins/obsidian/tests/client.test.ts +224 -0
- pkmrag-0.9.0/plugins/obsidian/tests/compliance.test.ts +279 -0
- pkmrag-0.9.0/plugins/obsidian/tsconfig.json +19 -0
- pkmrag-0.9.0/plugins/obsidian/versions.json +3 -0
- pkmrag-0.9.0/pyproject.toml +90 -0
- pkmrag-0.9.0/src/pkmrag/__init__.py +5 -0
- pkmrag-0.9.0/src/pkmrag/cache/__init__.py +8 -0
- pkmrag-0.9.0/src/pkmrag/cache/manager.py +98 -0
- pkmrag-0.9.0/src/pkmrag/cache/sqlite_cache.py +264 -0
- pkmrag-0.9.0/src/pkmrag/cli.py +294 -0
- pkmrag-0.9.0/src/pkmrag/cli_views.py +274 -0
- pkmrag-0.9.0/src/pkmrag/config.py +204 -0
- pkmrag-0.9.0/src/pkmrag/dialects/__init__.py +14 -0
- pkmrag-0.9.0/src/pkmrag/dialects/base.py +46 -0
- pkmrag-0.9.0/src/pkmrag/dialects/commonmark.py +149 -0
- pkmrag-0.9.0/src/pkmrag/dialects/obsidian.py +172 -0
- pkmrag-0.9.0/src/pkmrag/dialects/registry.py +60 -0
- pkmrag-0.9.0/src/pkmrag/discovery/__init__.py +7 -0
- pkmrag-0.9.0/src/pkmrag/discovery/engine.py +278 -0
- pkmrag-0.9.0/src/pkmrag/doctor.py +200 -0
- pkmrag-0.9.0/src/pkmrag/eval/__init__.py +16 -0
- pkmrag-0.9.0/src/pkmrag/eval/harness.py +145 -0
- pkmrag-0.9.0/src/pkmrag/eval/metrics.py +104 -0
- pkmrag-0.9.0/src/pkmrag/eval/models.py +62 -0
- pkmrag-0.9.0/src/pkmrag/eval/views.py +124 -0
- pkmrag-0.9.0/src/pkmrag/graph/__init__.py +6 -0
- pkmrag-0.9.0/src/pkmrag/graph/paths.py +199 -0
- pkmrag-0.9.0/src/pkmrag/graph/schema.py +64 -0
- pkmrag-0.9.0/src/pkmrag/graph/store.py +290 -0
- pkmrag-0.9.0/src/pkmrag/graph/traversal.py +191 -0
- pkmrag-0.9.0/src/pkmrag/inference/__init__.py +21 -0
- pkmrag-0.9.0/src/pkmrag/inference/base.py +69 -0
- pkmrag-0.9.0/src/pkmrag/inference/factory.py +51 -0
- pkmrag-0.9.0/src/pkmrag/inference/limiter.py +134 -0
- pkmrag-0.9.0/src/pkmrag/inference/mock.py +45 -0
- pkmrag-0.9.0/src/pkmrag/inference/ollama.py +37 -0
- pkmrag-0.9.0/src/pkmrag/inference/provider.py +259 -0
- pkmrag-0.9.0/src/pkmrag/ingest/__init__.py +8 -0
- pkmrag-0.9.0/src/pkmrag/ingest/pipeline.py +228 -0
- pkmrag-0.9.0/src/pkmrag/ingest/reindexer.py +258 -0
- pkmrag-0.9.0/src/pkmrag/mcp/__init__.py +8 -0
- pkmrag-0.9.0/src/pkmrag/mcp/auth.py +92 -0
- pkmrag-0.9.0/src/pkmrag/mcp/events.py +47 -0
- pkmrag-0.9.0/src/pkmrag/mcp/http_ops.py +255 -0
- pkmrag-0.9.0/src/pkmrag/mcp/http_server.py +273 -0
- pkmrag-0.9.0/src/pkmrag/mcp/server.py +213 -0
- pkmrag-0.9.0/src/pkmrag/mcp/server_state.py +143 -0
- pkmrag-0.9.0/src/pkmrag/mcp/tools.py +271 -0
- pkmrag-0.9.0/src/pkmrag/mcp/tools_sync.py +92 -0
- pkmrag-0.9.0/src/pkmrag/mcp/tools_vault.py +213 -0
- pkmrag-0.9.0/src/pkmrag/mcp/views.py +99 -0
- pkmrag-0.9.0/src/pkmrag/models.py +255 -0
- pkmrag-0.9.0/src/pkmrag/parser/__init__.py +19 -0
- pkmrag-0.9.0/src/pkmrag/parser/indexer.py +132 -0
- pkmrag-0.9.0/src/pkmrag/parser/markdown.py +227 -0
- pkmrag-0.9.0/src/pkmrag/plugin.py +233 -0
- pkmrag-0.9.0/src/pkmrag/plugin_assets/icon.svg +8 -0
- pkmrag-0.9.0/src/pkmrag/plugin_assets/main.js +1752 -0
- pkmrag-0.9.0/src/pkmrag/plugin_assets/manifest.json +11 -0
- pkmrag-0.9.0/src/pkmrag/plugin_assets/styles.css +201 -0
- pkmrag-0.9.0/src/pkmrag/search/__init__.py +21 -0
- pkmrag-0.9.0/src/pkmrag/search/chunker.py +236 -0
- pkmrag-0.9.0/src/pkmrag/search/embedder.py +80 -0
- pkmrag-0.9.0/src/pkmrag/search/fusion.py +135 -0
- pkmrag-0.9.0/src/pkmrag/search/service.py +188 -0
- pkmrag-0.9.0/src/pkmrag/search/vector_store.py +146 -0
- pkmrag-0.9.0/src/pkmrag/telemetry/__init__.py +28 -0
- pkmrag-0.9.0/src/pkmrag/telemetry/collector.py +75 -0
- pkmrag-0.9.0/src/pkmrag/telemetry/spans.py +105 -0
- pkmrag-0.9.0/src/pkmrag/telemetry/tracer.py +101 -0
- pkmrag-0.9.0/src/pkmrag/telemetry/views.py +102 -0
- pkmrag-0.9.0/src/pkmrag/vault_config.py +120 -0
- pkmrag-0.9.0/tests/conftest.py +43 -0
- pkmrag-0.9.0/tests/test_benchmark.py +56 -0
- pkmrag-0.9.0/tests/test_benchmark_obsidian_help.py +102 -0
- pkmrag-0.9.0/tests/test_cache.py +188 -0
- pkmrag-0.9.0/tests/test_chunker.py +92 -0
- pkmrag-0.9.0/tests/test_cli.py +93 -0
- pkmrag-0.9.0/tests/test_cli_discover.py +130 -0
- pkmrag-0.9.0/tests/test_dialects.py +180 -0
- pkmrag-0.9.0/tests/test_discovery.py +173 -0
- pkmrag-0.9.0/tests/test_doctor.py +102 -0
- pkmrag-0.9.0/tests/test_embedder.py +37 -0
- pkmrag-0.9.0/tests/test_eval_cli.py +109 -0
- pkmrag-0.9.0/tests/test_eval_metrics.py +167 -0
- pkmrag-0.9.0/tests/test_fusion.py +72 -0
- pkmrag-0.9.0/tests/test_graph_paths.py +118 -0
- pkmrag-0.9.0/tests/test_graph_scoping.py +77 -0
- pkmrag-0.9.0/tests/test_http_ops.py +105 -0
- pkmrag-0.9.0/tests/test_inference.py +224 -0
- pkmrag-0.9.0/tests/test_inference_telemetry.py +114 -0
- pkmrag-0.9.0/tests/test_inference_validation_retry.py +106 -0
- pkmrag-0.9.0/tests/test_ingest.py +255 -0
- pkmrag-0.9.0/tests/test_mcp_auth.py +88 -0
- pkmrag-0.9.0/tests/test_mcp_http.py +166 -0
- pkmrag-0.9.0/tests/test_mcp_server.py +122 -0
- pkmrag-0.9.0/tests/test_mcp_sync.py +85 -0
- pkmrag-0.9.0/tests/test_mcp_tools.py +265 -0
- pkmrag-0.9.0/tests/test_ollama.py +63 -0
- pkmrag-0.9.0/tests/test_plugin.py +164 -0
- pkmrag-0.9.0/tests/test_reindexer.py +219 -0
- pkmrag-0.9.0/tests/test_search.py +124 -0
- pkmrag-0.9.0/tests/test_search_tracing.py +97 -0
- pkmrag-0.9.0/tests/test_server_state.py +54 -0
- pkmrag-0.9.0/tests/test_telemetry.py +161 -0
- pkmrag-0.9.0/tests/test_trace_cli.py +78 -0
- pkmrag-0.9.0/tests/test_vault_config.py +69 -0
- pkmrag-0.9.0/tests/test_vector_store.py +64 -0
- pkmrag-0.9.0/uv.lock +2288 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# PKMRAG — Environment Configuration
|
|
3
|
+
# Copy this file to .env and adjust variables as needed:
|
|
4
|
+
# cp .env.example .env
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
# LLM Inference (Phase 4 Semantic Gap Detection)
|
|
8
|
+
# ------------------------------------------------------------------------------
|
|
9
|
+
# API key for the inference provider (Groq, OpenAI, OpenRouter, etc.)
|
|
10
|
+
OPENAI_API_KEY=your-api-key-here
|
|
11
|
+
|
|
12
|
+
# Alternatively, set a PKMRAG-specific API key override (ORBIT_LLM_API_KEY also supported)
|
|
13
|
+
# PKMRAG_LLM_API_KEY=your-pkmrag-api-key
|
|
14
|
+
|
|
15
|
+
# OpenAI-compatible API base URL
|
|
16
|
+
# Defaults to OpenAI's public API: https://api.openai.com/v1
|
|
17
|
+
# For Groq: https://api.groq.com/openai/v1
|
|
18
|
+
# For local Ollama: http://localhost:11434/v1
|
|
19
|
+
# For local vLLM / LiteLLM: http://localhost:8000/v1
|
|
20
|
+
# For OpenRouter: https://openrouter.ai/api/v1
|
|
21
|
+
OPENAI_BASE_URL=https://api.openai.com/v1
|
|
22
|
+
|
|
23
|
+
# Model identifier to use for classification
|
|
24
|
+
# Defaults to gpt-4o-mini
|
|
25
|
+
# Groq examples: llama-3.1-8b-instant, llama-3.3-70b-versatile
|
|
26
|
+
# Local examples: llama3.1, mistral-nemo, qwen2.5:7b
|
|
27
|
+
PKMRAG_LLM_MODEL=gpt-4o-mini
|
|
28
|
+
|
|
29
|
+
# LLM Rate Limiting
|
|
30
|
+
# ------------------------------------------------------------------------------
|
|
31
|
+
# Maximum requests per minute (RPM) to LLM provider (0 for unlimited)
|
|
32
|
+
# Default: 30
|
|
33
|
+
PKMRAG_LLM_RPM=30
|
|
34
|
+
|
|
35
|
+
# Maximum tokens per minute (TPM) to LLM provider (0 for unlimited)
|
|
36
|
+
# Default: 8000
|
|
37
|
+
PKMRAG_LLM_TPM=8000
|
|
38
|
+
|
|
39
|
+
# Maximum retries on HTTP 429 rate limit errors
|
|
40
|
+
# PKMRAG_LLM_MAX_RETRIES=3
|
|
41
|
+
|
|
42
|
+
# Storage & Directory Overrides (Optional)
|
|
43
|
+
# ------------------------------------------------------------------------------
|
|
44
|
+
# Default path to your Obsidian vault (used by `pkmrag install-plugin` and testing)
|
|
45
|
+
# PKMRAG_VAULT_PATH=/path/to/your/vault
|
|
46
|
+
|
|
47
|
+
# Default LadybugDB storage directory (defaults to <vault>/.pkmrag/graph)
|
|
48
|
+
# PKMRAG_DB_DIR=/custom/path/to/graph
|
|
49
|
+
|
|
50
|
+
# Default LanceDB vector storage directory (defaults to <vault>/.pkmrag/vectors)
|
|
51
|
+
# PKMRAG_VECTOR_DIR=/custom/path/to/vectors
|
|
52
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v5
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- run: uv sync --extra dev
|
|
19
|
+
- run: uv run pytest --cov=pkmrag --cov-report=term-missing
|
|
20
|
+
- name: Run retrieval evaluation quality gates
|
|
21
|
+
run: uv run pkmrag eval --min-mrr 0.80 --min-recall 0.80
|
|
22
|
+
|
|
23
|
+
lint:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: astral-sh/setup-uv@v5
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
- run: uv sync --extra dev
|
|
32
|
+
- run: uv run ruff check .
|
|
33
|
+
- run: uv run ruff format --check .
|
|
34
|
+
|
|
35
|
+
typecheck:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
- uses: astral-sh/setup-uv@v5
|
|
40
|
+
- uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.12"
|
|
43
|
+
- run: uv sync --extra dev
|
|
44
|
+
- run: uv run mypy src tests
|
pkmrag-0.9.0/.gitignore
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
# Virtual Environments
|
|
26
|
+
.venv/
|
|
27
|
+
env/
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
env.bak/
|
|
31
|
+
venv.bak/
|
|
32
|
+
|
|
33
|
+
# Testing & Linting
|
|
34
|
+
.pytest_cache/
|
|
35
|
+
.ruff_cache/
|
|
36
|
+
.mypy_cache/
|
|
37
|
+
.coverage
|
|
38
|
+
htmlcov/
|
|
39
|
+
|
|
40
|
+
# Local databases & storage (PKMRAG data)
|
|
41
|
+
*.kuzu/
|
|
42
|
+
*.lance/
|
|
43
|
+
*.db
|
|
44
|
+
*.sqlite
|
|
45
|
+
*.sqlite3
|
|
46
|
+
.pkmrag/
|
|
47
|
+
.orbit/
|
|
48
|
+
|
|
49
|
+
# IDE & OS
|
|
50
|
+
.vscode/
|
|
51
|
+
.idea/
|
|
52
|
+
*.swp
|
|
53
|
+
*.swo
|
|
54
|
+
.DS_Store
|
|
55
|
+
|
|
56
|
+
# Secrets & Environment Variables
|
|
57
|
+
.env
|
|
58
|
+
.env.*
|
|
59
|
+
!.env.example
|
|
60
|
+
|
|
61
|
+
# Scratch files
|
|
62
|
+
scratch/
|
|
63
|
+
|
|
64
|
+
# Node & Obsidian Plugin
|
|
65
|
+
node_modules/
|
|
66
|
+
plugins/obsidian/dist/
|
|
67
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
pkmrag-0.9.0/AGENTS.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# AGENTS.md — PKMRAG
|
|
2
|
+
|
|
3
|
+
## What This Is
|
|
4
|
+
|
|
5
|
+
A local-first Hybrid GraphRAG engine for linked personal knowledge bases (PKMs).
|
|
6
|
+
Obsidian serves as the primary reference dialect, with a pluggable dialect layer for CommonMark, Logseq, Foam, and other linked systems.
|
|
7
|
+
3-tier architecture: deterministic graph (LadybugDB) → semantic search (LanceDB) → AI gap detection (LLM).
|
|
8
|
+
Exposed as an MCP server — no chat UI.
|
|
9
|
+
|
|
10
|
+
## Project Layout
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/pkmrag/
|
|
14
|
+
cli.py # Typer CLI entry point
|
|
15
|
+
cli_views.py # Rich terminal display renderers
|
|
16
|
+
config.py # Settings, defaults, env vars
|
|
17
|
+
models.py # Pydantic data models (shared across modules)
|
|
18
|
+
doctor.py # `pkmrag doctor` health checks
|
|
19
|
+
dialects/ # Pluggable markdown dialect parsing (obsidian, commonmark)
|
|
20
|
+
cache/ # SQLite L1 query cache and dependency tracking
|
|
21
|
+
parser/ # Markdown parsing + vault file indexing
|
|
22
|
+
graph/ # LadybugDB graph store, schema DDL, and traversal
|
|
23
|
+
ingest/ # Vault → graph and vector ingestion pipeline & single-note reindexer
|
|
24
|
+
search/ # Chunking, FastEmbed, LanceDB vector store, RRF fusion, service
|
|
25
|
+
inference/ # LLM inference client (OpenAI, Ollama) and token-bucket rate limiter
|
|
26
|
+
discovery/ # Semantic gap discovery and relationship inference engine
|
|
27
|
+
eval/ # Retrieval evaluation harness and IR metrics (MRR, Recall, MAP)
|
|
28
|
+
telemetry/ # OpenTelemetry spans, collector, visual tree, tracer lifecycle
|
|
29
|
+
mcp/ # FastMCP server, tool handlers, and stdio transport
|
|
30
|
+
vault_config.py # Per-vault configuration reader/writer (<vault>/.pkmrag/config.json)
|
|
31
|
+
plugin.py # Obsidian plugin installer & bundler CLI
|
|
32
|
+
plugin_assets/ # Bundled standalone Obsidian plugin assets (manifest, main.js, styles)
|
|
33
|
+
|
|
34
|
+
tests/ # Mirrors src/pkmrag/ structure
|
|
35
|
+
benchmarks/ # Ground-truth evaluation benchmarks (golden_10, vault)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Hard Rules
|
|
40
|
+
|
|
41
|
+
1. **Max 300 lines per file.** If a file approaches this, split it. No exceptions.
|
|
42
|
+
2. **No overengineering.** Solve the problem in front of you. Don't add abstractions for hypothetical future needs.
|
|
43
|
+
3. **Simple > clever.** If a colleague can't understand it in 30 seconds, rewrite it.
|
|
44
|
+
4. **Prefer focused libraries over hand-rolled code.** If a well-maintained library solves the exact problem, use it — don't rewrite what's already battle-tested. But don't pull in a heavy framework for a single utility; the dependency's weight should be proportional to the value it provides.
|
|
45
|
+
5. **Type everything.** `mypy --strict` must pass. No `Any` escapes except for third-party lib boundaries.
|
|
46
|
+
6. **Pydantic for data boundaries.** All structured data crossing module boundaries uses Pydantic models defined in `models.py` (or a module-local `models.py` if domain-specific).
|
|
47
|
+
7. **Tests are mandatory.** Every new module gets a corresponding `tests/test_<module>.py`. Test behavior, not implementation.
|
|
48
|
+
8. **Preserve existing comments and docstrings** unless directly contradicted by the change.
|
|
49
|
+
9. **Keep docs current but minimal.** Update `README.md` and `AGENTS.md` when features or layout change. Don't pad them — if it's obvious from the code, don't document it.
|
|
50
|
+
|
|
51
|
+
## Style
|
|
52
|
+
|
|
53
|
+
- **Formatter/linter:** `ruff` (line-length 100). Run `uv run ruff check --fix . && uv run ruff format .`
|
|
54
|
+
- **Type checker:** `uv run mypy src/`
|
|
55
|
+
- **Tests:** `uv run pytest`
|
|
56
|
+
- Docstrings: one-line summary in `"""..."""`. Multi-line only when non-obvious.
|
|
57
|
+
- Imports: `from __future__ import annotations` at top of every module.
|
|
58
|
+
- Use `Path` from `pathlib`, never raw string paths for filesystem ops.
|
|
59
|
+
|
|
60
|
+
## Architecture Decisions (Don't Undo These)
|
|
61
|
+
|
|
62
|
+
- **Embedded DBs only.** LadybugDB + LanceDB + SQLite. No servers, no Docker, no network DBs.
|
|
63
|
+
- **Dialect-agnostic core.** The property graph, vector store, and MCP tools operate on abstract knowledge primitives (Note, Tag, Folder, LINKS_TO). All syntax parsing lives in pluggable `dialects/` (Obsidian, CommonMark, Logseq). Never introduce dialect-specific branching into storage, search, or MCP tools.
|
|
64
|
+
- **Incremental sync.** Ingestion compares file hashes; only changed files are reprocessed.
|
|
65
|
+
- **Inferred edges are separate from ground truth.** AI-discovered relationships go in their own table/label, tagged with confidence + model + timestamp. Never pollute human-curated graph data.
|
|
66
|
+
- **MCP over custom UI.** The primary interface is an MCP server (stdio + SSE), not a chat frontend.
|
|
67
|
+
|
|
68
|
+
## When Adding New Features
|
|
69
|
+
|
|
70
|
+
1. Ensure new functionality aligns with the architectural design and existing subsystems.
|
|
71
|
+
2. Put code in the right subpackage. Create a new one if needed — flat files over deep nesting.
|
|
72
|
+
3. Add CLI commands in `cli.py` using Typer. Keep handlers thin — delegate to engine modules.
|
|
73
|
+
4. Wire up tests before marking done.
|
|
74
|
+
|
|
75
|
+
## Common Commands
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv run pkmrag doctor # Sanity check both DBs
|
|
79
|
+
uv run pkmrag ingest <path> # Ingest a vault (all, graph, or vector)
|
|
80
|
+
uv run pkmrag search "query" --near <note># Hybrid search with graph boost
|
|
81
|
+
uv run pkmrag search "query" --trace # Hybrid search with visual execution trace tree
|
|
82
|
+
uv run pkmrag discover <path> # Discover semantic gaps and infer relationships
|
|
83
|
+
uv run pkmrag discover <path> -p ollama # Offline semantic discovery via local Ollama
|
|
84
|
+
uv run pkmrag eval # Automated IR retrieval evaluation against golden benchmark
|
|
85
|
+
uv run pkmrag serve <path> # Start stdio MCP server for Claude/Cursor
|
|
86
|
+
uv run pkmrag serve <path> -t http # Start HTTP/SSE MCP & REST daemon on port 3747
|
|
87
|
+
uv run pkmrag mcp-config <path> # Output MCP JSON client configuration
|
|
88
|
+
uv run pkmrag install-plugin # Install Obsidian companion plugin to vault (via PKMRAG_VAULT_PATH)
|
|
89
|
+
uv run pkmrag install-plugin --symlink # Symlink plugin files for live development
|
|
90
|
+
uv run ruff check --fix . # Lint
|
|
91
|
+
|
|
92
|
+
uv run ruff format . # Format
|
|
93
|
+
uv run mypy src tests # Type check
|
|
94
|
+
uv run pytest # Test
|
|
95
|
+
```
|
pkmrag-0.9.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Project Orbit Contributors
|
|
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.
|
pkmrag-0.9.0/PKG-INFO
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pkmrag
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: Local-first Hybrid GraphRAG retrieval engine and MCP server for linked knowledge bases
|
|
5
|
+
Project-URL: Homepage, https://github.com/pkmrag/pkmrag
|
|
6
|
+
Project-URL: Documentation, https://github.com/pkmrag/pkmrag#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/pkmrag/pkmrag
|
|
8
|
+
Project-URL: Issues, https://github.com/pkmrag/pkmrag/issues
|
|
9
|
+
Author: PKMRAG Contributors
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: graphrag,knowledge-graph,lancedb,mcp,obsidian,pkm,rag,vector-search
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: fastembed>=0.3.0
|
|
21
|
+
Requires-Dist: httpx>=0.27.0
|
|
22
|
+
Requires-Dist: ladybug>=0.20.0
|
|
23
|
+
Requires-Dist: lancedb>=0.38.0
|
|
24
|
+
Requires-Dist: mcp>=1.2.0
|
|
25
|
+
Requires-Dist: opentelemetry-api>=1.25.0
|
|
26
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.25.0
|
|
27
|
+
Requires-Dist: opentelemetry-sdk>=1.25.0
|
|
28
|
+
Requires-Dist: pyarrow>=17.0.0
|
|
29
|
+
Requires-Dist: pydantic-settings>=2.15.0
|
|
30
|
+
Requires-Dist: pydantic>=2.8.0
|
|
31
|
+
Requires-Dist: python-dotenv>=1.2.3
|
|
32
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
33
|
+
Requires-Dist: rich>=13.0.0
|
|
34
|
+
Requires-Dist: typer>=0.12.0
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.5.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<picture>
|
|
46
|
+
<source media="(prefers-color-scheme: dark)" srcset="assets/pkmrag-logo-text-dark.svg">
|
|
47
|
+
<img alt="PKMRAG" src="assets/pkmrag-logo-text.svg" width="520">
|
|
48
|
+
</picture>
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<strong>Embedded, Local-First Hybrid GraphRAG Retrieval Engine & MCP Server</strong>
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<a href="https://github.com/dev-hashemi/project-orbit/actions"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/dev-hashemi/project-orbit/ci.yml?branch=main&style=flat&label=CI&logo=githubactions&logoColor=white"></a>
|
|
57
|
+
<a href="https://github.com/dev-hashemi/project-orbit"><img alt="Coverage" src="https://img.shields.io/badge/coverage-89%25-brightgreen?style=flat&logo=pytest"></a>
|
|
58
|
+
<a href="https://www.python.org/downloads/"><img alt="Python" src="https://img.shields.io/badge/python-%3E%3D3.12-3776AB?style=flat&logo=python&logoColor=white"></a>
|
|
59
|
+
<a href="https://github.com/dev-hashemi/project-orbit/releases"><img alt="Version" src="https://img.shields.io/github/v/tag/dev-hashemi/project-orbit?style=flat&label=version&logo=github&logoColor=white"></a>
|
|
60
|
+
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-MIT-green?style=flat&logo=opensourceinitiative&logoColor=white"></a>
|
|
61
|
+
<a href="http://mypy-lang.org/"><img alt="Mypy" src="https://img.shields.io/badge/types-mypy_strict-2A6DB5?style=flat&logo=python&logoColor=white"></a>
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
PKMRAG is an open-source, local-first retrieval engine designed for linked personal knowledge bases (PKMs). While Obsidian serves as our primary reference dialect, PKMRAG operates on an abstract knowledge model supporting any linked document system (Logseq, Foam, CommonMark docs) via pluggable dialects. It combines an explicit structural property graph with an Arrow-backed vector and keyword search index, exposing contextual intelligence to frontier AI reasoning tools via the Model Context Protocol (MCP).
|
|
65
|
+
|
|
66
|
+
📖 **Technical Documentation:** [System Architecture & Subsystems](docs/architecture.md)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 🏛️ Architecture Overview
|
|
71
|
+
|
|
72
|
+
PKMRAG replaces brute-force triple extraction with a targeted, 3-tier discovery pipeline:
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
%%{init: {'theme': 'dark', 'themeVariables': { 'darkMode': true, 'background': 'transparent', 'mainBkg': '#1e293b', 'primaryColor': '#1e293b', 'primaryBorderColor': '#3b82f6', 'primaryTextColor': '#f8fafc', 'lineColor': '#38bdf8', 'edgeLabelBackground': '#1e293b' }}}%%
|
|
76
|
+
flowchart TD
|
|
77
|
+
Vault["📂 Linked Knowledge Base<br/><i>Obsidian, Logseq, CommonMark</i>"]
|
|
78
|
+
|
|
79
|
+
Vault --> T1["🏗️ Tier 1: Deterministic Parser ($0 Cost)"]
|
|
80
|
+
T1 --> BaseGraph[("LadybugDB Property Graph<br/><i>Wikilinks, Tags, Hierarchy</i>")]
|
|
81
|
+
|
|
82
|
+
Vault --> T2["🔍 Tier 2: Hybrid Semantic Index"]
|
|
83
|
+
T2 --> Lance[("LanceDB Vector & FTS Index<br/><i>Dense Embeddings + BM25</i>")]
|
|
84
|
+
|
|
85
|
+
BaseGraph --> T3["🧠 Tier 3: Semantic Gap Detector"]
|
|
86
|
+
Lance --> T3
|
|
87
|
+
T3 -->|"High vector similarity + graph distance ≥ 3"| Candidates["Unlinked Candidate Note Pairs"]
|
|
88
|
+
Candidates -->|"Targeted LLM Inference"| TypedEdges["Typed Relationships<br/><code>[:EXTENDS]</code>, <code>[:CONTRADICTS]</code>, <code>[:PREREQUISITE_FOR]</code>"]
|
|
89
|
+
TypedEdges --> BaseGraph
|
|
90
|
+
|
|
91
|
+
style T1 fill:#0f172a,stroke:#3b82f6,color:#e2e8f0
|
|
92
|
+
style T2 fill:#0f172a,stroke:#8b5cf6,color:#e2e8f0
|
|
93
|
+
style T3 fill:#7c2d12,stroke:#f97316,color:#e2e8f0
|
|
94
|
+
linkStyle default stroke:#38bdf8,stroke-width:2px;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 🚀 Key Architectural Principles
|
|
100
|
+
|
|
101
|
+
- **Zero-Daemon, Embedded Storage:** Runs entirely in-process using embedded C++ and Apache Arrow engines: **LadybugDB** for property graph traversals, **LanceDB** for hybrid vector/BM25 search, and **SQLite WAL** for sub-0.5ms L1 query caching. No Docker, no network databases.
|
|
102
|
+
- **Dialect-Agnostic Core:** Storage, retrieval, and MCP tools operate on abstract knowledge primitives (`Note`, `Tag`, `Folder`, `LINKS_TO`). Syntax parsing is completely encapsulated in pluggable dialects.
|
|
103
|
+
- **Model Context Protocol (MCP):** Serves as a high-precision retrieval data plane for AI agents (**Claude Code**, **Cursor**, **OpenCode**) without exposing raw filesystem mutation risks.
|
|
104
|
+
- **Scientific Quality Gating:** Retrieval accuracy is benchmarked with zero-cost IR metrics (MRR, Context Recall@5) guarding against semantic regressions.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 🛠️ Quickstart
|
|
109
|
+
|
|
110
|
+
### 1. Installation
|
|
111
|
+
Install PKMRAG into an isolated global environment using `pipx` or `uv tool`:
|
|
112
|
+
```bash
|
|
113
|
+
# Recommended for end users
|
|
114
|
+
pipx install pkmrag
|
|
115
|
+
# or
|
|
116
|
+
uv tool install pkmrag
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
For local development or cloning from source:
|
|
120
|
+
```bash
|
|
121
|
+
git clone https://github.com/dev-hashemi/project-orbit.git pkmrag
|
|
122
|
+
cd pkmrag
|
|
123
|
+
uv sync
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 2. Verify Storage & Engine Health
|
|
127
|
+
```bash
|
|
128
|
+
pkmrag doctor
|
|
129
|
+
```
|
|
130
|
+
```text
|
|
131
|
+
╭─────────────────────────────────────────────╮
|
|
132
|
+
│ PKMRAG v0.9.0 — System Health & Diagnostics │
|
|
133
|
+
╰─────────────────────────────────────────────╯
|
|
134
|
+
In-Process Data Plane Verification
|
|
135
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
136
|
+
┃ Component ┃ Status ┃ Version ┃ Latency ┃ Verification Details ┃
|
|
137
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━┩
|
|
138
|
+
│ LadybugDB Property │ PASS │ 0.20.4 │ 0.3ms │ Cypher transactional │
|
|
139
|
+
│ Graph │ │ │ │ read/write verified │
|
|
140
|
+
│ LanceDB Vector Engine │ PASS │ 0.38.0 │ 6.3ms │ Arrow-backed vector │
|
|
141
|
+
│ │ │ │ │ index verified │
|
|
142
|
+
│ Ollama Local Engine │ PASS │ active │ 1.2ms │ Local daemon detected │
|
|
143
|
+
└────────────────────────┴─────────┴─────────┴─────────┴───────────────────────┘
|
|
144
|
+
All systems operational. Engines ready for PKMRAG.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 3. Ingest and Search in 30 Seconds
|
|
148
|
+
```bash
|
|
149
|
+
pkmrag ingest /path/to/vault
|
|
150
|
+
pkmrag search "how does cache invalidation work?" --near "Cache Architecture.md"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 🔍 Core Capabilities
|
|
156
|
+
|
|
157
|
+
### Ingestion & Incremental Synchronization
|
|
158
|
+
Ingest notes, links, tags, and semantic vectors with SHA-256 delta sync:
|
|
159
|
+
```bash
|
|
160
|
+
pkmrag ingest /path/to/vault # Ingest graph topology + semantic vectors
|
|
161
|
+
pkmrag ingest /path/to/vault --target vector # Target specific plane (all, graph, or vector)
|
|
162
|
+
pkmrag ingest /path/to/docs --dialect commonmark # Explicitly select markdown dialect
|
|
163
|
+
pkmrag ingest /path/to/vault --rebuild # Force a clean rebuild
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Hybrid & Graph-Boosted Retrieval
|
|
167
|
+
Combines dense semantic similarity (`BAAI/bge-small-en-v1.5`), Tantivy BM25 keyword matching, Reciprocal Rank Fusion ($k=60$), and graph proximity multipliers:
|
|
168
|
+
```bash
|
|
169
|
+
pkmrag search "distributed consensus" # Hybrid search (dense + BM25 via RRF)
|
|
170
|
+
pkmrag search "consensus" --near "Paxos Algorithm.md" # Boosted by graph proximity to anchor note
|
|
171
|
+
pkmrag search "raft" --mode dense --limit 5 # Explicit retrieval mode (hybrid, dense, sparse)
|
|
172
|
+
pkmrag search "storage" --json # Machine-readable JSON output
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 🧠 Semantic Gap Discovery & Inferred Relationships
|
|
176
|
+
Detects unlinked note pairs with high semantic similarity ($\ge 0.80$) but graph distance $\ge 3$, classifying missing edges via local or remote LLMs:
|
|
177
|
+
```bash
|
|
178
|
+
pkmrag discover /path/to/vault --dry-run # Preview semantic gaps without calling LLM
|
|
179
|
+
pkmrag discover /path/to/vault --provider ollama # 100% offline local inference (Llama 3.2, Qwen 2.5)
|
|
180
|
+
pkmrag discover /path/to/vault --threshold 0.85 # Custom cosine similarity threshold
|
|
181
|
+
```
|
|
182
|
+
Inferred edges are stored separately in the LadybugDB `[:INFERRED_REL]` table with confidence, model name, and rationale—preserving human-curated wikilinks.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 🔌 Model Context Protocol (MCP) & HTTP Server
|
|
187
|
+
|
|
188
|
+
PKMRAG exposes a rich tool plane over **stdio** (for CLI/IDE agents) and **HTTP/SSE** (for Obsidian and network clients):
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Start stdio MCP server (Claude Code, Cursor, OpenCode)
|
|
192
|
+
pkmrag serve /path/to/vault
|
|
193
|
+
|
|
194
|
+
# Start HTTP/SSE daemon on port 3747 (dual MCP SSE + REST API plane)
|
|
195
|
+
pkmrag serve /path/to/vault --transport http --port 3747
|
|
196
|
+
|
|
197
|
+
# One-command registration for Claude Code:
|
|
198
|
+
claude mcp add pkmrag -- uv run pkmrag serve /path/to/vault
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Exposed Tools
|
|
202
|
+
- `query_vault`: Hybrid semantic + BM25 keyword retrieval with graph boost and folder/tag filters.
|
|
203
|
+
- `read_note`: Read note content enriched with graph context (tags, forward links, backlinks).
|
|
204
|
+
- `list_notes`: Browse notes in the vault with optional folder filtering and pattern matching.
|
|
205
|
+
- `list_tags` / `search_by_tag`: Rank and query notes by tag topology.
|
|
206
|
+
- `get_outline`: Extract heading hierarchy and line numbers for large notes.
|
|
207
|
+
- `get_note_context`: Inspect incoming backlinks, outgoing citations, 2-hop clusters, and AI-inferred relationships.
|
|
208
|
+
- `find_bridges`: Discover the shortest link path between two notes across the vault.
|
|
209
|
+
- `discover_gaps`: Uncover unlinked note pairs with high vector similarity for bridging.
|
|
210
|
+
- `vault_overview`: Bird's-eye view of vault notes, wikilinks, tags, and central hub notes.
|
|
211
|
+
- `reindex_note`: Targeted sub-40ms single-note incremental reindexing after external edits.
|
|
212
|
+
- `sync_vault`: Incremental delta scan updating modified notes across the vault.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 💎 Obsidian Desktop Plugin (`pkmrag`)
|
|
217
|
+
|
|
218
|
+
A native desktop companion plugin (`plugins/obsidian/`) connecting Obsidian to PKMRAG:
|
|
219
|
+
- **Interactive Setup Wizard:** If installed before the Python core engine, the sidebar automatically guides you through a 2-step setup with 1-click command copying and live verification.
|
|
220
|
+
- **Orbit Insights Sidebar:** Real-time semantic gap recommendations, contradiction warnings with LLM citations, and structural graph context.
|
|
221
|
+
- **Zero-Terminal Workflow & Auto-Daemon:** Transparently starts the background engine daemon on launch and shuts down cleanly on exit.
|
|
222
|
+
- **In-App AI Discovery & Indexing:** Trigger deep AI relationship discovery (`⚡ Discover`) and full vault rebuilds directly from Obsidian without opening a shell.
|
|
223
|
+
- **Settings-Driven LLM & Embedding Models:** Swap between Ollama, OpenAI, Groq, or local endpoints and customize models with 1-click latency verification directly inside Obsidian Settings.
|
|
224
|
+
- **CodeMirror 6 Inline Indicators:** Ambient visual widgets on headings (`🔗 N`, `⚠️`) without document clutter; clicking reveals the sidebar panel.
|
|
225
|
+
- **Proximity Concept Explorer:** Context-anchored hybrid retrieval drawer (`--near <note>`) directly within the editor with 1-click reference insertion.
|
|
226
|
+
- **Knowledge Governance:** Persistent negative feedback cache preventing dismissed links from recurring; transparent restoration drawer and global reset.
|
|
227
|
+
- **Zero-Config Token Security:** Automatically discovers `.pkmrag/server_token` (or legacy `.orbit/server_token`) from active vault.
|
|
228
|
+
- **Live Reactive Updates:** Subscribes to Server-Sent Events (`/api/v1/events`) for background indexing updates.
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Install companion plugin into your Obsidian vault:
|
|
232
|
+
pkmrag install-plugin /path/to/vault
|
|
233
|
+
|
|
234
|
+
# Or for plugin developers:
|
|
235
|
+
pkmrag install-plugin /path/to/vault --symlink
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
See [docs/subsystems/obsidian-plugin.md](docs/subsystems/obsidian-plugin.md) for installation and developer guides.
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 🎯 Benchmarks & Distributed Tracing
|
|
244
|
+
|
|
245
|
+
### Information Retrieval Quality Gates
|
|
246
|
+
Evaluated against the in-repo Golden 10 ground truth benchmark dataset (`benchmarks/golden_10.json`):
|
|
247
|
+
- **MRR (Mean Reciprocal Rank):** `0.950` (Target $\ge 0.80$, PASS)
|
|
248
|
+
- **Context Recall@5:** `0.950` (Target $\ge 0.80$, PASS)
|
|
249
|
+
- **Hits@1:** `90.0%` | **Hits@3:** `100.0%` | **Hits@5:** `100.0%`
|
|
250
|
+
- **Mean Average Precision (MAP@5):** `0.925`
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
pkmrag eval --min-mrr 0.85 --min-recall 0.80 # CI regression gate
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### OpenTelemetry Distributed Tracing
|
|
257
|
+
Inspect execution timelines and token consumption in real time with in-memory OpenTelemetry spans:
|
|
258
|
+
```bash
|
|
259
|
+
pkmrag search "storage" --near "LadybugDB.md" --trace
|
|
260
|
+
```
|
|
261
|
+
```text
|
|
262
|
+
╭───────── Trace ID: 66d44d13f5b480b5... ─────────╮
|
|
263
|
+
│ 🛰️ Trace: pkmrag.search 18.42ms (HIT, hybrid) │
|
|
264
|
+
│ ├── cache.lookup 0.15ms (HIT) │
|
|
265
|
+
│ ├── lancedb.search 8.12ms │
|
|
266
|
+
│ ├── ladybug.hops 4.20ms (dist: 1) │
|
|
267
|
+
│ └── rrf.fuse 0.18ms │
|
|
268
|
+
╰─────────────────────────────────────────────────╯
|
|
269
|
+
```
|
|
270
|
+
- **Zero Daemons Required:** Spans are collected in-memory and rendered locally.
|
|
271
|
+
- **LLM Token Auditing:** Tracks prompt and completion tokens per inference call.
|
|
272
|
+
- **Remote OTLP Exporter:** Optional live trace streaming to Langfuse, Jaeger, or Datadog via `.env`.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 🧪 Development & Quality Gates
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Unit & integration tests + Golden 10 benchmark
|
|
280
|
+
uv run pytest
|
|
281
|
+
|
|
282
|
+
# Strict type checking
|
|
283
|
+
uv run mypy src tests
|
|
284
|
+
|
|
285
|
+
# Linting & code formatting
|
|
286
|
+
uv run ruff check . && uv run ruff format --check .
|
|
287
|
+
|
|
288
|
+
# Retrieval evaluation against benchmark
|
|
289
|
+
uv run pkmrag eval
|
|
290
|
+
```
|