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.
Files changed (179) hide show
  1. {minder_cli-0.5.6 → minder_cli-0.5.8}/PKG-INFO +2 -4
  2. {minder_cli-0.5.6 → minder_cli-0.5.8}/pyproject.toml +2 -5
  3. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/jobs.py +5 -4
  4. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/use_cases.py +13 -39
  5. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/providers.py +46 -55
  6. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/transport.py +18 -3
  7. minder_cli-0.5.8/src/minder/bootstrap/workflow_seeder.py +64 -0
  8. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/cache/__init__.py +1 -2
  9. minder_cli-0.5.8/src/minder/cache/providers.py +61 -0
  10. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/config.py +33 -25
  11. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/local.py +6 -1
  12. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/__init__.py +2 -2
  13. minder_cli-0.5.8/src/minder/graph/checkpoint.py +162 -0
  14. minder_cli-0.5.8/src/minder/graph/executor.py +463 -0
  15. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/graph.py +31 -4
  16. minder_cli-0.5.8/src/minder/graph/memory_graph.py +276 -0
  17. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/__init__.py +2 -0
  18. minder_cli-0.5.8/src/minder/graph/nodes/guard.py +127 -0
  19. minder_cli-0.5.8/src/minder/graph/nodes/parallel_retriever.py +245 -0
  20. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/planning.py +7 -0
  21. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/reasoning.py +3 -0
  22. minder_cli-0.5.8/src/minder/graph/session_graph.py +352 -0
  23. minder_cli-0.5.8/src/minder/graph/state.py +91 -0
  24. minder_cli-0.5.8/src/minder/graph/supervisor.py +251 -0
  25. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/llama_cpp_llm.py +6 -1
  26. minder_cli-0.5.8/src/minder/model_bootstrap.py +205 -0
  27. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/__init__.py +3 -0
  28. minder_cli-0.5.8/src/minder/models/checkpoint.py +25 -0
  29. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/agent.py +3 -3
  30. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/ide.py +4 -4
  31. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/mcp.py +16 -6
  32. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/jobs.py +5 -4
  33. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/memories.py +3 -2
  34. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/prompts.py +3 -2
  35. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/skills.py +3 -2
  36. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/resources/__init__.py +2 -1
  37. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/runtime.py +64 -0
  38. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/server.py +12 -1
  39. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/interfaces.py +21 -0
  40. minder_cli-0.5.8/src/minder/store/qdrant/__init__.py +13 -0
  41. minder_cli-0.5.8/src/minder/store/qdrant/client.py +41 -0
  42. minder_cli-0.5.8/src/minder/store/qdrant/crud.py +275 -0
  43. minder_cli-0.5.8/src/minder/store/qdrant/graph_store.py +331 -0
  44. minder_cli-0.5.8/src/minder/store/qdrant/operational_store.py +859 -0
  45. minder_cli-0.5.8/src/minder/store/qdrant/vector_store.py +167 -0
  46. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/relational.py +63 -0
  47. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/memory.py +131 -30
  48. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/query.py +83 -40
  49. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/registry.py +1 -1
  50. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/session.py +67 -4
  51. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/workflow.py +49 -2
  52. minder_cli-0.5.8/src/minder/utils.py +17 -0
  53. minder_cli-0.5.6/src/minder/cache/providers.py +0 -140
  54. minder_cli-0.5.6/src/minder/graph/executor.py +0 -247
  55. minder_cli-0.5.6/src/minder/graph/nodes/guard.py +0 -64
  56. minder_cli-0.5.6/src/minder/graph/state.py +0 -27
  57. minder_cli-0.5.6/src/minder/store/milvus/__init__.py +0 -11
  58. minder_cli-0.5.6/src/minder/store/milvus/client.py +0 -26
  59. minder_cli-0.5.6/src/minder/store/milvus/collections.py +0 -15
  60. minder_cli-0.5.6/src/minder/store/milvus/vector_store.py +0 -232
  61. minder_cli-0.5.6/src/minder/store/mongodb/__init__.py +0 -11
  62. minder_cli-0.5.6/src/minder/store/mongodb/client.py +0 -49
  63. minder_cli-0.5.6/src/minder/store/mongodb/graph_store.py +0 -497
  64. minder_cli-0.5.6/src/minder/store/mongodb/indexes.py +0 -96
  65. minder_cli-0.5.6/src/minder/store/mongodb/operational_store.py +0 -1098
  66. {minder_cli-0.5.6 → minder_cli-0.5.8}/.gitignore +0 -0
  67. {minder_cli-0.5.6 → minder_cli-0.5.8}/LICENSE +0 -0
  68. {minder_cli-0.5.6 → minder_cli-0.5.8}/README-pypi.md +0 -0
  69. {minder_cli-0.5.6 → minder_cli-0.5.8}/README.md +0 -0
  70. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/__init__.py +0 -0
  71. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/api/routers/prompts.py +0 -0
  72. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/__init__.py +0 -0
  73. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/__init__.py +0 -0
  74. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/application/admin/dto.py +0 -0
  75. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/__init__.py +0 -0
  76. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/context.py +0 -0
  77. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/middleware.py +0 -0
  78. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/principal.py +0 -0
  79. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/rate_limiter.py +0 -0
  80. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/rbac.py +0 -0
  81. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/auth/service.py +0 -0
  82. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/__init__.py +0 -0
  83. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/bootstrap/agent_seeder.py +0 -0
  84. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/chunking/__init__.py +0 -0
  85. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/chunking/code_splitter.py +0 -0
  86. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/chunking/splitter.py +0 -0
  87. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/cli.py +0 -0
  88. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/context_compactor.py +0 -0
  89. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/continuity.py +0 -0
  90. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/dev.py +0 -0
  91. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/__init__.py +0 -0
  92. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/base.py +0 -0
  93. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/embedding/openai.py +0 -0
  94. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/edges.py +0 -0
  95. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/clarification.py +0 -0
  96. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/evaluator.py +0 -0
  97. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/llm.py +0 -0
  98. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/reflection.py +0 -0
  99. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/reranker.py +0 -0
  100. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/retriever.py +0 -0
  101. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/verification.py +0 -0
  102. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/nodes/workflow_planner.py +0 -0
  103. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/graph/runtime.py +0 -0
  104. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/__init__.py +0 -0
  105. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/error_learner.py +0 -0
  106. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/pattern_extractor.py +0 -0
  107. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/quality_optimizer.py +0 -0
  108. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/learning/skill_synthesizer.py +0 -0
  109. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/__init__.py +0 -0
  110. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/base.py +0 -0
  111. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/factory.py +0 -0
  112. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/llm/openai.py +0 -0
  113. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/agent.py +0 -0
  114. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/base.py +0 -0
  115. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/client.py +0 -0
  116. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/document.py +0 -0
  117. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/error.py +0 -0
  118. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/graph.py +0 -0
  119. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/history.py +0 -0
  120. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/job.py +0 -0
  121. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/prompt.py +0 -0
  122. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/repository.py +0 -0
  123. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/rule.py +0 -0
  124. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/session.py +0 -0
  125. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/skill.py +0 -0
  126. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/user.py +0 -0
  127. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/models/workflow.py +0 -0
  128. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/__init__.py +0 -0
  129. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/audit.py +0 -0
  130. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/logging.py +0 -0
  131. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/metrics.py +0 -0
  132. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/observability/tracing.py +0 -0
  133. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/__init__.py +0 -0
  134. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/__init__.py +0 -0
  135. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/auth.py +0 -0
  136. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/sync.py +0 -0
  137. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/commands/update.py +0 -0
  138. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/main.py +0 -0
  139. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/common.py +0 -0
  140. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/config.py +0 -0
  141. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/git.py +0 -0
  142. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/cli/utils/version.py +0 -0
  143. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/__init__.py +0 -0
  144. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/__init__.py +0 -0
  145. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/agents.py +0 -0
  146. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/api.py +0 -0
  147. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/context.py +0 -0
  148. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/dashboard.py +0 -0
  149. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/routes.py +0 -0
  150. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/runtime.py +0 -0
  151. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/presentation/http/admin/search.py +0 -0
  152. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/prompts/__init__.py +0 -0
  153. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/prompts/formatter.py +0 -0
  154. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/__init__.py +0 -0
  155. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/hybrid.py +0 -0
  156. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/mmr.py +0 -0
  157. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/retrieval/multi_hop.py +0 -0
  158. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/__init__.py +0 -0
  159. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/document.py +0 -0
  160. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/error.py +0 -0
  161. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/feedback.py +0 -0
  162. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/graph.py +0 -0
  163. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/history.py +0 -0
  164. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/repo_state.py +0 -0
  165. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/rule.py +0 -0
  166. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/store/vector.py +0 -0
  167. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/__init__.py +0 -0
  168. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/agents.py +0 -0
  169. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/auth.py +0 -0
  170. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/graph.py +0 -0
  171. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/ingest.py +0 -0
  172. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/repo_scanner.py +0 -0
  173. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/seeds/__init__.py +0 -0
  174. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/seeds/default_agents.py +0 -0
  175. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/tools/skills.py +0 -0
  176. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/transport/__init__.py +0 -0
  177. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/transport/base.py +0 -0
  178. {minder_cli-0.5.6 → minder_cli-0.5.8}/src/minder/transport/sse.py +0 -0
  179. {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.6
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: pymilvus>=2.6.12; extra == 'server'
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.6"
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
- "pymilvus>=2.6.12",
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.isoformat() if created_at else None,
308
- "updated_at": updated_at.isoformat() if updated_at else None,
309
- "started_at": started_at.isoformat() if started_at else None,
310
- "finished_at": finished_at.isoformat() if finished_at else None,
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").isoformat()
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.isoformat() if event.created_at else None,
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
- agent.created_at.isoformat()
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
- session.created_at.isoformat()
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 RedisCacheProvider
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 == "mongodb":
21
- from minder.store.mongodb.client import MongoClient
22
- from minder.store.mongodb.operational_store import MongoOperationalStore
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
- if provider == "sqlite":
36
- db_url = _sqlite_db_url(config.relational_store.db_path)
37
- else:
38
- db_url = config.relational_store.uri
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: 'mongodb', 'sqlite', 'postgresql'."
55
+ "Supported: 'qdrant', 'sqlite', 'postgresql'."
45
56
  )
46
57
 
47
58
 
48
59
  def build_cache(config: MinderConfig) -> ICacheProvider:
49
- provider = config.cache.provider
50
-
51
- if provider == "redis":
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
- if config.vector_store.provider == "milvus":
66
- from minder.store.milvus.client import MilvusClient
67
- from minder.store.milvus.vector_store import MilvusVectorStore
68
-
69
- client = MilvusClient(uri=config.vector_store.uri)
70
- return MilvusVectorStore(
71
- client,
72
- store,
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 == "mongodb":
89
- from minder.store.mongodb.client import MongoClient
90
- from minder.store.mongodb.graph_store import MongoGraphStore
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', 'mongodb', 'sqlite', 'postgresql'."
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
- *, user=None, repo_id: str, repo_path: str
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)
@@ -2,9 +2,8 @@
2
2
  Cache package — providers for runtime caching layer.
3
3
  """
4
4
 
5
- from minder.cache.providers import LRUCacheProvider, RedisCacheProvider
5
+ from minder.cache.providers import LRUCacheProvider
6
6
 
7
7
  __all__ = [
8
8
  "LRUCacheProvider",
9
- "RedisCacheProvider",
10
9
  ]
@@ -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 = "milvus_lite" # "milvus" (standalone) | "milvus_lite" | "memory"
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 = "mongodb" # "mongodb" | "sqlite" | "postgresql"
62
- db_path: str = "minder.db" # used by sqlite
63
- uri: str = "postgresql+asyncpg://localhost/minder" # used by postgresql
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" | "mongodb" | "sqlite" | "postgresql"
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 MongoDBConfig(BaseModel):
75
- uri: str = "mongodb://localhost:27017"
76
- database: str = "minder"
77
- min_pool_size: int = 2
78
- max_pool_size: int = 10
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
- provider: str = "redis" # "redis" is the only supported runtime backend
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
- mongodb: MongoDBConfig = Field(default_factory=MongoDBConfig)
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:
@@ -1,6 +1,6 @@
1
- from .state import GraphState
1
+ from .state import GraphState, GraphStateSchema
2
2
 
3
- __all__ = ["GraphState", "MinderGraph"]
3
+ __all__ = ["GraphState", "GraphStateSchema", "MinderGraph"]
4
4
 
5
5
 
6
6
  def __getattr__(name: str):