minder-cli 0.3.3__tar.gz → 0.3.6__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.
- {minder_cli-0.3.3 → minder_cli-0.3.6}/.gitignore +2 -1
- {minder_cli-0.3.3 → minder_cli-0.3.6}/PKG-INFO +42 -43
- minder_cli-0.3.6/README-pypi.md +80 -0
- minder_cli-0.3.6/README.md +96 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/pyproject.toml +5 -2
- minder_cli-0.3.6/src/minder/cli.py +7 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/config.py +11 -8
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/continuity.py +6 -10
- minder_cli-0.3.6/src/minder/embedding/local.py +184 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/graph.py +4 -8
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/state.py +1 -0
- minder_cli-0.3.6/src/minder/llm/__init__.py +11 -0
- minder_cli-0.3.6/src/minder/llm/factory.py +38 -0
- minder_cli-0.3.6/src/minder/llm/litert.py +324 -0
- minder_cli-0.3.6/src/minder/presentation/cli/__init__.py +3 -0
- minder_cli-0.3.6/src/minder/presentation/cli/commands/auth.py +58 -0
- minder_cli-0.3.6/src/minder/presentation/cli/commands/ide.py +146 -0
- minder_cli-0.3.6/src/minder/presentation/cli/commands/mcp.py +158 -0
- minder_cli-0.3.6/src/minder/presentation/cli/commands/sync.py +97 -0
- minder_cli-0.3.6/src/minder/presentation/cli/commands/update.py +221 -0
- minder_cli-0.3.6/src/minder/presentation/cli/main.py +107 -0
- minder_cli-0.3.6/src/minder/presentation/cli/utils/common.py +140 -0
- minder_cli-0.3.6/src/minder/presentation/cli/utils/config.py +61 -0
- minder_cli-0.3.6/src/minder/presentation/cli/utils/git.py +287 -0
- minder_cli-0.3.6/src/minder/presentation/cli/utils/version.py +70 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/context.py +9 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/memories.py +9 -3
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/search.py +104 -127
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/skills.py +7 -1
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/prompts/formatter.py +5 -9
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/server.py +5 -12
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/memory.py +18 -3
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/query.py +37 -5
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/skills.py +20 -3
- minder_cli-0.3.3/README.md +0 -83
- minder_cli-0.3.3/src/minder/cli.py +0 -1676
- minder_cli-0.3.3/src/minder/embedding/local.py +0 -76
- minder_cli-0.3.3/src/minder/llm/__init__.py +0 -5
- minder_cli-0.3.3/src/minder/llm/local.py +0 -240
- {minder_cli-0.3.3 → minder_cli-0.3.6}/LICENSE +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/api/routers/prompts.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/application/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/application/admin/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/application/admin/dto.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/application/admin/jobs.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/application/admin/use_cases.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/context.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/middleware.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/principal.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/rate_limiter.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/rbac.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/auth/service.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/bootstrap/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/bootstrap/providers.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/bootstrap/transport.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/cache/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/cache/providers.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/chunking/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/chunking/code_splitter.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/chunking/splitter.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/dev.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/embedding/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/embedding/base.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/embedding/openai.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/edges.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/executor.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/evaluator.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/guard.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/llm.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/planning.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/reasoning.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/reranker.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/retriever.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/verification.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/nodes/workflow_planner.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/graph/runtime.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/llm/base.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/llm/openai.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/base.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/client.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/document.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/error.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/graph.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/history.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/job.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/prompt.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/repository.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/rule.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/session.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/skill.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/user.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/models/workflow.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/observability/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/observability/audit.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/observability/logging.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/observability/metrics.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/observability/tracing.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/api.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/dashboard.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/jobs.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/prompts.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/routes.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/presentation/http/admin/runtime.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/prompts/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/resources/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/retrieval/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/retrieval/hybrid.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/retrieval/mmr.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/retrieval/multi_hop.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/runtime.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/document.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/error.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/feedback.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/graph.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/history.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/interfaces.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/milvus/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/milvus/client.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/milvus/collections.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/milvus/vector_store.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/mongodb/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/mongodb/client.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/mongodb/indexes.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/mongodb/operational_store.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/relational.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/repo_state.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/rule.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/store/vector.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/auth.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/graph.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/ingest.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/registry.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/repo_scanner.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/search.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/session.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/tools/workflow.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/transport/__init__.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/transport/base.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/transport/sse.py +0 -0
- {minder_cli-0.3.3 → minder_cli-0.3.6}/src/minder/transport/stdio.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: minder-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: Minder CLI is the command-line interface for the Minder self-hosted MCP platform.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hiimtrung/minder
|
|
6
6
|
Project-URL: Repository, https://github.com/hiimtrung/minder
|
|
@@ -19,8 +19,10 @@ Requires-Dist: fastapi>=0.136.0
|
|
|
19
19
|
Requires-Dist: httpx>=0.28.0
|
|
20
20
|
Provides-Extra: server
|
|
21
21
|
Requires-Dist: aiosqlite>=0.21.0; extra == 'server'
|
|
22
|
+
Requires-Dist: fastembed>=0.5.1; extra == 'server'
|
|
22
23
|
Requires-Dist: langgraph>=1.1.8; extra == 'server'
|
|
23
24
|
Requires-Dist: litellm>=1.83.1; extra == 'server'
|
|
25
|
+
Requires-Dist: litert-lm-api-nightly>=0.10; extra == 'server'
|
|
24
26
|
Requires-Dist: mcp>=1.26.0; extra == 'server'
|
|
25
27
|
Requires-Dist: motor>=3.7.0; extra == 'server'
|
|
26
28
|
Requires-Dist: passlib[bcrypt]>=1.7.4; extra == 'server'
|
|
@@ -35,86 +37,83 @@ Requires-Dist: zipp>=3.21.0; extra == 'server'
|
|
|
35
37
|
Requires-Dist: zstandard>=0.25.0; extra == 'server'
|
|
36
38
|
Description-Content-Type: text/markdown
|
|
37
39
|
|
|
38
|
-
#
|
|
40
|
+
# minder-cli
|
|
39
41
|
|
|
40
42
|
[](https://pypi.org/project/minder-cli/)
|
|
41
43
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
42
44
|
|
|
43
|
-
**
|
|
45
|
+
**minder-cli** is the command-line interface for [Minder](https://github.com/hiimtrung/minder) — a self-hosted MCP platform for repository-aware engineering intelligence.
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- **IDE Integration**: Scaffold repository-local MCP assets for VS Code, Cursor, and Claude Code.
|
|
48
|
-
- **Repository Sync**: Auto-detect cross-repo dependencies and synchronize project knowledge.
|
|
49
|
-
- **Self-Management**: Check for updates and upgrade both CLI and Server components in place.
|
|
50
|
-
- **Unified Auth**: Simple login flow to connect your local development environment to your Minder Server.
|
|
47
|
+
The CLI handles IDE scaffolding, repository sync, authentication, and self-updates. It connects to a **Minder Server** which runs the MCP gateway, RAG pipeline, memory engine, and admin console.
|
|
51
48
|
|
|
52
49
|
## Installation
|
|
53
50
|
|
|
54
|
-
Install the CLI from PyPI using `uv` (recommended) or `pipx`:
|
|
55
|
-
|
|
56
51
|
```bash
|
|
52
|
+
# Recommended
|
|
57
53
|
uv tool install minder-cli
|
|
58
|
-
|
|
54
|
+
|
|
55
|
+
# Alternative
|
|
59
56
|
pipx install minder-cli
|
|
60
57
|
```
|
|
61
58
|
|
|
62
|
-
##
|
|
59
|
+
## Requirements
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
A running [Minder Server](https://github.com/hiimtrung/minder) — see the [server setup guide](https://github.com/hiimtrung/minder/blob/main/docs/minder-server.md) to get one running in minutes with Docker.
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
### 1. Connect to your server
|
|
67
66
|
|
|
68
67
|
```bash
|
|
69
68
|
minder login --client-key mkc_your_client_key --server-url http://localhost:8800/sse
|
|
70
69
|
```
|
|
71
70
|
|
|
72
|
-
### 2.
|
|
73
|
-
|
|
74
|
-
Set up MCP tools and instructions for your favorite editor:
|
|
71
|
+
### 2. Set up IDE integration
|
|
75
72
|
|
|
76
73
|
```bash
|
|
77
|
-
# In your project root
|
|
74
|
+
# In your project root — scaffolds MCP config for your editor
|
|
78
75
|
minder install-ide --target vscode --target claude-code
|
|
79
76
|
```
|
|
80
77
|
|
|
81
|
-
|
|
78
|
+
Supported targets: `vscode`, `cursor`, `claude-code`.
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
### 3. Sync a repository
|
|
84
81
|
|
|
85
82
|
```bash
|
|
86
83
|
minder sync --repo-id <repository-uuid>
|
|
87
84
|
```
|
|
88
85
|
|
|
89
|
-
|
|
86
|
+
Indexes code and documentation so AI agents can use semantic search and RAG tools.
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
## Commands
|
|
92
89
|
|
|
93
|
-
|
|
|
94
|
-
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
90
|
+
| Command | Description |
|
|
91
|
+
|---------|-------------|
|
|
92
|
+
| `minder login` | Authenticate the CLI against a Minder Server |
|
|
93
|
+
| `minder install-ide` | Scaffold MCP assets for VS Code / Cursor / Claude Code |
|
|
94
|
+
| `minder sync` | Index a repository into the Minder Server |
|
|
95
|
+
| `minder check-update` | Check for available CLI and server updates |
|
|
96
|
+
| `minder self-update` | Update CLI or server in place |
|
|
99
97
|
|
|
100
|
-
##
|
|
98
|
+
## MCP Tools (once connected)
|
|
101
99
|
|
|
102
|
-
|
|
100
|
+
Your AI agents will have access to:
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
| Tool | Description |
|
|
103
|
+
|------|-------------|
|
|
104
|
+
| `minder_query` | Full RAG pipeline: retrieve → reason → verify → respond |
|
|
105
|
+
| `minder_search_code` | Semantic code search across indexed repositories |
|
|
106
|
+
| `minder_memory_recall` | Retrieve persisted engineering memory |
|
|
107
|
+
| `minder_workflow_get` | Read current workflow state |
|
|
108
|
+
| `minder_session_restore` | Restore session continuity across context windows |
|
|
109
109
|
|
|
110
|
-
##
|
|
110
|
+
## Links
|
|
111
111
|
|
|
112
|
-
- [
|
|
113
|
-
- [
|
|
114
|
-
- [
|
|
115
|
-
- [
|
|
116
|
-
- [System Architecture](docs/system-design.md)
|
|
112
|
+
- [GitHub Repository](https://github.com/hiimtrung/minder)
|
|
113
|
+
- [Server Setup Guide](https://github.com/hiimtrung/minder/blob/main/docs/minder-server.md)
|
|
114
|
+
- [Local Dev Setup](https://github.com/hiimtrung/minder/blob/main/docs/guides/local-setup.md)
|
|
115
|
+
- [System Design](https://github.com/hiimtrung/minder/blob/main/docs/system-design.md)
|
|
117
116
|
|
|
118
117
|
## License
|
|
119
118
|
|
|
120
|
-
Apache License 2.0. See [LICENSE](LICENSE) for details.
|
|
119
|
+
Apache License 2.0. See [LICENSE](https://github.com/hiimtrung/minder/blob/main/LICENSE) for details.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# minder-cli
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/minder-cli/)
|
|
4
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
|
|
6
|
+
**minder-cli** is the command-line interface for [Minder](https://github.com/hiimtrung/minder) — a self-hosted MCP platform for repository-aware engineering intelligence.
|
|
7
|
+
|
|
8
|
+
The CLI handles IDE scaffolding, repository sync, authentication, and self-updates. It connects to a **Minder Server** which runs the MCP gateway, RAG pipeline, memory engine, and admin console.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Recommended
|
|
14
|
+
uv tool install minder-cli
|
|
15
|
+
|
|
16
|
+
# Alternative
|
|
17
|
+
pipx install minder-cli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
A running [Minder Server](https://github.com/hiimtrung/minder) — see the [server setup guide](https://github.com/hiimtrung/minder/blob/main/docs/minder-server.md) to get one running in minutes with Docker.
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### 1. Connect to your server
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
minder login --client-key mkc_your_client_key --server-url http://localhost:8800/sse
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Set up IDE integration
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# In your project root — scaffolds MCP config for your editor
|
|
36
|
+
minder install-ide --target vscode --target claude-code
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Supported targets: `vscode`, `cursor`, `claude-code`.
|
|
40
|
+
|
|
41
|
+
### 3. Sync a repository
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
minder sync --repo-id <repository-uuid>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Indexes code and documentation so AI agents can use semantic search and RAG tools.
|
|
48
|
+
|
|
49
|
+
## Commands
|
|
50
|
+
|
|
51
|
+
| Command | Description |
|
|
52
|
+
|---------|-------------|
|
|
53
|
+
| `minder login` | Authenticate the CLI against a Minder Server |
|
|
54
|
+
| `minder install-ide` | Scaffold MCP assets for VS Code / Cursor / Claude Code |
|
|
55
|
+
| `minder sync` | Index a repository into the Minder Server |
|
|
56
|
+
| `minder check-update` | Check for available CLI and server updates |
|
|
57
|
+
| `minder self-update` | Update CLI or server in place |
|
|
58
|
+
|
|
59
|
+
## MCP Tools (once connected)
|
|
60
|
+
|
|
61
|
+
Your AI agents will have access to:
|
|
62
|
+
|
|
63
|
+
| Tool | Description |
|
|
64
|
+
|------|-------------|
|
|
65
|
+
| `minder_query` | Full RAG pipeline: retrieve → reason → verify → respond |
|
|
66
|
+
| `minder_search_code` | Semantic code search across indexed repositories |
|
|
67
|
+
| `minder_memory_recall` | Retrieve persisted engineering memory |
|
|
68
|
+
| `minder_workflow_get` | Read current workflow state |
|
|
69
|
+
| `minder_session_restore` | Restore session continuity across context windows |
|
|
70
|
+
|
|
71
|
+
## Links
|
|
72
|
+
|
|
73
|
+
- [GitHub Repository](https://github.com/hiimtrung/minder)
|
|
74
|
+
- [Server Setup Guide](https://github.com/hiimtrung/minder/blob/main/docs/minder-server.md)
|
|
75
|
+
- [Local Dev Setup](https://github.com/hiimtrung/minder/blob/main/docs/guides/local-setup.md)
|
|
76
|
+
- [System Design](https://github.com/hiimtrung/minder/blob/main/docs/system-design.md)
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
Apache License 2.0. See [LICENSE](https://github.com/hiimtrung/minder/blob/main/LICENSE) for details.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Minder
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/minder-cli/)
|
|
4
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
|
|
6
|
+
**Minder** is a self-hosted MCP (Model Context Protocol) platform for repository-aware engineering intelligence.
|
|
7
|
+
|
|
8
|
+
It combines a local-first inference stack, a persistent memory and workflow engine, and a developer-facing CLI into a single deployable unit.
|
|
9
|
+
|
|
10
|
+
## What's in this repo
|
|
11
|
+
|
|
12
|
+
| Component | Description |
|
|
13
|
+
|-----------|-------------|
|
|
14
|
+
| **Minder Server** | MCP gateway — SSE + stdio transport, RAG pipeline, workflow engine, memory, admin HTTP |
|
|
15
|
+
| **Minder CLI** (`minder-cli` on PyPI) | Edge CLI — IDE scaffold, repo sync, login, self-update |
|
|
16
|
+
| **Minder Dashboard** | Astro admin console — client management, onboarding, skill catalog |
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Developer → minder-cli → Minder Server ←→ AI agents (Codex / Copilot / Claude)
|
|
22
|
+
│
|
|
23
|
+
┌──────────────┼──────────────┐
|
|
24
|
+
│ │ │
|
|
25
|
+
MongoDB Redis Milvus
|
|
26
|
+
(graph/memory) (cache) (vector search)
|
|
27
|
+
│
|
|
28
|
+
┌─────┴──────┐
|
|
29
|
+
│ │
|
|
30
|
+
LiteRT-LM FastEmbed
|
|
31
|
+
(LLM gen) (embedding)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **LLM inference**: LiteRT-LM (Google AI Edge) — on-device, hardware-accelerated, no HTTP overhead
|
|
35
|
+
- **Embedding inference**: FastEmbed running natively in-process (`mxbai-embed-large-v1`) — zero-dependency ONNX acceleration
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Run the server
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 1. Download the LiteRT-LM model
|
|
43
|
+
./scripts/download_models.sh
|
|
44
|
+
|
|
45
|
+
# 2. Start infra (MongoDB + Redis + Milvus)
|
|
46
|
+
docker compose -f docker/docker-compose.local.yml up -d
|
|
47
|
+
|
|
48
|
+
# 3. Run Minder Server
|
|
49
|
+
uv run python -m minder.server
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or use the one-command release installer (Docker only, no local uv needed):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -fsSL https://raw.githubusercontent.com/hiimtrung/minder/main/scripts/release/install-minder-release.sh | bash
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Connect the CLI
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Install
|
|
62
|
+
uv tool install minder-cli
|
|
63
|
+
|
|
64
|
+
# Log in with your client key
|
|
65
|
+
minder login --client-key mkc_your_key --server-url http://localhost:8800/sse
|
|
66
|
+
|
|
67
|
+
# Set up IDE integration (VS Code, Cursor, Claude Code)
|
|
68
|
+
minder install-ide --target vscode --target claude-code
|
|
69
|
+
|
|
70
|
+
# Sync a repository
|
|
71
|
+
minder sync --repo-id <uuid>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## MCP Tools
|
|
75
|
+
|
|
76
|
+
When connected, Minder exposes these tools to your AI agents:
|
|
77
|
+
|
|
78
|
+
| Tool | Description |
|
|
79
|
+
|------|-------------|
|
|
80
|
+
| `minder_query` | Full RAG pipeline: retrieve → reason → verify → respond |
|
|
81
|
+
| `minder_search_code` | Semantic code search across indexed repos |
|
|
82
|
+
| `minder_memory_recall` | Retrieve persisted engineering memory |
|
|
83
|
+
| `minder_workflow_get` | Read current workflow state |
|
|
84
|
+
| `minder_session_restore` | Restore session continuity across context windows |
|
|
85
|
+
|
|
86
|
+
## Documentation
|
|
87
|
+
|
|
88
|
+
- [System Design](docs/system-design.md)
|
|
89
|
+
- [Server Setup](docs/minder-server.md)
|
|
90
|
+
- [Local Dev Setup](docs/guides/local-setup.md)
|
|
91
|
+
- [Production Deployment](docs/guides/production-deployment.md)
|
|
92
|
+
- [Admin & Client Onboarding](docs/guides/admin-client-onboarding.md)
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
Apache License 2.0. See [LICENSE](LICENSE) for details.
|
|
@@ -4,9 +4,9 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "minder-cli"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.6"
|
|
8
8
|
description = "Minder CLI is the command-line interface for the Minder self-hosted MCP platform."
|
|
9
|
-
readme = "README.md"
|
|
9
|
+
readme = "README-pypi.md"
|
|
10
10
|
requires-python = ">=3.14"
|
|
11
11
|
keywords = ["mcp", "cli", "ai", "code-search", "workflow"]
|
|
12
12
|
classifiers = [
|
|
@@ -26,8 +26,10 @@ dependencies = [
|
|
|
26
26
|
[project.optional-dependencies]
|
|
27
27
|
server = [
|
|
28
28
|
"aiosqlite>=0.21.0",
|
|
29
|
+
"fastembed>=0.5.1",
|
|
29
30
|
"langgraph>=1.1.8",
|
|
30
31
|
"litellm>=1.83.1",
|
|
32
|
+
"litert-lm-api-nightly>=0.10",
|
|
31
33
|
"mcp>=1.26.0",
|
|
32
34
|
"motor>=3.7.0",
|
|
33
35
|
"passlib[bcrypt]>=1.7.4",
|
|
@@ -67,6 +69,7 @@ packages = ["src/minder"]
|
|
|
67
69
|
[tool.hatch.build.targets.sdist]
|
|
68
70
|
include = [
|
|
69
71
|
"/README.md",
|
|
72
|
+
"/README-pypi.md",
|
|
70
73
|
"/pyproject.toml",
|
|
71
74
|
"/src/minder",
|
|
72
75
|
]
|
|
@@ -31,19 +31,22 @@ class AuthConfig(BaseModel):
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class EmbeddingConfig(BaseModel):
|
|
34
|
-
provider: str = "
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
provider: str = "fastembed"
|
|
35
|
+
runtime: str = "auto" # "auto" | "fastembed" | "mock"
|
|
36
|
+
fastembed_model: str = "mixedbread-ai/mxbai-embed-large-v1"
|
|
37
|
+
fastembed_cache_dir: str = "~/.minder/cache/fastembed"
|
|
38
|
+
dimensions: int = 1024
|
|
38
39
|
openai_api_key: Optional[str] = None
|
|
39
40
|
openai_model: str = "text-embedding-3-small"
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
class LLMConfig(BaseModel):
|
|
43
|
-
provider: str = "
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
provider: str = "litert" # "litert" | "openai"
|
|
45
|
+
# LiteRT-LM fields
|
|
46
|
+
litert_model_path: str = "~/.minder/models/gemma-4-E2B-it.litertlm"
|
|
47
|
+
litert_backend: str = "auto" # "auto" (GPU on Mac, CPU elsewhere) | "cpu" | "gpu"
|
|
48
|
+
litert_cache_dir: str = "~/.minder/cache/litert"
|
|
49
|
+
context_length: int = 32768
|
|
47
50
|
temperature: float = 0.1
|
|
48
51
|
openai_api_key: Optional[str] = None
|
|
49
52
|
openai_model: str = "gpt-4o-mini"
|
|
@@ -268,14 +268,10 @@ def _extract_json_object(raw: str) -> dict[str, Any] | None:
|
|
|
268
268
|
|
|
269
269
|
class ContinuitySynthesizer:
|
|
270
270
|
def __init__(self, config: MinderConfig) -> None:
|
|
271
|
-
from minder.llm.
|
|
271
|
+
from minder.llm.factory import create_llm
|
|
272
272
|
|
|
273
273
|
self._config = config
|
|
274
|
-
self._llm =
|
|
275
|
-
ollama_url=config.llm.ollama_url,
|
|
276
|
-
ollama_model=config.llm.ollama_model,
|
|
277
|
-
context_length=config.llm.context_length,
|
|
278
|
-
)
|
|
274
|
+
self._llm = create_llm(config.llm)
|
|
279
275
|
|
|
280
276
|
def synthesize_memory_hits(
|
|
281
277
|
self,
|
|
@@ -304,7 +300,7 @@ class ContinuitySynthesizer:
|
|
|
304
300
|
)
|
|
305
301
|
raw = self._llm.complete_text(
|
|
306
302
|
prompt,
|
|
307
|
-
max_tokens=
|
|
303
|
+
max_tokens=1000,
|
|
308
304
|
temperature=min(max(self._config.llm.temperature, 0.05), 0.3),
|
|
309
305
|
fallback="",
|
|
310
306
|
)
|
|
@@ -312,7 +308,7 @@ class ContinuitySynthesizer:
|
|
|
312
308
|
if not parsed:
|
|
313
309
|
return fallback, {
|
|
314
310
|
"provider": "heuristic",
|
|
315
|
-
"model": self._config.llm.
|
|
311
|
+
"model": self._config.llm.provider,
|
|
316
312
|
"runtime": self._llm.runtime,
|
|
317
313
|
}
|
|
318
314
|
return {
|
|
@@ -329,8 +325,8 @@ class ContinuitySynthesizer:
|
|
|
329
325
|
).items()
|
|
330
326
|
},
|
|
331
327
|
}, {
|
|
332
|
-
"provider": "
|
|
333
|
-
"model": self._config.llm.
|
|
328
|
+
"provider": "litert_lm",
|
|
329
|
+
"model": self._config.llm.provider,
|
|
334
330
|
"runtime": self._llm.runtime,
|
|
335
331
|
}
|
|
336
332
|
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Local Embedding provider — delegates to FastEmbed using ONNX runtime.
|
|
3
|
+
|
|
4
|
+
Falls back to a deterministic hash-based stub if initialization fails.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import gc
|
|
10
|
+
import hashlib
|
|
11
|
+
import logging
|
|
12
|
+
import math
|
|
13
|
+
from collections import OrderedDict
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
_MODEL_CACHE: dict[str, Any] = {}
|
|
21
|
+
_EMBEDDING_CACHE: OrderedDict[str, list[float]] = OrderedDict()
|
|
22
|
+
MAX_CACHE_SIZE = 100
|
|
23
|
+
MAX_TEXT_LENGTH = 8000 # Safety truncation to avoid over-context (~2000 tokens)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class LocalEmbeddingProvider:
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
fastembed_model: str = "mixedbread-ai/mxbai-embed-large-v1",
|
|
30
|
+
fastembed_cache_dir: str = "~/.minder/cache/fastembed",
|
|
31
|
+
dimensions: int = 1024,
|
|
32
|
+
runtime: str = "auto",
|
|
33
|
+
) -> None:
|
|
34
|
+
self._model_name = fastembed_model
|
|
35
|
+
self._cache_dir = str(Path(fastembed_cache_dir).expanduser())
|
|
36
|
+
self._dimensions = dimensions
|
|
37
|
+
self._runtime = runtime
|
|
38
|
+
self._model: Any | None = None
|
|
39
|
+
self._init_model()
|
|
40
|
+
|
|
41
|
+
def _init_model(self) -> None:
|
|
42
|
+
if self._runtime == "mock":
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
cache_key = f"{self._model_name}:{self._cache_dir}"
|
|
46
|
+
if cache_key in _MODEL_CACHE:
|
|
47
|
+
self._model = _MODEL_CACHE[cache_key]
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
from fastembed import TextEmbedding # type: ignore[import-not-found]
|
|
52
|
+
|
|
53
|
+
# Optimize for speed and resource usage:
|
|
54
|
+
# - threads=4 limits CPU usage while maintaining good throughput
|
|
55
|
+
# - lazy_load=False ensures first request is fast
|
|
56
|
+
self._model = TextEmbedding(
|
|
57
|
+
model_name=self._model_name,
|
|
58
|
+
cache_dir=self._cache_dir,
|
|
59
|
+
threads=4,
|
|
60
|
+
)
|
|
61
|
+
_MODEL_CACHE[cache_key] = self._model
|
|
62
|
+
except Exception as e:
|
|
63
|
+
logger.warning(
|
|
64
|
+
f"Failed to initialize FastEmbed model {self._model_name}: {e}. Using mock."
|
|
65
|
+
)
|
|
66
|
+
self._model = None
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def runtime(self) -> str:
|
|
70
|
+
if self._runtime != "auto":
|
|
71
|
+
return self._runtime
|
|
72
|
+
return "fastembed" if self._model is not None else "mock"
|
|
73
|
+
|
|
74
|
+
def embed(self, text: str) -> list[float]:
|
|
75
|
+
if not text:
|
|
76
|
+
return [0.0] * self._dimensions
|
|
77
|
+
|
|
78
|
+
# 1. Truncate to avoid over-context errors
|
|
79
|
+
safe_text = text[:MAX_TEXT_LENGTH]
|
|
80
|
+
|
|
81
|
+
# 2. Check cache
|
|
82
|
+
if safe_text in _EMBEDDING_CACHE:
|
|
83
|
+
_EMBEDDING_CACHE.move_to_end(safe_text)
|
|
84
|
+
return _EMBEDDING_CACHE[safe_text]
|
|
85
|
+
|
|
86
|
+
# 3. Perform embedding
|
|
87
|
+
embedding: list[float]
|
|
88
|
+
if self.runtime == "fastembed" and self._model is not None:
|
|
89
|
+
try:
|
|
90
|
+
# FastEmbed returns a generator of numpy arrays
|
|
91
|
+
embeddings = list(self._model.embed([safe_text]))
|
|
92
|
+
if embeddings:
|
|
93
|
+
embedding = embeddings[0].tolist()[: self._dimensions]
|
|
94
|
+
else:
|
|
95
|
+
embedding = self._hash_embed(safe_text)
|
|
96
|
+
except Exception as e:
|
|
97
|
+
logger.warning(f"FastEmbed failed during inference: {e}")
|
|
98
|
+
embedding = self._hash_embed(safe_text)
|
|
99
|
+
else:
|
|
100
|
+
embedding = self._hash_embed(safe_text)
|
|
101
|
+
|
|
102
|
+
# 4. Update cache (LRU)
|
|
103
|
+
_EMBEDDING_CACHE[safe_text] = embedding
|
|
104
|
+
if len(_EMBEDDING_CACHE) > MAX_CACHE_SIZE:
|
|
105
|
+
_EMBEDDING_CACHE.popitem(last=False)
|
|
106
|
+
|
|
107
|
+
return embedding
|
|
108
|
+
|
|
109
|
+
def embed_many(self, texts: list[str]) -> list[list[float]]:
|
|
110
|
+
if not texts:
|
|
111
|
+
return []
|
|
112
|
+
|
|
113
|
+
results: list[list[float]] = [[] for _ in texts]
|
|
114
|
+
to_embed_indices: list[int] = []
|
|
115
|
+
to_embed_texts: list[str] = []
|
|
116
|
+
|
|
117
|
+
# 1. Try cache first
|
|
118
|
+
for i, text in enumerate(texts):
|
|
119
|
+
safe_text = text[:MAX_TEXT_LENGTH] if text else ""
|
|
120
|
+
if not safe_text:
|
|
121
|
+
results[i] = [0.0] * self._dimensions
|
|
122
|
+
elif safe_text in _EMBEDDING_CACHE:
|
|
123
|
+
_EMBEDDING_CACHE.move_to_end(safe_text)
|
|
124
|
+
results[i] = _EMBEDDING_CACHE[safe_text]
|
|
125
|
+
else:
|
|
126
|
+
to_embed_indices.append(i)
|
|
127
|
+
to_embed_texts.append(safe_text)
|
|
128
|
+
|
|
129
|
+
if not to_embed_texts:
|
|
130
|
+
return results
|
|
131
|
+
|
|
132
|
+
# 2. Batch embed the missing ones
|
|
133
|
+
if self.runtime == "fastembed" and self._model is not None:
|
|
134
|
+
try:
|
|
135
|
+
embeddings = list(self._model.embed(to_embed_texts))
|
|
136
|
+
for i, emb in enumerate(embeddings):
|
|
137
|
+
idx = to_embed_indices[i]
|
|
138
|
+
vector = emb.tolist()[: self._dimensions]
|
|
139
|
+
results[idx] = vector
|
|
140
|
+
# Update cache
|
|
141
|
+
_EMBEDDING_CACHE[to_embed_texts[i]] = vector
|
|
142
|
+
except Exception as e:
|
|
143
|
+
logger.warning(f"FastEmbed batch failed: {e}")
|
|
144
|
+
for i, idx in enumerate(to_embed_indices):
|
|
145
|
+
vector = self._hash_embed(to_embed_texts[i])
|
|
146
|
+
results[idx] = vector
|
|
147
|
+
_EMBEDDING_CACHE[to_embed_texts[i]] = vector
|
|
148
|
+
else:
|
|
149
|
+
for i, idx in enumerate(to_embed_indices):
|
|
150
|
+
vector = self._hash_embed(to_embed_texts[i])
|
|
151
|
+
results[idx] = vector
|
|
152
|
+
_EMBEDDING_CACHE[to_embed_texts[i]] = vector
|
|
153
|
+
|
|
154
|
+
# 3. Cache maintenance
|
|
155
|
+
while len(_EMBEDDING_CACHE) > MAX_CACHE_SIZE:
|
|
156
|
+
_EMBEDDING_CACHE.popitem(last=False)
|
|
157
|
+
|
|
158
|
+
return results
|
|
159
|
+
|
|
160
|
+
def _hash_embed(self, text: str) -> list[float]:
|
|
161
|
+
"""Generate a deterministic but word-aware mock embedding."""
|
|
162
|
+
words = text.lower().split()
|
|
163
|
+
if not words:
|
|
164
|
+
return [0.0] * self._dimensions
|
|
165
|
+
|
|
166
|
+
vector = [0.0] * self._dimensions
|
|
167
|
+
for word in words:
|
|
168
|
+
h = hashlib.sha256(word.encode()).digest()
|
|
169
|
+
for i in range(self._dimensions):
|
|
170
|
+
byte_val = h[i % len(h)]
|
|
171
|
+
vector[i] += (byte_val / 255.0) - 0.5
|
|
172
|
+
|
|
173
|
+
norm = math.sqrt(sum(v * v for v in vector))
|
|
174
|
+
if norm > 1e-9:
|
|
175
|
+
return [v / norm for v in vector]
|
|
176
|
+
return [0.0] * self._dimensions
|
|
177
|
+
|
|
178
|
+
def clear_caches() -> None:
|
|
179
|
+
"""Clear global model and embedding caches to reclaim memory."""
|
|
180
|
+
global _MODEL_CACHE, _EMBEDDING_CACHE
|
|
181
|
+
_MODEL_CACHE.clear()
|
|
182
|
+
_EMBEDDING_CACHE.clear()
|
|
183
|
+
gc.collect()
|
|
184
|
+
logger.debug("Cleared FastEmbed global caches.")
|
|
@@ -23,7 +23,7 @@ from minder.graph.nodes import (
|
|
|
23
23
|
WorkflowPlannerNode,
|
|
24
24
|
)
|
|
25
25
|
from minder.graph.state import GraphState
|
|
26
|
-
from minder.llm.
|
|
26
|
+
from minder.llm.factory import create_llm
|
|
27
27
|
from minder.llm.openai import OpenAIFallbackLLM
|
|
28
28
|
from minder.store.interfaces import (
|
|
29
29
|
IOperationalStore,
|
|
@@ -58,8 +58,8 @@ class MinderGraph:
|
|
|
58
58
|
self._planning = planning or PlanningNode()
|
|
59
59
|
vector_store = VectorStore(store, store)
|
|
60
60
|
embedder = LocalEmbeddingProvider(
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
fastembed_model=config.embedding.fastembed_model,
|
|
62
|
+
fastembed_cache_dir=config.embedding.fastembed_cache_dir,
|
|
63
63
|
dimensions=config.embedding.dimensions,
|
|
64
64
|
runtime="auto",
|
|
65
65
|
)
|
|
@@ -72,11 +72,7 @@ class MinderGraph:
|
|
|
72
72
|
self._reranker = reranker # None by default; pass RerankerNode(...) to activate
|
|
73
73
|
self._reasoning = reasoning or ReasoningNode()
|
|
74
74
|
self._llm = llm or LLMNode(
|
|
75
|
-
primary=
|
|
76
|
-
ollama_url=config.llm.ollama_url,
|
|
77
|
-
ollama_model=config.llm.ollama_model,
|
|
78
|
-
context_length=config.llm.context_length,
|
|
79
|
-
),
|
|
75
|
+
primary=create_llm(config.llm),
|
|
80
76
|
fallback=OpenAIFallbackLLM(
|
|
81
77
|
config.llm.openai_api_key,
|
|
82
78
|
config.llm.openai_model,
|