mnemoai-assistant 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. mnemoai_assistant-0.1.0/.claude/settings.local.json +78 -0
  2. mnemoai_assistant-0.1.0/.gitignore +165 -0
  3. mnemoai_assistant-0.1.0/CLAUDE.md +199 -0
  4. mnemoai_assistant-0.1.0/LICENSE +21 -0
  5. mnemoai_assistant-0.1.0/PKG-INFO +1934 -0
  6. mnemoai_assistant-0.1.0/README.md +1878 -0
  7. mnemoai_assistant-0.1.0/bash/ollama-env-mac/README.md +56 -0
  8. mnemoai_assistant-0.1.0/bash/ollama-env-mac/ollama.environment.plist +24 -0
  9. mnemoai_assistant-0.1.0/bash/ollama-freeup-vram/README.md +46 -0
  10. mnemoai_assistant-0.1.0/bash/ollama-freeup-vram/com.ollama.vramcleaner.plist +28 -0
  11. mnemoai_assistant-0.1.0/bash/ollama-freeup-vram/ollama-vram-cleaner.service +11 -0
  12. mnemoai_assistant-0.1.0/bash/ollama-freeup-vram/ollama_free_vram.sh +3 -0
  13. mnemoai_assistant-0.1.0/bash/system-command-app/README.md +33 -0
  14. mnemoai_assistant-0.1.0/bash/system-command-app/mnemoai-wrapper.sh +20 -0
  15. mnemoai_assistant-0.1.0/docs/ARCHITECTURE.md +135 -0
  16. mnemoai_assistant-0.1.0/images/assistant-demo.gif +0 -0
  17. mnemoai_assistant-0.1.0/images/mnemoai-logo.png +0 -0
  18. mnemoai_assistant-0.1.0/pyproject.toml +93 -0
  19. mnemoai_assistant-0.1.0/pytest.ini +10 -0
  20. mnemoai_assistant-0.1.0/requirements-dev.txt +5 -0
  21. mnemoai_assistant-0.1.0/requirements.txt +30 -0
  22. mnemoai_assistant-0.1.0/src/mnemoai/__init__.py +1 -0
  23. mnemoai_assistant-0.1.0/src/mnemoai/__main__.py +6 -0
  24. mnemoai_assistant-0.1.0/src/mnemoai/client/__init__.py +5 -0
  25. mnemoai_assistant-0.1.0/src/mnemoai/client/agent/__init__.py +2 -0
  26. mnemoai_assistant-0.1.0/src/mnemoai/client/agent/agent.py +1168 -0
  27. mnemoai_assistant-0.1.0/src/mnemoai/client/agent/orchestrator.py +106 -0
  28. mnemoai_assistant-0.1.0/src/mnemoai/client/agent/reasoning_utils.py +99 -0
  29. mnemoai_assistant-0.1.0/src/mnemoai/client/agent/router.py +167 -0
  30. mnemoai_assistant-0.1.0/src/mnemoai/client/client.py +932 -0
  31. mnemoai_assistant-0.1.0/src/mnemoai/client/managers/__init__.py +0 -0
  32. mnemoai_assistant-0.1.0/src/mnemoai/client/managers/agent_conversation_manager.py +406 -0
  33. mnemoai_assistant-0.1.0/src/mnemoai/client/managers/user_profile_manager.py +558 -0
  34. mnemoai_assistant-0.1.0/src/mnemoai/client/mcp_tool_wrapper.py +367 -0
  35. mnemoai_assistant-0.1.0/src/mnemoai/client/memory/__init__.py +0 -0
  36. mnemoai_assistant-0.1.0/src/mnemoai/client/memory/chroma_store.py +244 -0
  37. mnemoai_assistant-0.1.0/src/mnemoai/client/memory/episodic_memory.py +390 -0
  38. mnemoai_assistant-0.1.0/src/mnemoai/client/memory/faiss_store.py +233 -0
  39. mnemoai_assistant-0.1.0/src/mnemoai/client/memory/playbook_store.py +343 -0
  40. mnemoai_assistant-0.1.0/src/mnemoai/client/memory/reflector.py +449 -0
  41. mnemoai_assistant-0.1.0/src/mnemoai/client/ui/__init__.py +1 -0
  42. mnemoai_assistant-0.1.0/src/mnemoai/client/ui/chat_interface.py +501 -0
  43. mnemoai_assistant-0.1.0/src/mnemoai/client/ui/spinner.py +41 -0
  44. mnemoai_assistant-0.1.0/src/mnemoai/main.py +80 -0
  45. mnemoai_assistant-0.1.0/src/mnemoai/models/__init__.py +0 -0
  46. mnemoai_assistant-0.1.0/src/mnemoai/models/chat_models/__init__.py +0 -0
  47. mnemoai_assistant-0.1.0/src/mnemoai/models/chat_models/chat_ollama_wrapper.py +17 -0
  48. mnemoai_assistant-0.1.0/src/mnemoai/models/chat_models/sagemaker_chat.py +352 -0
  49. mnemoai_assistant-0.1.0/src/mnemoai/models/controllers/__init__.py +1 -0
  50. mnemoai_assistant-0.1.0/src/mnemoai/models/controllers/base_model_controller.py +8 -0
  51. mnemoai_assistant-0.1.0/src/mnemoai/models/controllers/embeddings_controller.py +362 -0
  52. mnemoai_assistant-0.1.0/src/mnemoai/models/controllers/llm_controller.py +241 -0
  53. mnemoai_assistant-0.1.0/src/mnemoai/models/controllers/vision_model_controller.py +283 -0
  54. mnemoai_assistant-0.1.0/src/mnemoai/models/mantle_factory.py +129 -0
  55. mnemoai_assistant-0.1.0/src/mnemoai/models/provider_params.py +220 -0
  56. mnemoai_assistant-0.1.0/src/mnemoai/server/__init__.py +1 -0
  57. mnemoai_assistant-0.1.0/src/mnemoai/server/error_handler.py +278 -0
  58. mnemoai_assistant-0.1.0/src/mnemoai/server/server.py +16 -0
  59. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/__init__.py +13 -0
  60. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/background_tasks.py +449 -0
  61. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/describe_image.py +88 -0
  62. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/execute_bash.py +85 -0
  63. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/file_edit.py +212 -0
  64. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/file_search.py +277 -0
  65. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/fs_read.py +120 -0
  66. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/fs_write.py +422 -0
  67. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/git_safety.py +634 -0
  68. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/plan_mode.py +382 -0
  69. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/rag/__init__.py +14 -0
  70. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/rag/chroma_store.py +128 -0
  71. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/rag/faiss_store.py +152 -0
  72. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/rag/session.py +368 -0
  73. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/rag/vector_store_controller.py +144 -0
  74. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/rag_tool.py +138 -0
  75. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/__init__.py +19 -0
  76. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/chunking_helper.py +381 -0
  77. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/csv_reader.py +128 -0
  78. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/directory_reader.py +94 -0
  79. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/docx_reader.py +122 -0
  80. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/json_reader.py +173 -0
  81. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/line_reader.py +111 -0
  82. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/pdf_reader.py +113 -0
  83. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/readers/search_reader.py +75 -0
  84. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/todo_manager.py +162 -0
  85. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/tools_manager.py +165 -0
  86. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/web_crawler.py +164 -0
  87. mnemoai_assistant-0.1.0/src/mnemoai/server/tools/web_search.py +130 -0
  88. mnemoai_assistant-0.1.0/src/mnemoai/utils/__init__.py +1 -0
  89. mnemoai_assistant-0.1.0/src/mnemoai/utils/bm25.py +64 -0
  90. mnemoai_assistant-0.1.0/src/mnemoai/utils/config.py +144 -0
  91. mnemoai_assistant-0.1.0/src/mnemoai/utils/config.yaml.bedrock.example +383 -0
  92. mnemoai_assistant-0.1.0/src/mnemoai/utils/config.yaml.bedrock.mantle.example +429 -0
  93. mnemoai_assistant-0.1.0/src/mnemoai/utils/config.yaml.example +384 -0
  94. mnemoai_assistant-0.1.0/src/mnemoai/utils/configurator.py +870 -0
  95. mnemoai_assistant-0.1.0/src/mnemoai/utils/console.py +22 -0
  96. mnemoai_assistant-0.1.0/src/mnemoai/utils/formatting/__init__.py +4 -0
  97. mnemoai_assistant-0.1.0/src/mnemoai/utils/formatting/code_formatter.py +203 -0
  98. mnemoai_assistant-0.1.0/src/mnemoai/utils/formatting/response_parser.py +66 -0
  99. mnemoai_assistant-0.1.0/src/mnemoai/utils/formatting/url_formatter.py +133 -0
  100. mnemoai_assistant-0.1.0/src/mnemoai/utils/logger.py +59 -0
  101. mnemoai_assistant-0.1.0/src/mnemoai/utils/paths.py +97 -0
  102. mnemoai_assistant-0.1.0/tests/__init__.py +0 -0
  103. mnemoai_assistant-0.1.0/tests/conftest.py +13 -0
  104. mnemoai_assistant-0.1.0/tests/integration/__init__.py +0 -0
  105. mnemoai_assistant-0.1.0/tests/integration/conftest.py +81 -0
  106. mnemoai_assistant-0.1.0/tests/integration/test_agent_live.py +51 -0
  107. mnemoai_assistant-0.1.0/tests/unit/__init__.py +0 -0
  108. mnemoai_assistant-0.1.0/tests/unit/test_bedrock_endpoint.py +390 -0
  109. mnemoai_assistant-0.1.0/tests/unit/test_bm25.py +57 -0
  110. mnemoai_assistant-0.1.0/tests/unit/test_configurator.py +599 -0
  111. mnemoai_assistant-0.1.0/tests/unit/test_conversation_compaction.py +212 -0
  112. mnemoai_assistant-0.1.0/tests/unit/test_episodic_heuristics.py +118 -0
  113. mnemoai_assistant-0.1.0/tests/unit/test_error_handler.py +81 -0
  114. mnemoai_assistant-0.1.0/tests/unit/test_execute_bash.py +89 -0
  115. mnemoai_assistant-0.1.0/tests/unit/test_file_tools.py +129 -0
  116. mnemoai_assistant-0.1.0/tests/unit/test_formatters.py +114 -0
  117. mnemoai_assistant-0.1.0/tests/unit/test_git_safety.py +106 -0
  118. mnemoai_assistant-0.1.0/tests/unit/test_model_scoped_paths.py +40 -0
  119. mnemoai_assistant-0.1.0/tests/unit/test_orchestrator.py +66 -0
  120. mnemoai_assistant-0.1.0/tests/unit/test_paths.py +75 -0
  121. mnemoai_assistant-0.1.0/tests/unit/test_reasoning_utils.py +118 -0
  122. mnemoai_assistant-0.1.0/tests/unit/test_response_parser.py +52 -0
  123. mnemoai_assistant-0.1.0/tests/unit/test_vision_content.py +44 -0
@@ -0,0 +1,78 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git:*)",
5
+ "Bash(wc:*)",
6
+ "Bash(python:*)",
7
+ "Bash(python3:*)",
8
+ "Bash(conda run:*)",
9
+ "Bash(pip3 show:*)",
10
+ "Bash(echo \"BSA5sucQmeJ_iULMzVkGcmR8uX8NiYy==>your_brave_api_key\")",
11
+ "Read(//tmp/**)",
12
+ "Bash(ls -la /Users/bpistone/development/private/mnemoai/server/tools/*.py)",
13
+ "Bash(ls:*)",
14
+ "WebFetch(domain:docs.anthropic.com)",
15
+ "WebFetch(domain:python.langchain.com)",
16
+ "WebFetch(domain:docs.langchain.com)",
17
+ "WebFetch(domain:github.com)",
18
+ "Bash(pip show:*)",
19
+ "Bash(poetry show:*)",
20
+ "Bash(uv pip:*)",
21
+ "Bash(pip list:*)",
22
+ "Bash(source /Users/bpistone/development/private/mnemoai/.venv/bin/activate)",
23
+ "Bash(/Users/bpistone/miniconda3/envs/mnemoai/bin/pip list:*)",
24
+ "Bash(/Users/bpistone/miniconda3/envs/mnemoai/bin/pip index:*)",
25
+ "Bash(/Users/bpistone/miniconda3/envs/mnemoai/bin/python -c \"from langchain_aws import ChatBedrockConverse; print\\('available'\\)\" 2>&1)",
26
+ "Bash(/Users/bpistone/miniconda3/envs/mnemoai/bin/python -c \":*)",
27
+ "WebFetch(domain:en.wikipedia.org)",
28
+ "WebFetch(domain:www.elastic.co)",
29
+ "WebFetch(domain:kmwllc.com)",
30
+ "WebFetch(domain:www.anthropic.com)",
31
+ "Bash(echo \"exit: $? \\(no output above = no circular import risk\\)\")",
32
+ "Read(//Users/bpistone/development/private/**)",
33
+ "Bash(diff -q mnemoai/__TRACKED_VAR__ ai-assistant/__TRACKED_VAR__)",
34
+ "Bash(echo \"exit: $? \\(no output = no matches found anywhere in ~/.claude\\)\")",
35
+ "Bash(echo \"exit: $? \\(no output = none of these Mantle/custom-endpoint hooks exist in the app\\)\")",
36
+ "Bash(grep *)",
37
+ "Bash(cd /Users/bpistone/development/private)",
38
+ "Bash([ ! -e \"mnemoai/$f\" ])",
39
+ "Bash(echo 'REPO-MISSING __TRACKED_VAR__')",
40
+ "Bash([ ! -e \"ai-assistant/$f\" ])",
41
+ "Bash(echo 'RUNTIME-MISSING __TRACKED_VAR__')",
42
+ "Read(//private/tmp/_strands_check/**)",
43
+ "Bash(tar xzf *)",
44
+ "Bash(awk 'NR>=237 && /^[A-Z]/ && NR>237 {print NR\": \"$0; exit} NR>=237 && NR<=290 {last=NR}' personal-ast)",
45
+ "Bash(awk -F: '$1>237')",
46
+ "Bash(sed -n '186,256p' mnemoai/utils/config.yaml.example)",
47
+ "Bash(sed -n '215,221p' mnemoai-strands/utils/config.yaml.example)",
48
+ "WebFetch(domain:claude.ai)",
49
+ "Bash(cat)",
50
+ "Bash(echo \"exit code: $?\")",
51
+ "Bash(rm -f _reexec_test.py)",
52
+ "Bash(echo \"remote head: $\\(git ls-remote origin -h refs/heads/langgraph)",
53
+ "Bash(/Users/bpistone/miniconda3/envs/mnemoai/bin/python -c 'import langchain_aws,os;print\\(os.path.dirname\\(langchain_aws.__file__\\)\\)')",
54
+ "Bash(echo \"remote: $\\(git ls-remote origin -h refs/heads/langgraph)",
55
+ "WebFetch(domain:docs.litellm.ai)",
56
+ "Bash(awk '/^## / {if\\(name\\) print len, name; name=$0; len=0; next} {len+=length\\($0\\)+1} END {if\\(name\\) print len, name}' CLAUDE.md)",
57
+ "Bash(sed 's/[[:space:]]*$//' CLAUDE.md)",
58
+ "Bash(echo \"chars if trailing whitespace stripped: $\\(sed 's/[[:space:]]*$//' CLAUDE.md)",
59
+ "Bash(sed 's/ */ /g' CLAUDE.md)",
60
+ "Bash(echo \"if internal multi-spaces collapsed: $\\(sed 's/ */ /g' CLAUDE.md)",
61
+ "Bash(xargs dirname)",
62
+ "Bash(sed -n '1,16p' src/personal_ai_assistant/server/tools/tools_manager.py)",
63
+ "Bash(sed -n '1,16p' src/personal_ai_assistant/server/tools/readers/pdf_reader.py)",
64
+ "Bash(echo \"remote main: $\\(git ls-remote origin -h refs/heads/main)",
65
+ "Bash(gh auth *)",
66
+ "Bash(gh repo *)",
67
+ "Bash(awk '{print $2}')",
68
+ "Bash(cd *)",
69
+ "Bash(echo \"remote langgraph : $\\(git ls-remote origin -h refs/heads/langgraph)",
70
+ "Bash(PYTHONPATH=src python -c \"import ast; ast.parse\\(open\\('src/mnemoai/client/ui/chat_interface.py'\\).read\\(\\)\\); print\\('parses OK'\\)\")",
71
+ "Bash(echo \"remote dev : $\\(git ls-remote origin -h refs/heads/dev)",
72
+ "Bash(uvx ruff *)",
73
+ "Bash(echo \"remote dev: $\\(git ls-remote origin -h refs/heads/dev)",
74
+ "Bash(echo \"local : $\\(git rev-parse main\\) remote: $\\(git ls-remote origin -h refs/heads/main)",
75
+ "Bash(uvx git-filter-repo *)"
76
+ ]
77
+ }
78
+ }
@@ -0,0 +1,165 @@
1
+ # Configuration (contains API keys)
2
+ src/mnemoai/utils/config.yaml
3
+ utils/config.yaml
4
+
5
+ # IDE
6
+ .idea/
7
+ .vscode/
8
+
9
+ # Environments
10
+ .env
11
+ .venv
12
+ env/
13
+ venv/
14
+ ENV/
15
+ env.bak/
16
+ venv.bak/
17
+
18
+ # Logs
19
+ **/logs
20
+ *.log
21
+
22
+ # OS generated files
23
+ .DS_Store
24
+ .DS_Store?
25
+ ._*
26
+ .Spotlight-V100
27
+ .Trashes
28
+ ehthumbs.db
29
+ Thumbs.db
30
+
31
+ # Byte-compiled / optimized / DLL files
32
+ __pycache__/
33
+ *.py[cod]
34
+ *$py.class
35
+
36
+ # C extensions
37
+ *.so
38
+
39
+ # Distribution / packaging
40
+ .Python
41
+ build/
42
+ develop-eggs/
43
+ dist/
44
+ downloads/
45
+ eggs/
46
+ .eggs/
47
+ lib/
48
+ lib64/
49
+ parts/
50
+ sdist/
51
+ var/
52
+ wheels/
53
+ pip-wheel-metadata/
54
+ share/python-wheels/
55
+ *.egg-info/
56
+ .installed.cfg
57
+ *.egg
58
+ MANIFEST
59
+
60
+ # PyInstaller
61
+ # Usually these files are written by a python script from a template
62
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
63
+ *.manifest
64
+ *.spec
65
+
66
+ # Installer logs
67
+ pip-log.txt
68
+ pip-delete-this-directory.txt
69
+
70
+ # Unit test / coverage reports
71
+ htmlcov/
72
+ .tox/
73
+ .nox/
74
+ .coverage
75
+ .coverage.*
76
+ .cache
77
+ nosetests.xml
78
+ coverage.xml
79
+ *.cover
80
+ *.py,cover
81
+ .hypothesis/
82
+ .pytest_cache/
83
+
84
+ # Translations
85
+ *.mo
86
+ *.pot
87
+
88
+ # Django stuff:
89
+ *.log
90
+ local_settings.py
91
+ db.sqlite3
92
+ db.sqlite3-journal
93
+
94
+ # Flask stuff:
95
+ instance/
96
+ .webassets-cache
97
+
98
+ # Scrapy stuff:
99
+ .scrapy
100
+
101
+ # Sphinx documentation
102
+ docs/_build/
103
+
104
+ # PyBuilder
105
+ target/
106
+
107
+ # Jupyter Notebook
108
+ .ipynb_checkpoints
109
+
110
+ # IPython
111
+ profile_default/
112
+ ipython_config.py
113
+
114
+ # pyenv
115
+ .python-version
116
+
117
+ # pipenv
118
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
119
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
120
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
121
+ # install all needed dependencies.
122
+ #Pipfile.lock
123
+
124
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
125
+ __pypackages__/
126
+
127
+ # Celery stuff
128
+ celerybeat-schedule
129
+ celerybeat.pid
130
+
131
+ # SageMath parsed files
132
+ *.sage.py
133
+
134
+ # Spyder project settings
135
+ .spyderproject
136
+ .spyproject
137
+
138
+ # Rope project settings
139
+ .ropeproject
140
+
141
+ # mkdocs documentation
142
+ /site
143
+
144
+ # mypy
145
+ .mypy_cache/
146
+ .dmypy.json
147
+ dmypy.json
148
+
149
+ # Pyre type checker
150
+ .pyre/
151
+
152
+ */**/venv
153
+ */**/*.egg-info
154
+ */**/default.profraw
155
+
156
+ # Terraform files
157
+ */**/.terraform*
158
+
159
+ # Base data exclude
160
+ */**/cdk.*/
161
+
162
+ ./claude
163
+ ./**/claude
164
+ ./.claude
165
+ ./**/.claude
@@ -0,0 +1,199 @@
1
+ # CLAUDE.md
2
+
3
+ ## Project Overview
4
+
5
+ Local agentic AI assistant built on LangGraph + MCP (Model Context Protocol). The client spawns an MCP server as a subprocess, routes queries through a StateGraph (classify → orchestrate/call_model ↔ execute_tools), and persists episodic memory, learned strategies (ACE Playbook), and user profiles across sessions. Supports Ollama, AWS Bedrock, OpenAI, SageMaker, and LiteLLM as LLM providers.
6
+
7
+ ## Quick Commands
8
+
9
+ ```bash
10
+ # Run from a checkout (src layout: package under src/, run as a module)
11
+ PYTHONPATH=src python -m mnemoai # verbose (shows thinking)
12
+ PYTHONPATH=src python -m mnemoai --no-verbose
13
+
14
+ # Or install, then use the console command
15
+ uv tool install . # or: pip install -e .
16
+ mnemoai
17
+
18
+ # Install dependencies (checkout dev)
19
+ pip install -r requirements.txt
20
+
21
+ # System-wide access (symlink once)
22
+ chmod +x bash/system-command-app/mnemoai-wrapper.sh
23
+ ln -sf $(pwd)/bash/system-command-app/mnemoai-wrapper.sh /usr/local/bin/mnemoai
24
+ ```
25
+
26
+ ## Architecture
27
+
28
+ ```
29
+ main.py → ChatInterface → LangGraphClient.query()
30
+ → inject episodic memory context
31
+ → LangGraphAgent (StateGraph):
32
+ classifier → [route] → call_model ↔ execute_tools (MCP)
33
+ → [full] → orchestrator → worker loops → aggregator
34
+ → AgentConversationManager (summarize if over token limit)
35
+ → UserProfileManager (learn preferences)
36
+ → Reflector + PlaybookStore (learn from tool successes/failures)
37
+ ```
38
+
39
+ **Client-server split:** The MCP server (`server/server.py`) runs as a stdio subprocess. The client maintains a persistent connection via a background asyncio thread in `client/mcp_tool_wrapper.py`. All tool calls route through MCP protocol.
40
+
41
+ ## Directory Structure
42
+
43
+ **src layout:** the single package `mnemoai` lives under `src/`.
44
+ Paths below are relative to `src/mnemoai/` (e.g. `client/` is
45
+ `src/mnemoai/client/`). `main.py` is the package entry (`cli()`),
46
+ also runnable as `python -m mnemoai`. `tests/`, `docs/`, `bash/`
47
+ stay at the repo root.
48
+
49
+ | Directory | Role |
50
+ | ------------------------ | ------------------------------------------------------------------------- |
51
+ | `client/` | LangGraphClient facade, MCP bridge |
52
+ | `client/agent/` | Agent loop: StateGraph agent, query router, orchestrator, reasoning utils |
53
+ | `client/memory/` | Episodic memory (ChromaDB/FAISS), ACE Playbook, Reflector |
54
+ | `client/managers/` | Conversation token management, user profile learning |
55
+ | `client/ui/` | prompt_toolkit chat loop, spinner |
56
+ | `server/` | FastMCP server entry point (run as a subprocess) |
57
+ | `server/tools/` | Tool implementations (bash, file ops, git, web, RAG, vision, planning) |
58
+ | `server/tools/rag/` | Session-scoped vector store, hybrid search engine |
59
+ | `server/tools/readers/` | File format readers (PDF, DOCX, CSV, JSON, directory, line, search) |
60
+ | `models/` | `provider_params` registry + `mantle_factory` |
61
+ | `models/controllers/` | Provider-dispatching LLM/vision/embeddings controllers |
62
+ | `models/chat_models/` | Concrete LangChain ChatModel subclasses (ChatOllamaWrapper, ChatSageMaker)|
63
+ | `utils/` | Config singleton, configurator, paths, logger, BM25, text formatting |
64
+ | `bash/` (repo root) | Shell scripts (system command wrapper, Ollama VRAM management) |
65
+
66
+ ## Detailed File Map
67
+
68
+ The full per-file reference (every module, its key classes/functions, and
69
+ what it does) lives in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) to keep
70
+ this file lean. Consult it when you need to locate or understand a specific
71
+ file; the sections below cover the high-level architecture and conventions.
72
+
73
+ ## Key Patterns
74
+
75
+ ### Config singleton (`utils/config.py`)
76
+
77
+ All configuration flows through `Config()` which loads `utils/config.yaml` (gitignored). Access via `Config().get("SECTION.KEY", default)`. The `.system_prompt` property injects the current date.
78
+
79
+ ### MCP tool registration (`server/tools/tools_manager.py`)
80
+
81
+ `ToolManager.register_tools(mcp)` conditionally registers tool groups based on config toggles. Each tool file defines functions decorated with `@mcp.tool()`.
82
+
83
+ ### Hybrid search (semantic + BM25)
84
+
85
+ Used in both episodic memory and RAG. Pattern: get top-N candidates from vector store, get top-N from BM25, merge with configurable weights (`utils/bm25.py`).
86
+
87
+ ### Multi-provider LLM abstraction (`models/controllers/llm_controller.py`)
88
+
89
+ `LangChainLLMController.initialize_model()` dispatches on `MODEL_ID.TYPE` (bedrock/mantle/ollama/openai/sagemaker/litellm). Each provider's supported config keys / client-kwarg mapping live in `models/provider_params.py` (consumed via `build_kwargs`).
90
+
91
+ ### Bedrock Mantle (`models/mantle_factory.py`)
92
+
93
+ `TYPE: mantle` reaches AWS Bedrock Mantle via a bearer token minted from standard AWS (SigV4) credentials. `API_PROTOCOL` selects the wire protocol: `chat_completions` (OpenAI `/v1`), `responses` (OpenAI Responses `/openai/v1`, e.g. GPT-5.4), `anthropic` (Anthropic Messages `/anthropic`, Claude). The factory is shared by the LLM and vision controllers. Model availability varies by region (e.g. GPT-5.4 is in us-west-2).
94
+
95
+ ### Conversation compaction (`client/managers/agent_conversation_manager.py`)
96
+
97
+ Keeps the conversation under `MAX_CONVERSATION_TOKENS` by summarizing older messages into the system prompt while keeping recent turns verbatim. Triggers automatically when over budget, or manually via `/compact`. The kept window is bounded by message count AND a token budget so an oversized recent message (e.g. a pasted document) is summarized, not kept. Tool calls/results are preserved in the summary.
98
+
99
+ ### Query routing (`client/agent/router.py`)
100
+
101
+ `QueryRouter.classify()` uses the LLM to categorize queries. Routes map to tool subsets in `ROUTE_TOOLS` dict — only relevant tools are bound per query.
102
+
103
+ ### Orchestrator-workers (`client/agent/orchestrator.py`, `client/agent/agent.py`)
104
+
105
+ For "full" complexity tasks: decompose → parse subtasks (JSON) → run worker loop per subtask with category-specific tools → aggregate results.
106
+
107
+ ### ACE Playbook learning (`client/memory/reflector.py`, `client/memory/playbook_store.py`)
108
+
109
+ After each interaction, the Reflector analyzes tool execution trajectories, detects failure patterns, and extracts reusable strategies stored in the PlaybookStore. Relevant strategies are injected into the system prompt for future queries.
110
+
111
+ ### Episodic memory (`client/memory/episodic_memory.py`)
112
+
113
+ Stores successful task completions with tool usage patterns. Retrieved via hybrid search before each query and injected as context.
114
+
115
+ ## Configuration
116
+
117
+ `utils/config.yaml` (gitignored). Copy from one of the provided templates:
118
+ `utils/config.yaml.example` (Ollama/local), `utils/config.yaml.bedrock.example` (standard Bedrock), or `utils/config.yaml.bedrock.mantle.example` (Bedrock Mantle). Each is a complete drop-in config for that provider — keep them in sync when adding shared config keys.
119
+
120
+ | Section | Purpose |
121
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
122
+ | `MODEL_ID` | LLM provider/`TYPE` (bedrock, mantle, ollama, openai, sagemaker, litellm), model name, inference params. Mantle adds `API_PROTOCOL` (chat_completions/responses/anthropic) and optional `ENDPOINT_URL`. |
123
+ | `VISION_MODEL_ID` | Vision model for image description (same provider types as `MODEL_ID`) |
124
+ | `RAG` | Embedding model, chunk size, hybrid weights, vector store type |
125
+ | `EPISODIC_MEMORY` | Thresholds, search weights, success/error markers |
126
+ | `PLAYBOOK` | Max entries, similarity threshold, injection limit |
127
+ | `LLM` | Retry config, thinking toggle, agent `RECURSION_LIMIT`, `MCP_CALL_TIMEOUT`, and compaction (`KEEP_RECENT_MESSAGES`, `MANUAL_COMPACT_KEEP_RECENT`, `KEEP_RECENT_TOKEN_BUDGET`) |
128
+ | `PROFILE` | User name (data isolation), profiling toggle |
129
+ | `BRAVE_API_KEY` | Web search API key |
130
+ | `SYSTEM_PROMPT` | Full system prompt (XML-structured) |
131
+ | `ROUTING_PROMPT` | Query classifier prompt |
132
+ | `ORCHESTRATOR_PROMPT` | Task decomposition prompt |
133
+ | `AGGREGATOR_PROMPT` | Result synthesis prompt |
134
+
135
+ **Feature toggles** (all boolean in config root):
136
+ `ENABLE_RAG`, `ENABLE_EPISODIC_MEMORY`, `ENABLE_PLAYBOOK`, `ENABLE_WEB_SEARCH`, `ENABLE_WEB_CRAWL`, `ENABLE_ROUTING`, `ENABLE_ORCHESTRATION`
137
+
138
+ **Environment variables:**
139
+
140
+ - `OPENAI_API_KEY` — for OpenAI provider
141
+ - `LOG_LEVEL` — logging verbosity (default: INFO)
142
+ - AWS credentials via `aws configure` for Bedrock/SageMaker/Mantle (Mantle mints a bearer token from these via `aws-bedrock-token-generator`)
143
+ - Config `ENV` section sets additional env vars at startup
144
+
145
+ **Runtime data:** All state lives under a single app home, `~/.mnemoai/` (override with `$MNEMOAI_HOME`), resolved centrally in `utils/paths.py`. Layout: `config.yaml`, `plans/`, `tasks/`, and per-profile `{profile_name}/` (conversations, todos, RAG indexes, chunk caches, user profile). **Episodic memory and the ACE playbook are model-scoped** under `{profile_name}/models/{sanitized_model_name}/` so switching the chat model doesn't contaminate memory built with a different one. All path construction goes through `utils/paths.py` (`app_home`, `config_path`, `plans_dir`, `tasks_dir`, `profile_dir`, `model_dir`).
146
+
147
+ ## Code Conventions
148
+
149
+ - **Tests** — pytest unit suite in `tests/` covers pure-logic modules (no LLM/Ollama needed). Run with `python -m pytest`. See the Testing section below
150
+ - **Error handling in tools** — `@tool_error_handler` decorator (`server/error_handler.py`) for standardized responses
151
+ - **Async/sync bridge** — MCP client uses a background thread with `asyncio.new_event_loop()` in `client/mcp_tool_wrapper.py`; sync callers use `run_coroutine_threadsafe`
152
+ - **Imports** — relative within packages, absolute across packages
153
+ - **Type hints** — used for LangChain/LangGraph state schemas (`TypedDict`), model classes; not enforced everywhere
154
+ - **Naming** — snake_case functions/variables, PascalCase classes, UPPER_CASE config keys
155
+ - **File I/O** — JSON for persistence (playbook, todos, profile, episodic metadata), SQLite for chunk cache
156
+ - **Token counting** — tiktoken for OpenAI/Bedrock, character-based approximation (÷4) for Ollama
157
+
158
+ ## Testing
159
+
160
+ ```bash
161
+ pip install -r requirements-dev.txt # installs pytest
162
+ python -m pytest # everything (integration auto-skips)
163
+ python -m pytest tests/unit # unit tier only
164
+ python -m pytest tests/unit/test_bm25.py # run one file
165
+ python -m pytest -m integration # integration tier (needs Ollama + config.yaml)
166
+ python -m pytest -m "not integration" # explicitly exclude integration
167
+ ```
168
+
169
+ - Layout: `tests/unit/` (pure-logic) and `tests/integration/` (live agent). Configured via `pytest.ini` (testpaths=tests). `tests/conftest.py` puts the repo root on `sys.path` so `utils`/`client`/`server` import cleanly.
170
+ - **Unit tier (default):** deterministic, pure-logic tests — no LLM, Ollama, or network needed, runs in seconds. Covers `utils/bm25.py`, `client/agent/reasoning_utils.py`, `utils/formatting/` (response_parser, url_formatter, code_formatter), `client/agent/orchestrator.parse_subtasks`, `server/error_handler.py`, `server/tools/git_safety.py` (command-danger classification), `server/tools/file_edit.py` + `glob_search`, `execute_bash` timeout/process-group behavior, `client/memory/episodic_memory` heuristics, Bedrock/Mantle model wiring (`test_bedrock_endpoint.py`), vision content normalization (`test_vision_content.py`), and conversation compaction incl. token-aware retention (`test_conversation_compaction.py`).
171
+ - Unit tests must not require a `config.yaml` — modules degrade gracefully without one. Keep import-time side effects config-independent so new code stays unit-testable.
172
+ - **Integration tier (`tests/integration/`, marked `@pytest.mark.integration`):** drives the real `LangGraphClient` + Ollama + MCP subprocess (greeting/routing, tool calls, bash timeout, no-silent-empty-turn). Auto-skipped unless a runtime `config.yaml` exists AND the configured Ollama host is reachable (see `tests/integration/conftest.py`). The shared client is session-scoped; an autouse fixture calls `clear_context()` between tests for isolation.
173
+
174
+ ## Adding a New MCP Tool
175
+
176
+ 1. Create `server/tools/my_tool.py`
177
+ 2. Define function with `@mcp.tool()` decorator (receives `mcp` from registration)
178
+ 3. Add `@tool_error_handler` for standardized error responses
179
+ 4. Register in `server/tools/tools_manager.py` → `register_tools()` method
180
+ 5. If conditionally enabled, gate behind a config toggle
181
+ 6. Add route mapping in `client/agent/router.py` → `ROUTE_TOOLS` if it belongs to a specific category
182
+
183
+ ## Adding a New LLM Provider
184
+
185
+ 1. Add provider case in `models/controllers/llm_controller.py` → `initialize_model()`
186
+ 2. Register the provider's supported config keys in `models/provider_params.py` (the registry consumed via `build_kwargs` and used by `/model` pruning)
187
+ 3. If custom LangChain model needed, create class in `models/chat_models/`
188
+ 4. Add embedding support in `models/controllers/embeddings_controller.py` if provider offers embeddings
189
+ 5. Add vision support in `models/controllers/vision_model_controller.py` if applicable
190
+ 6. Document config structure in all `utils/config.yaml*.example` templates
191
+
192
+ ## Known Limitations
193
+
194
+ - Unit tests cover pure logic only — agent/LLM integration paths still need manual verification
195
+ - MCP server is a subprocess — debugging requires attaching to child process or reading logs
196
+ - No Docker/containerization — runs directly on host with system Python/conda/venv
197
+ - No database — all persistence is file-based (JSON, FAISS index files, SQLite chunk cache)
198
+ - Single-user — profile name in config isolates data but no auth/multi-tenancy
199
+ - `ripgrep` (rg) required for `grep_search` tool — install separately
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bruno Pistone
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.