claude-mpm 4.7.4__py3-none-any.whl → 4.18.2__py3-none-any.whl

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 (308) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  4. claude_mpm/agents/BASE_PM.md +106 -1
  5. claude_mpm/agents/OUTPUT_STYLE.md +329 -11
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
  7. claude_mpm/agents/agent_loader.py +17 -5
  8. claude_mpm/agents/frontmatter_validator.py +284 -253
  9. claude_mpm/agents/templates/README.md +465 -0
  10. claude_mpm/agents/templates/agent-manager.json +4 -1
  11. claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
  12. claude_mpm/agents/templates/api_qa.json +11 -2
  13. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  14. claude_mpm/agents/templates/clerk-ops.json +12 -2
  15. claude_mpm/agents/templates/code_analyzer.json +8 -2
  16. claude_mpm/agents/templates/content-agent.json +358 -0
  17. claude_mpm/agents/templates/dart_engineer.json +15 -2
  18. claude_mpm/agents/templates/data_engineer.json +15 -2
  19. claude_mpm/agents/templates/documentation.json +10 -2
  20. claude_mpm/agents/templates/engineer.json +21 -1
  21. claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
  22. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  23. claude_mpm/agents/templates/golang_engineer.json +270 -0
  24. claude_mpm/agents/templates/imagemagick.json +4 -1
  25. claude_mpm/agents/templates/java_engineer.json +346 -0
  26. claude_mpm/agents/templates/local_ops_agent.json +1227 -6
  27. claude_mpm/agents/templates/memory_manager.json +4 -1
  28. claude_mpm/agents/templates/nextjs_engineer.json +141 -133
  29. claude_mpm/agents/templates/ops.json +12 -2
  30. claude_mpm/agents/templates/php-engineer.json +270 -174
  31. claude_mpm/agents/templates/pm_examples.md +474 -0
  32. claude_mpm/agents/templates/pm_red_flags.md +240 -0
  33. claude_mpm/agents/templates/product_owner.json +338 -0
  34. claude_mpm/agents/templates/project_organizer.json +14 -4
  35. claude_mpm/agents/templates/prompt-engineer.json +13 -2
  36. claude_mpm/agents/templates/python_engineer.json +174 -81
  37. claude_mpm/agents/templates/qa.json +11 -2
  38. claude_mpm/agents/templates/react_engineer.json +16 -3
  39. claude_mpm/agents/templates/refactoring_engineer.json +12 -2
  40. claude_mpm/agents/templates/research.json +34 -21
  41. claude_mpm/agents/templates/response_format.md +583 -0
  42. claude_mpm/agents/templates/ruby-engineer.json +129 -192
  43. claude_mpm/agents/templates/rust_engineer.json +270 -0
  44. claude_mpm/agents/templates/security.json +10 -2
  45. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  46. claude_mpm/agents/templates/ticketing.json +10 -2
  47. claude_mpm/agents/templates/typescript_engineer.json +116 -125
  48. claude_mpm/agents/templates/validation_templates.md +312 -0
  49. claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
  50. claude_mpm/agents/templates/version_control.json +12 -2
  51. claude_mpm/agents/templates/web_qa.json +11 -2
  52. claude_mpm/agents/templates/web_ui.json +15 -2
  53. claude_mpm/cli/__init__.py +34 -614
  54. claude_mpm/cli/commands/agent_manager.py +25 -12
  55. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  56. claude_mpm/cli/commands/agents.py +235 -148
  57. claude_mpm/cli/commands/agents_detect.py +380 -0
  58. claude_mpm/cli/commands/agents_recommend.py +309 -0
  59. claude_mpm/cli/commands/aggregate.py +7 -3
  60. claude_mpm/cli/commands/analyze.py +9 -4
  61. claude_mpm/cli/commands/analyze_code.py +7 -2
  62. claude_mpm/cli/commands/auto_configure.py +570 -0
  63. claude_mpm/cli/commands/config.py +47 -13
  64. claude_mpm/cli/commands/configure.py +419 -1571
  65. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  66. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  67. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  68. claude_mpm/cli/commands/configure_models.py +18 -0
  69. claude_mpm/cli/commands/configure_navigation.py +167 -0
  70. claude_mpm/cli/commands/configure_paths.py +104 -0
  71. claude_mpm/cli/commands/configure_persistence.py +254 -0
  72. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  73. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  74. claude_mpm/cli/commands/configure_validators.py +73 -0
  75. claude_mpm/cli/commands/local_deploy.py +537 -0
  76. claude_mpm/cli/commands/memory.py +54 -20
  77. claude_mpm/cli/commands/mpm_init.py +585 -196
  78. claude_mpm/cli/commands/mpm_init_handler.py +37 -3
  79. claude_mpm/cli/commands/search.py +170 -4
  80. claude_mpm/cli/commands/upgrade.py +152 -0
  81. claude_mpm/cli/executor.py +202 -0
  82. claude_mpm/cli/helpers.py +105 -0
  83. claude_mpm/cli/interactive/__init__.py +3 -0
  84. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  85. claude_mpm/cli/parsers/__init__.py +7 -1
  86. claude_mpm/cli/parsers/agents_parser.py +9 -0
  87. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  88. claude_mpm/cli/parsers/base_parser.py +110 -3
  89. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  90. claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
  91. claude_mpm/cli/shared/output_formatters.py +28 -19
  92. claude_mpm/cli/startup.py +481 -0
  93. claude_mpm/cli/utils.py +52 -1
  94. claude_mpm/commands/mpm-agents-detect.md +168 -0
  95. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  96. claude_mpm/commands/mpm-agents.md +75 -1
  97. claude_mpm/commands/mpm-auto-configure.md +217 -0
  98. claude_mpm/commands/mpm-help.md +163 -0
  99. claude_mpm/commands/mpm-init.md +148 -3
  100. claude_mpm/commands/mpm-version.md +113 -0
  101. claude_mpm/commands/mpm.md +1 -0
  102. claude_mpm/config/agent_config.py +2 -2
  103. claude_mpm/config/model_config.py +428 -0
  104. claude_mpm/constants.py +1 -0
  105. claude_mpm/core/base_service.py +13 -12
  106. claude_mpm/core/enums.py +452 -0
  107. claude_mpm/core/factories.py +1 -1
  108. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  109. claude_mpm/core/interactive_session.py +9 -3
  110. claude_mpm/core/log_manager.py +2 -0
  111. claude_mpm/core/logging_config.py +6 -2
  112. claude_mpm/core/oneshot_session.py +8 -4
  113. claude_mpm/core/optimized_agent_loader.py +3 -3
  114. claude_mpm/core/output_style_manager.py +12 -192
  115. claude_mpm/core/service_registry.py +5 -1
  116. claude_mpm/core/types.py +2 -9
  117. claude_mpm/core/typing_utils.py +7 -6
  118. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  119. claude_mpm/dashboard/templates/index.html +3 -41
  120. claude_mpm/hooks/__init__.py +20 -0
  121. claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
  122. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  123. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
  124. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  125. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  126. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  127. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  128. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  129. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  130. claude_mpm/hooks/kuzu_memory_hook.py +37 -12
  131. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  132. claude_mpm/models/resume_log.py +340 -0
  133. claude_mpm/services/agents/__init__.py +18 -5
  134. claude_mpm/services/agents/auto_config_manager.py +796 -0
  135. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  136. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  137. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  138. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  139. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  140. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  141. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
  142. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  143. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  144. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
  145. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  146. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  147. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  148. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  149. claude_mpm/services/agents/local_template_manager.py +1 -1
  150. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  151. claude_mpm/services/agents/observers.py +547 -0
  152. claude_mpm/services/agents/recommender.py +568 -0
  153. claude_mpm/services/agents/registry/modification_tracker.py +5 -2
  154. claude_mpm/services/command_handler_service.py +11 -5
  155. claude_mpm/services/core/__init__.py +33 -1
  156. claude_mpm/services/core/interfaces/__init__.py +90 -3
  157. claude_mpm/services/core/interfaces/agent.py +184 -0
  158. claude_mpm/services/core/interfaces/health.py +172 -0
  159. claude_mpm/services/core/interfaces/model.py +281 -0
  160. claude_mpm/services/core/interfaces/process.py +372 -0
  161. claude_mpm/services/core/interfaces/project.py +121 -0
  162. claude_mpm/services/core/interfaces/restart.py +307 -0
  163. claude_mpm/services/core/interfaces/stability.py +260 -0
  164. claude_mpm/services/core/memory_manager.py +11 -24
  165. claude_mpm/services/core/models/__init__.py +79 -0
  166. claude_mpm/services/core/models/agent_config.py +381 -0
  167. claude_mpm/services/core/models/health.py +162 -0
  168. claude_mpm/services/core/models/process.py +235 -0
  169. claude_mpm/services/core/models/restart.py +302 -0
  170. claude_mpm/services/core/models/stability.py +264 -0
  171. claude_mpm/services/core/models/toolchain.py +306 -0
  172. claude_mpm/services/core/path_resolver.py +23 -7
  173. claude_mpm/services/diagnostics/__init__.py +2 -2
  174. claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
  175. claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
  176. claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
  177. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
  178. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  179. claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
  180. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  181. claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
  182. claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
  183. claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
  184. claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
  185. claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
  186. claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
  187. claude_mpm/services/diagnostics/models.py +19 -24
  188. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  189. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  190. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  191. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  192. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  193. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  194. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  195. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  196. claude_mpm/services/local_ops/__init__.py +163 -0
  197. claude_mpm/services/local_ops/crash_detector.py +257 -0
  198. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  199. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  200. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  201. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  202. claude_mpm/services/local_ops/health_manager.py +430 -0
  203. claude_mpm/services/local_ops/log_monitor.py +396 -0
  204. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  205. claude_mpm/services/local_ops/process_manager.py +595 -0
  206. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  207. claude_mpm/services/local_ops/restart_manager.py +401 -0
  208. claude_mpm/services/local_ops/restart_policy.py +387 -0
  209. claude_mpm/services/local_ops/state_manager.py +372 -0
  210. claude_mpm/services/local_ops/unified_manager.py +600 -0
  211. claude_mpm/services/mcp_config_manager.py +9 -4
  212. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  213. claude_mpm/services/mcp_gateway/core/base.py +18 -31
  214. claude_mpm/services/mcp_gateway/main.py +30 -0
  215. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
  216. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
  217. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
  218. claude_mpm/services/mcp_service_verifier.py +1 -1
  219. claude_mpm/services/memory/failure_tracker.py +563 -0
  220. claude_mpm/services/memory_hook_service.py +165 -4
  221. claude_mpm/services/model/__init__.py +147 -0
  222. claude_mpm/services/model/base_provider.py +365 -0
  223. claude_mpm/services/model/claude_provider.py +412 -0
  224. claude_mpm/services/model/model_router.py +453 -0
  225. claude_mpm/services/model/ollama_provider.py +415 -0
  226. claude_mpm/services/monitor/daemon_manager.py +3 -2
  227. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  228. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  229. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  230. claude_mpm/services/monitor/server.py +2 -1
  231. claude_mpm/services/project/__init__.py +23 -0
  232. claude_mpm/services/project/detection_strategies.py +719 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  234. claude_mpm/services/self_upgrade_service.py +342 -0
  235. claude_mpm/services/session_management_service.py +3 -2
  236. claude_mpm/services/session_manager.py +205 -1
  237. claude_mpm/services/shared/async_service_base.py +16 -27
  238. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  239. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  240. claude_mpm/services/socketio/handlers/hook.py +13 -2
  241. claude_mpm/services/socketio/handlers/registry.py +4 -2
  242. claude_mpm/services/socketio/server/main.py +10 -8
  243. claude_mpm/services/subprocess_launcher_service.py +14 -5
  244. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
  245. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  246. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  247. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
  248. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  249. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  250. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  251. claude_mpm/services/unified/deployment_strategies/local.py +6 -5
  252. claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
  253. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
  254. claude_mpm/services/unified/interfaces.py +3 -1
  255. claude_mpm/services/unified/unified_analyzer.py +14 -10
  256. claude_mpm/services/unified/unified_config.py +2 -1
  257. claude_mpm/services/unified/unified_deployment.py +9 -4
  258. claude_mpm/services/version_service.py +104 -1
  259. claude_mpm/skills/__init__.py +21 -0
  260. claude_mpm/skills/bundled/__init__.py +6 -0
  261. claude_mpm/skills/bundled/api-documentation.md +393 -0
  262. claude_mpm/skills/bundled/async-testing.md +571 -0
  263. claude_mpm/skills/bundled/code-review.md +143 -0
  264. claude_mpm/skills/bundled/database-migration.md +199 -0
  265. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  266. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  267. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  268. claude_mpm/skills/bundled/git-workflow.md +414 -0
  269. claude_mpm/skills/bundled/imagemagick.md +204 -0
  270. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  271. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  272. claude_mpm/skills/bundled/pdf.md +141 -0
  273. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  274. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  275. claude_mpm/skills/bundled/security-scanning.md +327 -0
  276. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  277. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  278. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  279. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  280. claude_mpm/skills/bundled/xlsx.md +157 -0
  281. claude_mpm/skills/registry.py +286 -0
  282. claude_mpm/skills/skill_manager.py +310 -0
  283. claude_mpm/storage/state_storage.py +15 -15
  284. claude_mpm/tools/code_tree_analyzer.py +177 -141
  285. claude_mpm/tools/code_tree_events.py +4 -2
  286. claude_mpm/utils/agent_dependency_loader.py +40 -20
  287. claude_mpm/utils/display_helper.py +260 -0
  288. claude_mpm/utils/git_analyzer.py +407 -0
  289. claude_mpm/utils/robust_installer.py +73 -19
  290. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
  291. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
  292. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  293. claude_mpm/dashboard/static/index-hub-backup.html +0 -713
  294. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  295. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  296. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  297. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  298. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  299. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  300. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  301. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  302. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  303. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  304. claude_mpm/services/project/analyzer_refactored.py +0 -450
  305. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
  306. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
  307. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
  308. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
@@ -11,6 +11,7 @@ Extracted from ClaudeRunner to follow Single Responsibility Principle.
11
11
  from typing import Any, Dict
12
12
 
13
13
  from claude_mpm.core.base_service import BaseService
14
+ from claude_mpm.core.enums import ServiceState
14
15
  from claude_mpm.services.core.interfaces import MemoryHookInterface
15
16
 
16
17
 
@@ -41,8 +42,8 @@ class MemoryHookService(BaseService, MemoryHookInterface):
41
42
  These hooks ensure memory is properly managed and persisted.
42
43
 
43
44
  DESIGN DECISION: We register hooks for key lifecycle events:
44
- - Before Claude interaction: Load relevant memories
45
- - After Claude interaction: Save new memories
45
+ - Before Claude interaction: Load relevant memories (kuzu-memory + legacy)
46
+ - After Claude interaction: Save new memories (kuzu-memory + legacy)
46
47
  - On error: Ensure memory state is preserved
47
48
  """
48
49
  if not self.hook_service:
@@ -90,11 +91,169 @@ class MemoryHookService(BaseService, MemoryHookInterface):
90
91
  if success2:
91
92
  self.registered_hooks.append("memory_save")
92
93
 
93
- self.logger.debug("Memory hooks registered successfully")
94
+ self.logger.debug("Legacy memory hooks registered successfully")
95
+
96
+ # Register kuzu-memory hooks if available
97
+ self._register_kuzu_memory_hooks()
98
+
99
+ # Register failure-learning hooks
100
+ self._register_failure_learning_hooks()
94
101
 
95
102
  except Exception as e:
96
103
  self.logger.warning(f"Failed to register memory hooks: {e}")
97
104
 
105
+ def _register_kuzu_memory_hooks(self):
106
+ """Register kuzu-memory bidirectional enrichment hooks.
107
+
108
+ WHY: Kuzu-memory provides persistent knowledge graph storage that works
109
+ across conversations. This enables:
110
+ 1. Delegation context enrichment with relevant memories (READ)
111
+ 2. Automatic learning extraction from responses (WRITE)
112
+
113
+ DESIGN DECISION: These hooks are separate from legacy memory hooks to
114
+ allow independent evolution and configuration. Both systems can coexist.
115
+ """
116
+ try:
117
+ # Check if kuzu-memory is enabled in config
118
+ from claude_mpm.core.config import Config
119
+
120
+ config = Config()
121
+ kuzu_config = config.get("memory.kuzu", {})
122
+ if isinstance(kuzu_config, dict):
123
+ kuzu_enabled = kuzu_config.get("enabled", True)
124
+ enrichment_enabled = kuzu_config.get("enrichment", True)
125
+ learning_enabled = kuzu_config.get("learning", True)
126
+ else:
127
+ # Default to enabled if config section doesn't exist
128
+ kuzu_enabled = True
129
+ enrichment_enabled = True
130
+ learning_enabled = True
131
+
132
+ if not kuzu_enabled:
133
+ self.logger.debug("Kuzu-memory disabled in configuration")
134
+ return
135
+
136
+ from claude_mpm.hooks import (
137
+ get_kuzu_enrichment_hook,
138
+ get_kuzu_response_hook,
139
+ )
140
+
141
+ # Get kuzu-memory hooks
142
+ enrichment_hook = get_kuzu_enrichment_hook()
143
+ learning_hook = get_kuzu_response_hook()
144
+
145
+ # Register enrichment hook (PreDelegationHook) if enabled
146
+ if enrichment_hook.enabled and enrichment_enabled:
147
+ success = self.hook_service.register_hook(enrichment_hook)
148
+ if success:
149
+ self.registered_hooks.append("kuzu_memory_enrichment")
150
+ self.logger.info(
151
+ "✅ Kuzu-memory enrichment enabled (prompts → memories)"
152
+ )
153
+ else:
154
+ self.logger.warning(
155
+ "Failed to register kuzu-memory enrichment hook"
156
+ )
157
+ elif not enrichment_enabled:
158
+ self.logger.debug("Kuzu-memory enrichment disabled in configuration")
159
+
160
+ # Register learning hook (PostDelegationHook) if enabled
161
+ if learning_hook.enabled and learning_enabled:
162
+ success = self.hook_service.register_hook(learning_hook)
163
+ if success:
164
+ self.registered_hooks.append("kuzu_response_learner")
165
+ self.logger.info(
166
+ "✅ Kuzu-memory learning enabled (responses → memories)"
167
+ )
168
+ else:
169
+ self.logger.warning("Failed to register kuzu-memory learning hook")
170
+ elif not learning_enabled:
171
+ self.logger.debug("Kuzu-memory learning disabled in configuration")
172
+
173
+ # If neither hook is enabled, kuzu-memory is not available
174
+ if not enrichment_hook.enabled and not learning_hook.enabled:
175
+ self.logger.debug(
176
+ "Kuzu-memory not available. Install with: pipx install kuzu-memory"
177
+ )
178
+
179
+ except ImportError as e:
180
+ self.logger.debug(f"Kuzu-memory hooks not available: {e}")
181
+ except Exception as e:
182
+ self.logger.warning(f"Failed to register kuzu-memory hooks: {e}")
183
+
184
+ def _register_failure_learning_hooks(self):
185
+ """Register failure-learning hooks for automatic learning extraction.
186
+
187
+ WHY: When tasks fail and agents fix them, we want to automatically capture
188
+ this as a learning. The failure-learning system provides:
189
+ 1. Failure detection from tool outputs (errors, exceptions, test failures)
190
+ 2. Fix detection when same task type succeeds after failure
191
+ 3. Learning extraction and persistence to agent memory files
192
+
193
+ DESIGN DECISION: These hooks work as a chain with specific priorities:
194
+ - FailureDetectionHook (priority=85): Detects failures after tool execution
195
+ - FixDetectionHook (priority=87): Matches fixes with failures
196
+ - LearningExtractionHook (priority=89): Extracts and persists learnings
197
+
198
+ The system is enabled by default but can be disabled via configuration.
199
+ """
200
+ try:
201
+ # Check if failure-learning is enabled in config
202
+ from claude_mpm.core.config import Config
203
+
204
+ config = Config()
205
+ failure_learning_config = config.get("memory.failure_learning", {})
206
+
207
+ if isinstance(failure_learning_config, dict):
208
+ enabled = failure_learning_config.get("enabled", True)
209
+ else:
210
+ # Default to enabled if config section doesn't exist
211
+ enabled = True
212
+
213
+ if not enabled:
214
+ self.logger.debug("Failure-learning disabled in configuration")
215
+ return
216
+
217
+ # Import failure-learning hooks
218
+ from claude_mpm.hooks.failure_learning import (
219
+ get_failure_detection_hook,
220
+ get_fix_detection_hook,
221
+ get_learning_extraction_hook,
222
+ )
223
+
224
+ # Get hook instances
225
+ failure_hook = get_failure_detection_hook()
226
+ fix_hook = get_fix_detection_hook()
227
+ learning_hook = get_learning_extraction_hook()
228
+
229
+ # Register hooks in priority order
230
+ success1 = self.hook_service.register_hook(failure_hook)
231
+ success2 = self.hook_service.register_hook(fix_hook)
232
+ success3 = self.hook_service.register_hook(learning_hook)
233
+
234
+ if success1:
235
+ self.registered_hooks.append("failure_detection")
236
+ self.logger.debug("✅ Failure detection enabled")
237
+
238
+ if success2:
239
+ self.registered_hooks.append("fix_detection")
240
+ self.logger.debug("✅ Fix detection enabled")
241
+
242
+ if success3:
243
+ self.registered_hooks.append("learning_extraction")
244
+ self.logger.debug("✅ Learning extraction enabled")
245
+
246
+ if success1 and success2 and success3:
247
+ self.logger.info(
248
+ "✅ Failure-learning system enabled "
249
+ "(failures → fixes → learnings → memory)"
250
+ )
251
+
252
+ except ImportError as e:
253
+ self.logger.debug(f"Failure-learning hooks not available: {e}")
254
+ except Exception as e:
255
+ self.logger.warning(f"Failed to register failure-learning hooks: {e}")
256
+
98
257
  def _load_relevant_memories_hook(self, context):
99
258
  """Hook function to load relevant memories before Claude interaction.
100
259
 
@@ -305,5 +464,7 @@ class MemoryHookService(BaseService, MemoryHookInterface):
305
464
  "hook_service_available": self.hook_service is not None,
306
465
  "memory_enabled": self.is_memory_enabled(),
307
466
  "total_hooks": len(self.registered_hooks),
308
- "status": "active" if self.registered_hooks else "inactive",
467
+ "status": (
468
+ ServiceState.RUNNING if self.registered_hooks else ServiceState.IDLE
469
+ ),
309
470
  }
@@ -0,0 +1,147 @@
1
+ """
2
+ Model Services Package for Claude MPM Framework
3
+ ================================================
4
+
5
+ WHY: Provides hybrid local/cloud content processing with intelligent routing
6
+ and automatic fallback. Enables privacy-preserving local model execution via
7
+ Ollama with cloud fallback to Claude for reliability.
8
+
9
+ ARCHITECTURE:
10
+ - Interfaces: Core contracts for model providers and routing (IModelProvider, IModelRouter)
11
+ - Base Provider: Common functionality for all providers (BaseModelProvider)
12
+ - Providers: Ollama (local) and Claude (cloud) implementations
13
+ - Router: Intelligent routing with fallback logic (ModelRouter)
14
+ - Configuration: Centralized config management (model_config.py)
15
+
16
+ USAGE:
17
+
18
+ Basic Usage with Auto-Routing:
19
+ ```python
20
+ from claude_mpm.services.model import ModelRouter
21
+ from claude_mpm.services.core.interfaces.model import ModelCapability
22
+
23
+ # Create router with default config (auto mode)
24
+ router = ModelRouter()
25
+ await router.initialize()
26
+
27
+ # Analyze content (tries Ollama first, falls back to Claude)
28
+ response = await router.analyze_content(
29
+ content="Your article text here...",
30
+ task=ModelCapability.SEO_ANALYSIS
31
+ )
32
+
33
+ if response.success:
34
+ print(f"Analysis by {response.provider}:")
35
+ print(response.result)
36
+ ```
37
+
38
+ Direct Provider Usage:
39
+ ```python
40
+ from claude_mpm.services.model import OllamaProvider
41
+
42
+ # Use Ollama directly
43
+ provider = OllamaProvider(config={
44
+ "host": "http://localhost:11434"
45
+ })
46
+
47
+ if await provider.is_available():
48
+ response = await provider.analyze_content(
49
+ content="Text to analyze",
50
+ task=ModelCapability.READABILITY
51
+ )
52
+ ```
53
+
54
+ Configuration-Based Setup:
55
+ ```python
56
+ from claude_mpm.config.model_config import ModelConfigManager
57
+ from claude_mpm.services.model import ModelRouter
58
+
59
+ # Load config from file
60
+ config = ModelConfigManager.load_config(".claude/configuration.yaml")
61
+ router_config = ModelConfigManager.get_router_config(config)
62
+
63
+ # Create router with loaded config
64
+ router = ModelRouter(config=router_config)
65
+ await router.initialize()
66
+ ```
67
+
68
+ PROVIDER STRATEGIES:
69
+ - AUTO: Try Ollama first, fallback to Claude (default)
70
+ - OLLAMA: Local-only, fail if unavailable (privacy mode)
71
+ - CLAUDE: Cloud-only, always use Claude
72
+ - PRIVACY: Like OLLAMA with privacy-focused messages
73
+
74
+ RECOMMENDED MODELS (Ollama):
75
+ - SEO Analysis: llama3.3:70b - Comprehensive SEO insights
76
+ - Readability: gemma2:9b - Fast, accurate readability scoring
77
+ - Grammar: qwen3:14b - Specialized grammar checking
78
+ - Summarization: mistral:7b - Concise, effective summaries
79
+ - Keyword Extraction: seoassistant - SEO-specialized model
80
+
81
+ CONFIGURATION:
82
+ See claude_mpm.config.model_config for detailed configuration options.
83
+
84
+ Example configuration.yaml:
85
+ ```yaml
86
+ content_agent:
87
+ model_provider: auto
88
+
89
+ ollama:
90
+ enabled: true
91
+ host: http://localhost:11434
92
+ fallback_to_cloud: true
93
+ models:
94
+ seo_analysis: llama3.3:70b
95
+ readability: gemma2:9b
96
+
97
+ claude:
98
+ enabled: true
99
+ model: claude-3-5-sonnet-20241022
100
+ ```
101
+
102
+ PHASE 1 STATUS (Current):
103
+ ✅ Core interfaces and contracts defined
104
+ ✅ Base provider with common functionality
105
+ ✅ Ollama provider with direct API integration
106
+ ✅ Claude provider (Phase 1: mock responses)
107
+ ✅ Router with intelligent fallback logic
108
+ ✅ Configuration management with validation
109
+ ⏳ Claude API integration (Phase 2)
110
+ ⏳ Content agent integration (Phase 2)
111
+ """
112
+
113
+ # Re-export interfaces for convenience
114
+ from claude_mpm.services.core.interfaces.model import (
115
+ IModelProvider,
116
+ IModelRouter,
117
+ ModelCapability,
118
+ ModelProvider,
119
+ ModelResponse,
120
+ )
121
+ from claude_mpm.services.model.base_provider import BaseModelProvider
122
+ from claude_mpm.services.model.claude_provider import ClaudeProvider
123
+ from claude_mpm.services.model.model_router import ModelRouter, RoutingStrategy
124
+ from claude_mpm.services.model.ollama_provider import OllamaProvider
125
+
126
+ __all__ = [ # noqa: RUF022 - Semantic grouping preferred over alphabetical
127
+ # Base classes
128
+ "BaseModelProvider",
129
+ # Providers
130
+ "ClaudeProvider",
131
+ "OllamaProvider",
132
+ # Router
133
+ "ModelRouter",
134
+ "RoutingStrategy",
135
+ # Interfaces
136
+ "IModelProvider",
137
+ "IModelRouter",
138
+ # Data types
139
+ "ModelCapability",
140
+ "ModelProvider",
141
+ "ModelResponse",
142
+ ]
143
+
144
+ # Version and metadata
145
+ __version__ = "1.0.0"
146
+ __phase__ = "1"
147
+ __status__ = "Core Infrastructure Complete"
@@ -0,0 +1,365 @@
1
+ """
2
+ Base Model Provider Implementation for Claude MPM Framework
3
+ ===========================================================
4
+
5
+ WHY: Provides common functionality for all model providers, reducing
6
+ duplication and ensuring consistent behavior across implementations.
7
+
8
+ DESIGN DECISION: Abstract base class extends both BaseService and IModelProvider,
9
+ providing service lifecycle management plus model-specific utilities.
10
+
11
+ RESPONSIBILITIES:
12
+ - Common error handling and logging
13
+ - Task-specific prompt generation
14
+ - Response formatting and validation
15
+ - Performance metrics tracking
16
+ - Retry logic for transient failures
17
+ """
18
+
19
+ import asyncio
20
+ import time
21
+ from abc import abstractmethod
22
+ from typing import Any, Dict, Optional
23
+
24
+ from claude_mpm.core.logger import get_logger
25
+ from claude_mpm.services.core.base import BaseService
26
+ from claude_mpm.services.core.interfaces.model import (
27
+ IModelProvider,
28
+ ModelCapability,
29
+ ModelResponse,
30
+ )
31
+
32
+
33
+ class BaseModelProvider(BaseService, IModelProvider):
34
+ """
35
+ Abstract base class for model providers.
36
+
37
+ WHY: Centralizes common provider functionality like prompt generation,
38
+ error handling, and response formatting.
39
+
40
+ Usage:
41
+ class MyProvider(BaseModelProvider):
42
+ async def analyze_content(self, content, task, model=None, **kwargs):
43
+ prompt = self.get_task_prompt(task, content)
44
+ # Call provider API
45
+ return self.create_response(...)
46
+ """
47
+
48
+ # Task-specific prompt templates
49
+ TASK_PROMPTS: Dict[ModelCapability, str] = {
50
+ ModelCapability.SEO_ANALYSIS: """Analyze the following content for SEO effectiveness. Provide:
51
+ 1. Primary and secondary keywords identified
52
+ 2. Keyword density analysis
53
+ 3. Meta description recommendation
54
+ 4. Title tag optimization suggestions
55
+ 5. Content structure analysis (H1, H2, etc.)
56
+ 6. SEO score (0-100) with justification
57
+
58
+ Content to analyze:
59
+ {content}
60
+
61
+ Provide your analysis in a structured format.""",
62
+ ModelCapability.READABILITY: """Analyze the readability of the following content. Provide:
63
+ 1. Readability score (Flesch-Kincaid or similar)
64
+ 2. Average sentence length
65
+ 3. Complex word count
66
+ 4. Grade level assessment
67
+ 5. Suggestions for improvement
68
+ 6. Overall readability rating (Easy/Medium/Hard)
69
+
70
+ Content to analyze:
71
+ {content}
72
+
73
+ Provide your analysis in a structured format.""",
74
+ ModelCapability.GRAMMAR: """Perform a grammar and style check on the following content. Identify:
75
+ 1. Grammatical errors with corrections
76
+ 2. Spelling mistakes
77
+ 3. Punctuation issues
78
+ 4. Style inconsistencies
79
+ 5. Clarity improvements
80
+ 6. Overall quality score (0-100)
81
+
82
+ Content to analyze:
83
+ {content}
84
+
85
+ Provide your analysis in a structured format.""",
86
+ ModelCapability.SUMMARIZATION: """Provide a comprehensive summary of the following content:
87
+ 1. Main topic and key points (3-5 bullet points)
88
+ 2. Supporting details
89
+ 3. Conclusions or recommendations
90
+ 4. One-sentence TL;DR
91
+
92
+ Content to summarize:
93
+ {content}
94
+
95
+ Provide your summary in a structured format.""",
96
+ ModelCapability.KEYWORD_EXTRACTION: """Extract and analyze keywords from the following content:
97
+ 1. Primary keywords (top 5-10)
98
+ 2. Long-tail keyword phrases
99
+ 3. Semantic relationships between keywords
100
+ 4. Keyword relevance scores
101
+ 5. Suggested additional keywords
102
+
103
+ Content to analyze:
104
+ {content}
105
+
106
+ Provide your keyword analysis in a structured format.""",
107
+ ModelCapability.ACCESSIBILITY: """Analyze the accessibility of the following content:
108
+ 1. Language complexity level
109
+ 2. Inclusivity assessment
110
+ 3. Plain language recommendations
111
+ 4. Potential barriers for readers with disabilities
112
+ 5. WCAG compliance suggestions
113
+ 6. Accessibility score (0-100)
114
+
115
+ Content to analyze:
116
+ {content}
117
+
118
+ Provide your analysis in a structured format.""",
119
+ ModelCapability.SENTIMENT: """Analyze the sentiment and tone of the following content:
120
+ 1. Overall sentiment (Positive/Negative/Neutral)
121
+ 2. Sentiment score (-1 to +1)
122
+ 3. Emotional tone detected
123
+ 4. Audience perception analysis
124
+ 5. Tone consistency evaluation
125
+
126
+ Content to analyze:
127
+ {content}
128
+
129
+ Provide your analysis in a structured format.""",
130
+ ModelCapability.GENERAL: """Analyze the following content and provide:
131
+ 1. Overview and main themes
132
+ 2. Quality assessment
133
+ 3. Structural analysis
134
+ 4. Improvement suggestions
135
+ 5. Overall effectiveness rating
136
+
137
+ Content to analyze:
138
+ {content}
139
+
140
+ Provide your analysis in a structured format.""",
141
+ }
142
+
143
+ def __init__(
144
+ self,
145
+ provider_name: str,
146
+ config: Optional[Dict[str, Any]] = None,
147
+ ):
148
+ """
149
+ Initialize base model provider.
150
+
151
+ Args:
152
+ provider_name: Name of the provider (e.g., "ollama", "claude")
153
+ config: Provider-specific configuration
154
+ """
155
+ super().__init__(service_name=f"{provider_name}_provider", config=config)
156
+ self.provider_name = provider_name
157
+ self.logger = get_logger(f"model.{provider_name}")
158
+ self._request_count = 0
159
+ self._error_count = 0
160
+ self._total_latency = 0.0
161
+
162
+ def get_task_prompt(self, task: ModelCapability, content: str) -> str:
163
+ """
164
+ Generate task-specific prompt.
165
+
166
+ WHY: Centralizes prompt engineering. Tasks require different analysis
167
+ approaches and output formats.
168
+
169
+ Args:
170
+ task: Type of analysis to perform
171
+ content: Content to analyze
172
+
173
+ Returns:
174
+ Formatted prompt string
175
+ """
176
+ template = self.TASK_PROMPTS.get(
177
+ task, self.TASK_PROMPTS[ModelCapability.GENERAL]
178
+ )
179
+ return template.format(content=content)
180
+
181
+ def create_response(
182
+ self,
183
+ success: bool,
184
+ model: str,
185
+ task: ModelCapability,
186
+ result: str = "",
187
+ metadata: Optional[Dict[str, Any]] = None,
188
+ error: Optional[str] = None,
189
+ ) -> ModelResponse:
190
+ """
191
+ Create standardized model response.
192
+
193
+ WHY: Ensures consistent response format across all providers.
194
+
195
+ Args:
196
+ success: Whether operation succeeded
197
+ model: Model used
198
+ task: Task performed
199
+ result: Analysis result
200
+ metadata: Additional metadata
201
+ error: Error message if failed
202
+
203
+ Returns:
204
+ ModelResponse object
205
+ """
206
+ return ModelResponse(
207
+ success=success,
208
+ provider=self.provider_name,
209
+ model=model,
210
+ task=task.value,
211
+ result=result,
212
+ metadata=metadata or {},
213
+ error=error,
214
+ )
215
+
216
+ async def analyze_with_retry(
217
+ self,
218
+ analyze_func,
219
+ content: str,
220
+ task: ModelCapability,
221
+ model: Optional[str] = None,
222
+ max_retries: int = 3,
223
+ **kwargs,
224
+ ) -> ModelResponse:
225
+ """
226
+ Execute analysis with retry logic.
227
+
228
+ WHY: Handles transient failures (network issues, rate limits, etc.)
229
+ without requiring retry logic in each provider implementation.
230
+
231
+ Args:
232
+ analyze_func: Async function to call for analysis
233
+ content: Content to analyze
234
+ task: Task to perform
235
+ model: Optional model to use
236
+ max_retries: Maximum retry attempts
237
+ **kwargs: Additional arguments for analyze_func
238
+
239
+ Returns:
240
+ ModelResponse from successful attempt or final error
241
+ """
242
+ last_error = None
243
+
244
+ for attempt in range(max_retries):
245
+ try:
246
+ start_time = time.time()
247
+ response = await analyze_func(content, task, model, **kwargs)
248
+ latency = time.time() - start_time
249
+
250
+ # Track metrics
251
+ self._request_count += 1
252
+ self._total_latency += latency
253
+
254
+ if response.success:
255
+ response.metadata["latency_seconds"] = latency
256
+ response.metadata["attempt"] = attempt + 1
257
+ self.log_debug(
258
+ f"Analysis completed in {latency:.2f}s (attempt {attempt + 1})"
259
+ )
260
+ return response
261
+ last_error = response.error
262
+ self._error_count += 1
263
+
264
+ except Exception as e:
265
+ last_error = str(e)
266
+ self._error_count += 1
267
+ self.log_warning(
268
+ f"Analysis attempt {attempt + 1} failed: {e}",
269
+ exc_info=True,
270
+ )
271
+
272
+ # Wait before retry (exponential backoff)
273
+ if attempt < max_retries - 1:
274
+ wait_time = 2**attempt # 1s, 2s, 4s
275
+ self.log_info(f"Retrying in {wait_time}s...")
276
+ await asyncio.sleep(wait_time)
277
+
278
+ # All retries failed
279
+ self.log_error(f"All {max_retries} attempts failed. Last error: {last_error}")
280
+ return self.create_response(
281
+ success=False,
282
+ model=model or "unknown",
283
+ task=task,
284
+ error=f"Failed after {max_retries} attempts: {last_error}",
285
+ )
286
+
287
+ def validate_content(self, content: str, max_length: Optional[int] = None) -> bool:
288
+ """
289
+ Validate content before analysis.
290
+
291
+ WHY: Prevents invalid requests and provides early error detection.
292
+
293
+ Args:
294
+ content: Content to validate
295
+ max_length: Optional maximum length in characters
296
+
297
+ Returns:
298
+ True if valid, False otherwise
299
+ """
300
+ if not content or not content.strip():
301
+ self.log_warning("Empty content provided for analysis")
302
+ return False
303
+
304
+ if max_length and len(content) > max_length:
305
+ self.log_warning(
306
+ f"Content length {len(content)} exceeds maximum {max_length}"
307
+ )
308
+ return False
309
+
310
+ return True
311
+
312
+ def get_metrics(self) -> Dict[str, Any]:
313
+ """
314
+ Get provider performance metrics.
315
+
316
+ Returns:
317
+ Dictionary of metrics (request count, error rate, avg latency)
318
+ """
319
+ avg_latency = (
320
+ self._total_latency / self._request_count if self._request_count > 0 else 0
321
+ )
322
+ error_rate = (
323
+ self._error_count / self._request_count if self._request_count > 0 else 0
324
+ )
325
+
326
+ return {
327
+ "provider": self.provider_name,
328
+ "request_count": self._request_count,
329
+ "error_count": self._error_count,
330
+ "error_rate": error_rate,
331
+ "avg_latency_seconds": avg_latency,
332
+ }
333
+
334
+ async def initialize(self) -> bool:
335
+ """
336
+ Initialize provider.
337
+
338
+ Subclasses should override to perform provider-specific setup.
339
+
340
+ Returns:
341
+ True if initialization successful
342
+ """
343
+ self.log_info(f"Initializing {self.provider_name} provider")
344
+ self._initialized = True
345
+ return True
346
+
347
+ async def shutdown(self) -> None:
348
+ """
349
+ Shutdown provider and cleanup resources.
350
+
351
+ Subclasses should override to perform provider-specific cleanup.
352
+ """
353
+ self.log_info(f"Shutting down {self.provider_name} provider")
354
+ self._shutdown = True
355
+
356
+ @abstractmethod
357
+ async def get_model_info(self, model: str) -> Dict[str, Any]:
358
+ """
359
+ Get model information.
360
+
361
+ Must be implemented by subclasses.
362
+ """
363
+
364
+
365
+ __all__ = ["BaseModelProvider"]