minder-cli 0.5.6__tar.gz → 0.5.8__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.5.6 → minder_cli-0.5.8}/PKG-INFO +2 -4
- {minder_cli-0.5.6 → minder_cli-0.5.8}/pyproject.toml +2 -5
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/jobs.py +5 -4
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/use_cases.py +13 -39
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/providers.py +46 -55
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/transport.py +18 -3
- minder_cli-0.5.8/src/minder/bootstrap/workflow_seeder.py +64 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/cache/__init__.py +1 -2
- minder_cli-0.5.8/src/minder/cache/providers.py +61 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/config.py +33 -25
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/local.py +6 -1
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/__init__.py +2 -2
- minder_cli-0.5.8/src/minder/graph/checkpoint.py +162 -0
- minder_cli-0.5.8/src/minder/graph/executor.py +463 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/graph.py +31 -4
- minder_cli-0.5.8/src/minder/graph/memory_graph.py +276 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/__init__.py +2 -0
- minder_cli-0.5.8/src/minder/graph/nodes/guard.py +127 -0
- minder_cli-0.5.8/src/minder/graph/nodes/parallel_retriever.py +245 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/planning.py +7 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/reasoning.py +3 -0
- minder_cli-0.5.8/src/minder/graph/session_graph.py +352 -0
- minder_cli-0.5.8/src/minder/graph/state.py +91 -0
- minder_cli-0.5.8/src/minder/graph/supervisor.py +251 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/llama_cpp_llm.py +6 -1
- minder_cli-0.5.8/src/minder/model_bootstrap.py +205 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/__init__.py +3 -0
- minder_cli-0.5.8/src/minder/models/checkpoint.py +25 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/agent.py +3 -3
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/ide.py +4 -4
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/mcp.py +16 -6
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/jobs.py +5 -4
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/memories.py +3 -2
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/prompts.py +3 -2
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/skills.py +3 -2
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/resources/__init__.py +2 -1
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/runtime.py +64 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/server.py +12 -1
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/interfaces.py +21 -0
- minder_cli-0.5.8/src/minder/store/qdrant/__init__.py +13 -0
- minder_cli-0.5.8/src/minder/store/qdrant/client.py +41 -0
- minder_cli-0.5.8/src/minder/store/qdrant/crud.py +275 -0
- minder_cli-0.5.8/src/minder/store/qdrant/graph_store.py +331 -0
- minder_cli-0.5.8/src/minder/store/qdrant/operational_store.py +859 -0
- minder_cli-0.5.8/src/minder/store/qdrant/vector_store.py +167 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/relational.py +63 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/memory.py +131 -30
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/query.py +83 -40
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/registry.py +1 -1
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/session.py +67 -4
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/workflow.py +49 -2
- minder_cli-0.5.8/src/minder/utils.py +17 -0
- minder_cli-0.5.6/src/minder/cache/providers.py +0 -140
- minder_cli-0.5.6/src/minder/graph/executor.py +0 -247
- minder_cli-0.5.6/src/minder/graph/nodes/guard.py +0 -64
- minder_cli-0.5.6/src/minder/graph/state.py +0 -27
- minder_cli-0.5.6/src/minder/store/milvus/__init__.py +0 -11
- minder_cli-0.5.6/src/minder/store/milvus/client.py +0 -26
- minder_cli-0.5.6/src/minder/store/milvus/collections.py +0 -15
- minder_cli-0.5.6/src/minder/store/milvus/vector_store.py +0 -232
- minder_cli-0.5.6/src/minder/store/mongodb/__init__.py +0 -11
- minder_cli-0.5.6/src/minder/store/mongodb/client.py +0 -49
- minder_cli-0.5.6/src/minder/store/mongodb/graph_store.py +0 -497
- minder_cli-0.5.6/src/minder/store/mongodb/indexes.py +0 -96
- minder_cli-0.5.6/src/minder/store/mongodb/operational_store.py +0 -1098
- {minder_cli-0.5.6 → minder_cli-0.5.8}/.gitignore +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/LICENSE +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/README-pypi.md +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/README.md +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/api/routers/prompts.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/dto.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/context.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/middleware.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/principal.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/rate_limiter.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/rbac.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/service.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/agent_seeder.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/chunking/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/chunking/code_splitter.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/chunking/splitter.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/cli.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/context_compactor.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/continuity.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/dev.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/base.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/openai.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/edges.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/clarification.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/evaluator.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/llm.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/reflection.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/reranker.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/retriever.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/verification.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/workflow_planner.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/runtime.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/error_learner.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/pattern_extractor.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/quality_optimizer.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/skill_synthesizer.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/base.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/factory.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/openai.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/agent.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/base.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/client.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/document.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/error.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/graph.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/history.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/job.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/prompt.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/repository.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/rule.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/session.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/skill.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/user.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/workflow.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/audit.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/logging.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/metrics.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/tracing.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/auth.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/sync.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/update.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/main.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/common.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/config.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/git.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/version.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/agents.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/api.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/context.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/dashboard.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/routes.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/runtime.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/search.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/prompts/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/prompts/formatter.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/hybrid.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/mmr.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/multi_hop.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/document.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/error.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/feedback.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/graph.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/history.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/repo_state.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/rule.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/vector.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/agents.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/auth.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/graph.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/ingest.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/repo_scanner.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/seeds/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/seeds/default_agents.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/skills.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/transport/__init__.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/transport/base.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/transport/sse.py +0 -0
- {minder_cli-0.5.6 → minder_cli-0.5.8}/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.5.
|
|
3
|
+
Version: 0.5.8
|
|
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
|
|
@@ -23,14 +23,12 @@ Requires-Dist: langgraph>=1.1.8; extra == 'server'
|
|
|
23
23
|
Requires-Dist: litellm>=1.83.1; extra == 'server'
|
|
24
24
|
Requires-Dist: llama-cpp-python>=0.3.7; extra == 'server'
|
|
25
25
|
Requires-Dist: mcp>=1.26.0; extra == 'server'
|
|
26
|
-
Requires-Dist: motor>=3.7.0; extra == 'server'
|
|
27
26
|
Requires-Dist: passlib[bcrypt]>=1.7.4; extra == 'server'
|
|
28
27
|
Requires-Dist: prometheus-client>=0.24.1; extra == 'server'
|
|
29
28
|
Requires-Dist: pydantic-settings[toml]>=2.13.1; extra == 'server'
|
|
30
29
|
Requires-Dist: pydantic>=2.12.5; extra == 'server'
|
|
31
30
|
Requires-Dist: pyjwt>=2.12.1; extra == 'server'
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist: redis>=4.2.0; extra == 'server'
|
|
31
|
+
Requires-Dist: qdrant-client>=1.14.0; extra == 'server'
|
|
34
32
|
Requires-Dist: sqlalchemy[asyncio]>=2.0.49; extra == 'server'
|
|
35
33
|
Requires-Dist: yarl>=1.16.0; extra == 'server'
|
|
36
34
|
Requires-Dist: zipp>=3.21.0; extra == 'server'
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "minder-cli"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.8"
|
|
8
8
|
description = "Minder CLI is the command-line interface for the Minder self-hosted MCP platform."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.14"
|
|
@@ -30,14 +30,12 @@ server = [
|
|
|
30
30
|
"litellm>=1.83.1",
|
|
31
31
|
"llama-cpp-python>=0.3.7",
|
|
32
32
|
"mcp>=1.26.0",
|
|
33
|
-
"motor>=3.7.0",
|
|
34
33
|
"passlib[bcrypt]>=1.7.4",
|
|
35
34
|
"prometheus-client>=0.24.1",
|
|
36
35
|
"pydantic>=2.12.5",
|
|
37
36
|
"pydantic-settings[toml]>=2.13.1",
|
|
38
37
|
"pyjwt>=2.12.1",
|
|
39
|
-
"
|
|
40
|
-
"redis>=4.2.0",
|
|
38
|
+
"qdrant-client>=1.14.0",
|
|
41
39
|
"sqlalchemy[asyncio]>=2.0.49",
|
|
42
40
|
"yarl>=1.16.0",
|
|
43
41
|
"zipp>=3.21.0",
|
|
@@ -54,7 +52,6 @@ minder = "minder.cli:main"
|
|
|
54
52
|
|
|
55
53
|
[dependency-groups]
|
|
56
54
|
dev = [
|
|
57
|
-
"fakeredis[lua]>=2.27.0",
|
|
58
55
|
"mypy>=1.20.1",
|
|
59
56
|
"pytest>=9.0.2",
|
|
60
57
|
"pytest-asyncio>=1.3.0",
|
|
@@ -10,6 +10,7 @@ from typing import Any
|
|
|
10
10
|
from minder.config import MinderConfig
|
|
11
11
|
from minder.store.interfaces import IOperationalStore
|
|
12
12
|
from minder.tools.skills import SkillTools
|
|
13
|
+
from minder.utils import _iso
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def _utcnow() -> datetime:
|
|
@@ -304,10 +305,10 @@ class AdminJobService:
|
|
|
304
305
|
"progress_total": int(getattr(job, "progress_total", 0) or 0),
|
|
305
306
|
"message": getattr(job, "message", None),
|
|
306
307
|
"events": list(getattr(job, "events", []) or []),
|
|
307
|
-
"created_at": created_at
|
|
308
|
-
"updated_at": updated_at
|
|
309
|
-
"started_at": started_at
|
|
310
|
-
"finished_at": finished_at
|
|
308
|
+
"created_at": _iso(created_at),
|
|
309
|
+
"updated_at": _iso(updated_at),
|
|
310
|
+
"started_at": _iso(started_at),
|
|
311
|
+
"finished_at": _iso(finished_at),
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
|
|
@@ -63,6 +63,7 @@ from minder.observability.audit import AuditEmitter
|
|
|
63
63
|
from minder.store.interfaces import IGraphRepository, IOperationalStore
|
|
64
64
|
from minder.tools.graph import GraphTools
|
|
65
65
|
from minder.tools.registry import SCOPEABLE_TOOLS
|
|
66
|
+
from minder.utils import _iso
|
|
66
67
|
|
|
67
68
|
_UNSET: Any = object() # sentinel for optional update fields
|
|
68
69
|
|
|
@@ -335,9 +336,7 @@ class AdminConsoleUseCases:
|
|
|
335
336
|
{
|
|
336
337
|
"event_type": str(getattr(event, "event_type", "")),
|
|
337
338
|
"created_at": (
|
|
338
|
-
getattr(event, "created_at")
|
|
339
|
-
if getattr(event, "created_at", None)
|
|
340
|
-
else "unknown time"
|
|
339
|
+
_iso(getattr(event, "created_at", None)) or "unknown time"
|
|
341
340
|
),
|
|
342
341
|
}
|
|
343
342
|
for event in filtered[:limit]
|
|
@@ -373,6 +372,9 @@ class AdminConsoleUseCases:
|
|
|
373
372
|
"antigravity": (
|
|
374
373
|
f'{{"mcpServers":{{"minder":{{"serverUrl":"{base_url}/mcp","headers":{{"X-Minder-Client-Key":"<mkc_...>"}}}}}}}}'
|
|
375
374
|
),
|
|
375
|
+
"gemini": (
|
|
376
|
+
f'{{"mcpServers":{{"minder":{{"serverUrl":"{base_url}/mcp","headers":{{"X-Minder-Client-Key":"<mkc_...>"}}}}}}}}'
|
|
377
|
+
),
|
|
376
378
|
"cursor": (
|
|
377
379
|
f'{{"mcpServers":{{"minder":{{"url":"{base_url}/mcp","headers":{{"X-Minder-Client-Key":"<mkc_...>"}}}}}}}}'
|
|
378
380
|
),
|
|
@@ -421,7 +423,7 @@ class AdminConsoleUseCases:
|
|
|
421
423
|
"resource_id": event.resource_id,
|
|
422
424
|
"resource_name": None,
|
|
423
425
|
"outcome": event.outcome,
|
|
424
|
-
"created_at": event.created_at
|
|
426
|
+
"created_at": _iso(event.created_at),
|
|
425
427
|
"audit_metadata": getattr(event, "audit_metadata", None),
|
|
426
428
|
}
|
|
427
429
|
|
|
@@ -560,11 +562,7 @@ class AdminConsoleUseCases:
|
|
|
560
562
|
"display_name": getattr(user, "display_name", user.username),
|
|
561
563
|
"role": user.role,
|
|
562
564
|
"is_active": bool(getattr(user, "is_active", True)),
|
|
563
|
-
"created_at": (
|
|
564
|
-
user.created_at.isoformat()
|
|
565
|
-
if getattr(user, "created_at", None)
|
|
566
|
-
else None
|
|
567
|
-
),
|
|
565
|
+
"created_at": _iso(getattr(user, "created_at", None)),
|
|
568
566
|
}
|
|
569
567
|
|
|
570
568
|
# ------------------------------------------------------------------
|
|
@@ -647,11 +645,7 @@ class AdminConsoleUseCases:
|
|
|
647
645
|
"description": getattr(workflow, "description", ""),
|
|
648
646
|
"enforcement": getattr(workflow, "enforcement", "strict"),
|
|
649
647
|
"steps": steps,
|
|
650
|
-
"created_at": (
|
|
651
|
-
workflow.created_at.isoformat()
|
|
652
|
-
if getattr(workflow, "created_at", None)
|
|
653
|
-
else None
|
|
654
|
-
),
|
|
648
|
+
"created_at": _iso(getattr(workflow, "created_at", None)),
|
|
655
649
|
}
|
|
656
650
|
|
|
657
651
|
# ------------------------------------------------------------------
|
|
@@ -752,16 +746,8 @@ class AdminConsoleUseCases:
|
|
|
752
746
|
"artifact_types": list(getattr(agent, "artifact_types", []) or []),
|
|
753
747
|
"tags": list(getattr(agent, "tags", []) or []),
|
|
754
748
|
"is_default": bool(getattr(agent, "is_default", False)),
|
|
755
|
-
"created_at": (
|
|
756
|
-
|
|
757
|
-
if getattr(agent, "created_at", None)
|
|
758
|
-
else None
|
|
759
|
-
),
|
|
760
|
-
"updated_at": (
|
|
761
|
-
agent.updated_at.isoformat()
|
|
762
|
-
if getattr(agent, "updated_at", None)
|
|
763
|
-
else None
|
|
764
|
-
),
|
|
749
|
+
"created_at": _iso(getattr(agent, "created_at", None)),
|
|
750
|
+
"updated_at": _iso(getattr(agent, "updated_at", None)),
|
|
765
751
|
}
|
|
766
752
|
|
|
767
753
|
# ------------------------------------------------------------------
|
|
@@ -824,16 +810,8 @@ class AdminConsoleUseCases:
|
|
|
824
810
|
"active_skills": dict(getattr(session, "active_skills", {}) or {}),
|
|
825
811
|
"state": dict(getattr(session, "state", {}) or {}),
|
|
826
812
|
"ttl": int(getattr(session, "ttl", 86400) or 86400),
|
|
827
|
-
"created_at": (
|
|
828
|
-
|
|
829
|
-
if getattr(session, "created_at", None)
|
|
830
|
-
else ""
|
|
831
|
-
),
|
|
832
|
-
"last_active": (
|
|
833
|
-
session.last_active.isoformat()
|
|
834
|
-
if getattr(session, "last_active", None)
|
|
835
|
-
else ""
|
|
836
|
-
),
|
|
813
|
+
"created_at": _iso(getattr(session, "created_at", None)) or "",
|
|
814
|
+
"last_active": _iso(getattr(session, "last_active", None)) or "",
|
|
837
815
|
}
|
|
838
816
|
|
|
839
817
|
# ------------------------------------------------------------------
|
|
@@ -1031,11 +1009,7 @@ class AdminConsoleUseCases:
|
|
|
1031
1009
|
"workflow_name": getattr(state, "workflow_name", None) if state else None,
|
|
1032
1010
|
"workflow_state": getattr(state, "state", None) if state else None,
|
|
1033
1011
|
"current_step": getattr(state, "current_step", None) if state else None,
|
|
1034
|
-
"created_at": (
|
|
1035
|
-
repo.created_at.isoformat()
|
|
1036
|
-
if getattr(repo, "created_at", None)
|
|
1037
|
-
else None
|
|
1038
|
-
),
|
|
1012
|
+
"created_at": _iso(getattr(repo, "created_at", None)),
|
|
1039
1013
|
}
|
|
1040
1014
|
|
|
1041
1015
|
async def sync_repository_graph(
|
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
4
5
|
|
|
5
|
-
from minder.cache.providers import
|
|
6
|
+
from minder.cache.providers import LRUCacheProvider
|
|
6
7
|
from minder.config import MinderConfig
|
|
7
8
|
from minder.store.interfaces import ICacheProvider, IGraphRepository, IOperationalStore, IVectorStore
|
|
8
9
|
from minder.store.vector import VectorStore
|
|
9
10
|
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from minder.store.qdrant.client import QdrantClientWrapper
|
|
13
|
+
|
|
14
|
+
# Single shared Qdrant client — all three stores reuse the same connection pool.
|
|
15
|
+
_qdrant_client: QdrantClientWrapper | None = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _get_qdrant_client(config: MinderConfig) -> QdrantClientWrapper:
|
|
19
|
+
global _qdrant_client
|
|
20
|
+
if _qdrant_client is None:
|
|
21
|
+
from minder.store.qdrant.client import QdrantClientWrapper
|
|
22
|
+
_qdrant_client = QdrantClientWrapper(
|
|
23
|
+
url=config.qdrant.url,
|
|
24
|
+
api_key=config.qdrant.api_key or None,
|
|
25
|
+
prefer_grpc=config.qdrant.prefer_grpc,
|
|
26
|
+
prefix=config.qdrant.collection_prefix,
|
|
27
|
+
)
|
|
28
|
+
return _qdrant_client
|
|
29
|
+
|
|
10
30
|
|
|
11
31
|
def _sqlite_db_url(raw_path: str) -> str:
|
|
12
32
|
db_path = Path(raw_path).expanduser()
|
|
@@ -17,64 +37,45 @@ def _sqlite_db_url(raw_path: str) -> str:
|
|
|
17
37
|
def build_store(config: MinderConfig) -> IOperationalStore:
|
|
18
38
|
provider = config.relational_store.provider
|
|
19
39
|
|
|
20
|
-
if provider == "
|
|
21
|
-
from minder.store.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
client = MongoClient(
|
|
25
|
-
uri=config.mongodb.uri,
|
|
26
|
-
database=config.mongodb.database,
|
|
27
|
-
min_pool_size=config.mongodb.min_pool_size,
|
|
28
|
-
max_pool_size=config.mongodb.max_pool_size,
|
|
29
|
-
)
|
|
30
|
-
return MongoOperationalStore(client) # type: ignore[return-value]
|
|
40
|
+
if provider == "qdrant":
|
|
41
|
+
from minder.store.qdrant.operational_store import QdrantOperationalStore
|
|
42
|
+
return QdrantOperationalStore(_get_qdrant_client(config)) # type: ignore[return-value]
|
|
31
43
|
|
|
32
44
|
if provider in ("sqlite", "postgresql"):
|
|
33
45
|
from minder.store.relational import RelationalStore
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
db_url = (
|
|
47
|
+
_sqlite_db_url(config.relational_store.db_path)
|
|
48
|
+
if provider == "sqlite"
|
|
49
|
+
else config.relational_store.uri
|
|
50
|
+
)
|
|
40
51
|
return RelationalStore(db_url) # type: ignore[return-value]
|
|
41
52
|
|
|
42
53
|
raise ValueError(
|
|
43
54
|
f"Unsupported relational_store.provider '{provider}'. "
|
|
44
|
-
"Supported: '
|
|
55
|
+
"Supported: 'qdrant', 'sqlite', 'postgresql'."
|
|
45
56
|
)
|
|
46
57
|
|
|
47
58
|
|
|
48
59
|
def build_cache(config: MinderConfig) -> ICacheProvider:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return RedisCacheProvider(
|
|
53
|
-
uri=config.redis.uri,
|
|
54
|
-
prefix=config.redis.prefix,
|
|
55
|
-
default_ttl=config.redis.cache_ttl,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
raise ValueError(
|
|
59
|
-
f"Unsupported cache.provider '{provider}'. "
|
|
60
|
-
"Only 'redis' is supported. Set [cache] provider = \"redis\" in minder.toml."
|
|
60
|
+
return LRUCacheProvider(
|
|
61
|
+
max_size=config.cache.max_size,
|
|
62
|
+
default_ttl=config.cache.ttl_seconds,
|
|
61
63
|
)
|
|
62
64
|
|
|
63
65
|
|
|
64
66
|
def build_vector_store(config: MinderConfig, store: IOperationalStore) -> IVectorStore:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
prefix=config.vector_store.collection_prefix,
|
|
67
|
+
provider = config.vector_store.provider
|
|
68
|
+
|
|
69
|
+
if provider == "qdrant":
|
|
70
|
+
from minder.store.qdrant.vector_store import QdrantVectorStore
|
|
71
|
+
return QdrantVectorStore(
|
|
72
|
+
_get_qdrant_client(config),
|
|
73
|
+
store, # type: ignore[arg-type]
|
|
74
|
+
prefix=config.qdrant.collection_prefix,
|
|
74
75
|
dimensions=config.embedding.dimensions,
|
|
75
76
|
)
|
|
76
77
|
|
|
77
|
-
return VectorStore(store, store)
|
|
78
|
+
return VectorStore(store, store) # type: ignore[arg-type]
|
|
78
79
|
|
|
79
80
|
|
|
80
81
|
def build_graph_store(config: MinderConfig) -> IGraphRepository | None:
|
|
@@ -85,21 +86,12 @@ def build_graph_store(config: MinderConfig) -> IGraphRepository | None:
|
|
|
85
86
|
if provider == "auto":
|
|
86
87
|
provider = config.relational_store.provider
|
|
87
88
|
|
|
88
|
-
if provider == "
|
|
89
|
-
from minder.store.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
client = MongoClient(
|
|
93
|
-
uri=config.mongodb.uri,
|
|
94
|
-
database=config.mongodb.database,
|
|
95
|
-
min_pool_size=config.mongodb.min_pool_size,
|
|
96
|
-
max_pool_size=config.mongodb.max_pool_size,
|
|
97
|
-
)
|
|
98
|
-
return MongoGraphStore(client) # type: ignore[return-value]
|
|
89
|
+
if provider == "qdrant":
|
|
90
|
+
from minder.store.qdrant.graph_store import QdrantGraphStore
|
|
91
|
+
return QdrantGraphStore(_get_qdrant_client(config)) # type: ignore[return-value]
|
|
99
92
|
|
|
100
93
|
if provider in ("sqlite", "postgresql"):
|
|
101
94
|
from minder.store.graph import KnowledgeGraphStore
|
|
102
|
-
|
|
103
95
|
if provider == "sqlite":
|
|
104
96
|
if config.graph_store.provider == "auto" and config.relational_store.provider == "sqlite":
|
|
105
97
|
db_url = _sqlite_db_url(config.relational_store.db_path)
|
|
@@ -110,10 +102,9 @@ def build_graph_store(config: MinderConfig) -> IGraphRepository | None:
|
|
|
110
102
|
db_url = config.relational_store.uri
|
|
111
103
|
else:
|
|
112
104
|
db_url = config.graph_store.uri
|
|
113
|
-
|
|
114
105
|
return KnowledgeGraphStore(db_url)
|
|
115
106
|
|
|
116
107
|
raise ValueError(
|
|
117
108
|
f"Unsupported graph_store.provider '{provider}'. "
|
|
118
|
-
"Supported: 'auto', '
|
|
109
|
+
"Supported: 'auto', 'qdrant', 'sqlite', 'postgresql'."
|
|
119
110
|
)
|
|
@@ -9,6 +9,7 @@ from minder.auth.service import AuthError
|
|
|
9
9
|
from minder.auth.service import AuthService
|
|
10
10
|
from minder.cache.providers import LRUCacheProvider
|
|
11
11
|
from minder.config import MinderConfig
|
|
12
|
+
from minder.graph import MinderGraph
|
|
12
13
|
from minder.presentation.http.admin.routes import build_http_routes
|
|
13
14
|
from minder.prompts import PromptRegistry
|
|
14
15
|
from minder.resources import ResourceRegistry
|
|
@@ -45,13 +46,20 @@ def build_transport(
|
|
|
45
46
|
agent_tools = AgentTools(store)
|
|
46
47
|
auth_tools = AuthTools(store, auth_service)
|
|
47
48
|
session_tools = SessionTools(store)
|
|
48
|
-
workflow_tools = WorkflowTools(store, repo_state_store)
|
|
49
49
|
memory_tools = MemoryTools(store, config)
|
|
50
50
|
skill_tools = SkillTools(store, config)
|
|
51
51
|
graph_tools = GraphTools(graph_store, store)
|
|
52
|
+
shared_graph = MinderGraph(store, config, graph_tools=graph_tools)
|
|
53
|
+
workflow_tools = WorkflowTools(
|
|
54
|
+
store,
|
|
55
|
+
repo_state_store,
|
|
56
|
+
graph=shared_graph,
|
|
57
|
+
config=config,
|
|
58
|
+
)
|
|
52
59
|
query_tools = QueryTools(
|
|
53
60
|
store,
|
|
54
61
|
config,
|
|
62
|
+
graph=shared_graph,
|
|
55
63
|
vector_store=vector_store,
|
|
56
64
|
graph_tools=graph_tools,
|
|
57
65
|
)
|
|
@@ -302,12 +310,19 @@ def build_transport(
|
|
|
302
310
|
)
|
|
303
311
|
|
|
304
312
|
async def minder_workflow_step(
|
|
305
|
-
*,
|
|
313
|
+
*,
|
|
314
|
+
user=None,
|
|
315
|
+
repo_id: str | None = None,
|
|
316
|
+
repo_path: str | None = None,
|
|
317
|
+
session_id: str | None = None,
|
|
318
|
+
decision: dict[str, Any] | None = None,
|
|
306
319
|
) -> dict[str, Any]: # noqa: ANN001
|
|
307
320
|
del user
|
|
308
321
|
return await workflow_tools.minder_workflow_step(
|
|
309
|
-
repo_id=uuid.UUID(repo_id),
|
|
322
|
+
repo_id=uuid.UUID(repo_id) if repo_id else None,
|
|
310
323
|
repo_path=repo_path,
|
|
324
|
+
session_id=uuid.UUID(session_id) if session_id else None,
|
|
325
|
+
decision=decision,
|
|
311
326
|
)
|
|
312
327
|
|
|
313
328
|
async def minder_workflow_update(
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Seed default workflows on first startup."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import uuid
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from minder.store.interfaces import IOperationalStore
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
DEFAULT_WORKFLOWS: list[dict[str, Any]] = [
|
|
14
|
+
{
|
|
15
|
+
"name": "tdd",
|
|
16
|
+
"version": 1,
|
|
17
|
+
"description": "Test-Driven Development workflow ensuring tests are written before implementation.",
|
|
18
|
+
"enforcement": "strict",
|
|
19
|
+
"steps": [
|
|
20
|
+
{
|
|
21
|
+
"name": "Problem Analysis",
|
|
22
|
+
"description": "Analyze the problem, understand requirements, and plan the implementation.",
|
|
23
|
+
"gate": "Provide a clear problem analysis and implementation plan.",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "Test Writing",
|
|
27
|
+
"description": "Write failing tests that define the expected behavior and cover edge cases.",
|
|
28
|
+
"gate": "Verify that tests are written and fail as expected (red state).",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "Implementation",
|
|
32
|
+
"description": "Implement the minimum code necessary to make the tests pass.",
|
|
33
|
+
"gate": "Verify that all tests pass (green state) and no regressions are introduced.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "Review",
|
|
37
|
+
"description": "Review the code for quality, adherence to patterns, and clean up technical debt.",
|
|
38
|
+
"gate": "Code review approval and verification of quality standards.",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
"policies": {"block_step_skips": True},
|
|
42
|
+
"default_for_repo": True,
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def seed_default_workflows(store: IOperationalStore) -> None:
|
|
48
|
+
"""Insert default workflows only if they do not already exist.
|
|
49
|
+
|
|
50
|
+
Never overwrites user-modified defaults — guards by name existence check.
|
|
51
|
+
"""
|
|
52
|
+
for defn in DEFAULT_WORKFLOWS:
|
|
53
|
+
name = defn["name"]
|
|
54
|
+
existing = await store.get_workflow_by_name(name)
|
|
55
|
+
if existing is not None:
|
|
56
|
+
logger.debug("Workflow %r already exists, skipping seed", name)
|
|
57
|
+
continue
|
|
58
|
+
|
|
59
|
+
# Make a copy and inject an id if not present
|
|
60
|
+
payload = dict(defn)
|
|
61
|
+
payload["id"] = uuid.uuid4()
|
|
62
|
+
|
|
63
|
+
await store.create_workflow(**payload)
|
|
64
|
+
logger.info("Seeded default workflow: %r", name)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cache Providers — implements ICacheProvider for runtime cache/session layer.
|
|
3
|
+
|
|
4
|
+
Provides in-memory LRU cache provider as a zero-dependency fallback.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class LRUCacheProvider:
|
|
11
|
+
"""
|
|
12
|
+
In-memory LRU cache provider implementing ICacheProvider.
|
|
13
|
+
|
|
14
|
+
Used as zero-dependency fallback.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, *, max_size: int = 1000, default_ttl: int = 3600) -> None:
|
|
18
|
+
self._max_size = max_size
|
|
19
|
+
self._default_ttl = default_ttl
|
|
20
|
+
self._store: dict[str, str] = {}
|
|
21
|
+
|
|
22
|
+
async def get(self, key: str) -> str | None:
|
|
23
|
+
return self._store.get(key)
|
|
24
|
+
|
|
25
|
+
async def set(self, key: str, value: str, *, ttl: int | None = None) -> None:
|
|
26
|
+
if len(self._store) >= self._max_size:
|
|
27
|
+
# Evict oldest entry (FIFO as simple approximation)
|
|
28
|
+
oldest_key = next(iter(self._store))
|
|
29
|
+
del self._store[oldest_key]
|
|
30
|
+
self._store[key] = value
|
|
31
|
+
|
|
32
|
+
async def delete(self, key: str) -> None:
|
|
33
|
+
self._store.pop(key, None)
|
|
34
|
+
|
|
35
|
+
async def exists(self, key: str) -> bool:
|
|
36
|
+
return key in self._store
|
|
37
|
+
|
|
38
|
+
async def expire(self, key: str, ttl: int) -> None:
|
|
39
|
+
pass # No-op for in-memory store
|
|
40
|
+
|
|
41
|
+
async def incr(self, key: str) -> int:
|
|
42
|
+
current = int(self._store.get(key, "0"))
|
|
43
|
+
current += 1
|
|
44
|
+
self._store[key] = str(current)
|
|
45
|
+
return current
|
|
46
|
+
|
|
47
|
+
async def keys(self, pattern: str) -> list[str]:
|
|
48
|
+
import fnmatch
|
|
49
|
+
return [k for k in self._store if fnmatch.fnmatch(k, pattern)]
|
|
50
|
+
|
|
51
|
+
async def flush_namespace(self, namespace: str) -> None:
|
|
52
|
+
prefix = f"{namespace}:"
|
|
53
|
+
to_delete = [k for k in self._store if k.startswith(prefix)]
|
|
54
|
+
for k in to_delete:
|
|
55
|
+
del self._store[k]
|
|
56
|
+
|
|
57
|
+
async def health_check(self) -> bool:
|
|
58
|
+
return True
|
|
59
|
+
|
|
60
|
+
async def close(self) -> None:
|
|
61
|
+
self._store.clear()
|
|
@@ -51,38 +51,29 @@ class LLMConfig(BaseModel):
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
class VectorStoreConfig(BaseModel):
|
|
54
|
-
provider: str = "
|
|
55
|
-
db_path: str = "~/.minder/data/milvus.db" # used by milvus_lite only
|
|
56
|
-
uri: str = "http://localhost:19530" # used by milvus standalone
|
|
54
|
+
provider: str = "qdrant" # "qdrant" | "memory"
|
|
57
55
|
collection_prefix: str = "minder_"
|
|
58
56
|
|
|
59
57
|
|
|
60
58
|
class RelationalStoreConfig(BaseModel):
|
|
61
|
-
provider: str = "
|
|
62
|
-
db_path: str = "minder.db" #
|
|
63
|
-
uri: str = "postgresql+asyncpg://localhost/minder" #
|
|
59
|
+
provider: str = "qdrant" # "qdrant" | "sqlite" | "postgresql"
|
|
60
|
+
db_path: str = "minder.db" # sqlite fallback
|
|
61
|
+
uri: str = "postgresql+asyncpg://localhost/minder" # postgresql only
|
|
64
62
|
|
|
65
63
|
|
|
66
64
|
class GraphStoreConfig(BaseModel):
|
|
67
65
|
enabled: bool = True
|
|
68
|
-
provider: str = "auto" # "auto"
|
|
69
|
-
# auto: mirrors relational_store.provider (mongodb → mongodb, sqlite → sqlite, postgresql → postgresql)
|
|
66
|
+
provider: str = "auto" # "auto" mirrors relational_store.provider
|
|
70
67
|
db_path: str = "~/.minder/data/graph.db" # sqlite only
|
|
71
68
|
uri: str = "postgresql+asyncpg://localhost/minder_graph" # postgresql only
|
|
72
69
|
|
|
73
70
|
|
|
74
|
-
class
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
class QdrantConfig(BaseModel):
|
|
72
|
+
url: str = "http://localhost:6333"
|
|
73
|
+
api_key: Optional[str] = None
|
|
74
|
+
prefer_grpc: bool = False
|
|
75
|
+
collection_prefix: str = "minder_"
|
|
80
76
|
|
|
81
|
-
class RedisConfig(BaseModel):
|
|
82
|
-
uri: str = "redis://localhost:6379/0"
|
|
83
|
-
prefix: str = "minder:"
|
|
84
|
-
session_ttl: int = 86400
|
|
85
|
-
cache_ttl: int = 3600
|
|
86
77
|
|
|
87
78
|
|
|
88
79
|
class RetrievalConfig(BaseModel):
|
|
@@ -92,12 +83,27 @@ class RetrievalConfig(BaseModel):
|
|
|
92
83
|
hybrid_alpha: float = 0.7
|
|
93
84
|
|
|
94
85
|
|
|
86
|
+
class MemoryConfig(BaseModel):
|
|
87
|
+
agentic_recall: bool = False
|
|
88
|
+
recall_min_score: float = 0.4
|
|
89
|
+
recall_max_iterations: int = 3
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class SessionConfig(BaseModel):
|
|
93
|
+
agentic_restore: bool = False
|
|
94
|
+
restore_recall_count: int = 8
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class GraphConfig(BaseModel):
|
|
98
|
+
runtime: str = "langgraph"
|
|
99
|
+
enable_parallel_retrieval: bool = False
|
|
100
|
+
enable_checkpointing: bool = True
|
|
101
|
+
checkpoint_ttl_days: int = 7
|
|
102
|
+
|
|
103
|
+
|
|
95
104
|
class CacheConfig(BaseModel):
|
|
96
105
|
enabled: bool = True
|
|
97
|
-
|
|
98
|
-
max_size: int = (
|
|
99
|
-
1000 # unused; kept for backwards-compat with any existing .env files
|
|
100
|
-
)
|
|
106
|
+
max_size: int = 1000
|
|
101
107
|
ttl_seconds: int = 3600
|
|
102
108
|
|
|
103
109
|
|
|
@@ -142,9 +148,11 @@ class Settings(BaseSettings):
|
|
|
142
148
|
default_factory=RelationalStoreConfig
|
|
143
149
|
)
|
|
144
150
|
graph_store: GraphStoreConfig = Field(default_factory=GraphStoreConfig)
|
|
145
|
-
|
|
146
|
-
redis: RedisConfig = Field(default_factory=RedisConfig)
|
|
151
|
+
qdrant: QdrantConfig = Field(default_factory=QdrantConfig)
|
|
147
152
|
retrieval: RetrievalConfig = Field(default_factory=RetrievalConfig)
|
|
153
|
+
memory: MemoryConfig = Field(default_factory=MemoryConfig)
|
|
154
|
+
session: SessionConfig = Field(default_factory=SessionConfig)
|
|
155
|
+
graph: GraphConfig = Field(default_factory=GraphConfig)
|
|
148
156
|
cache: CacheConfig = Field(default_factory=CacheConfig)
|
|
149
157
|
rate_limit: RateLimitConfig = Field(default_factory=RateLimitConfig)
|
|
150
158
|
verification: VerificationConfig = Field(default_factory=VerificationConfig)
|
|
@@ -13,7 +13,7 @@ import math
|
|
|
13
13
|
from collections import OrderedDict
|
|
14
14
|
from typing import Any
|
|
15
15
|
|
|
16
|
-
from minder.runtime import llama_cpp_usable
|
|
16
|
+
from minder.runtime import get_writable_hf_cache_dir, llama_cpp_usable
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
|
|
@@ -61,11 +61,16 @@ class LocalEmbeddingProvider:
|
|
|
61
61
|
from llama_cpp import Llama
|
|
62
62
|
|
|
63
63
|
logger.info("Initializing Llama.cpp embedding engine for %s", self._model_repo)
|
|
64
|
+
cache_dir = get_writable_hf_cache_dir()
|
|
65
|
+
cache_kwargs: dict[str, Any] = (
|
|
66
|
+
{} if cache_dir is None else {"cache_dir": cache_dir}
|
|
67
|
+
)
|
|
64
68
|
self._model = Llama.from_pretrained(
|
|
65
69
|
repo_id=self._model_repo,
|
|
66
70
|
filename=self._model_file,
|
|
67
71
|
embedding=True,
|
|
68
72
|
verbose=False,
|
|
73
|
+
**cache_kwargs,
|
|
69
74
|
)
|
|
70
75
|
_MODEL_CACHE[cache_key] = self._model
|
|
71
76
|
except Exception as e:
|