claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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 (434) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +2 -2
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +330 -86
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +363 -220
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +124 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -13,16 +13,23 @@ agent outputs because:
13
13
  """
14
14
 
15
15
  import re
16
- from typing import Dict, Any, List
17
- from claude_mpm.hooks.base_hook import PreDelegationHook, PostDelegationHook, HookContext, HookResult
16
+ from typing import Any, Dict, List
17
+
18
18
  from claude_mpm.core.config import Config
19
19
  from claude_mpm.core.logger import get_logger
20
+ from claude_mpm.hooks.base_hook import (
21
+ HookContext,
22
+ HookResult,
23
+ PostDelegationHook,
24
+ PreDelegationHook,
25
+ )
20
26
 
21
27
  logger = get_logger(__name__)
22
28
 
23
29
  # Try to import memory manager with fallback handling
24
30
  try:
25
31
  from claude_mpm.services.agents.memory import AgentMemoryManager
32
+
26
33
  MEMORY_MANAGER_AVAILABLE = True
27
34
  except ImportError as e:
28
35
  logger.warning(f"AgentMemoryManager not available: {e}")
@@ -32,6 +39,7 @@ except ImportError as e:
32
39
  # Try to import socketio server with fallback handling
33
40
  try:
34
41
  from claude_mpm.services.socketio_server import get_socketio_server
42
+
35
43
  SOCKETIO_AVAILABLE = True
36
44
  except ImportError as e:
37
45
  logger.debug(f"SocketIO server not available: {e}")
@@ -41,24 +49,24 @@ except ImportError as e:
41
49
 
42
50
  class MemoryPreDelegationHook(PreDelegationHook):
43
51
  """Inject agent memory into delegation context.
44
-
52
+
45
53
  WHY: Agents perform better when they have access to accumulated project knowledge.
46
54
  This hook loads agent-specific memory and adds it to the delegation context,
47
55
  allowing agents to apply learned patterns and avoid known mistakes.
48
-
56
+
49
57
  DESIGN DECISION: Memory is injected as a clearly formatted section in the context
50
58
  to ensure agents understand it's their accumulated knowledge, not current task info.
51
59
  """
52
-
60
+
53
61
  def __init__(self, config: Config = None):
54
62
  """Initialize with optional config.
55
-
63
+
56
64
  Args:
57
65
  config: Optional Config object. If not provided, will create default Config.
58
66
  """
59
67
  super().__init__(name="memory_pre_delegation", priority=20)
60
68
  self.config = config or Config()
61
-
69
+
62
70
  # Initialize memory manager only if available
63
71
  if MEMORY_MANAGER_AVAILABLE and AgentMemoryManager:
64
72
  try:
@@ -69,10 +77,10 @@ class MemoryPreDelegationHook(PreDelegationHook):
69
77
  else:
70
78
  logger.info("Memory manager not available - hook will be inactive")
71
79
  self.memory_manager = None
72
-
80
+
73
81
  def execute(self, context: HookContext) -> HookResult:
74
82
  """Add agent memory to delegation context.
75
-
83
+
76
84
  WHY: By loading memory before delegation, agents can reference their
77
85
  accumulated knowledge when performing tasks, leading to better outcomes.
78
86
  """
@@ -80,27 +88,33 @@ class MemoryPreDelegationHook(PreDelegationHook):
80
88
  if not self.memory_manager:
81
89
  logger.debug("Memory manager not available - skipping memory injection")
82
90
  return HookResult(success=True, data=context.data, modified=False)
83
-
91
+
84
92
  try:
85
93
  # Extract and normalize agent ID from context
86
- agent_name = context.data.get('agent', '')
94
+ agent_name = context.data.get("agent", "")
87
95
  if not agent_name:
88
96
  return HookResult(success=True, data=context.data, modified=False)
89
-
97
+
90
98
  # Normalize agent ID (e.g., "Engineer Agent" -> "engineer")
91
- agent_id = agent_name.lower().replace(' ', '_').replace('_agent', '').replace('agent', '').strip('_')
92
-
99
+ agent_id = (
100
+ agent_name.lower()
101
+ .replace(" ", "_")
102
+ .replace("_agent", "")
103
+ .replace("agent", "")
104
+ .strip("_")
105
+ )
106
+
93
107
  if agent_id:
94
108
  # Load agent memory
95
109
  memory_content = self.memory_manager.load_agent_memory(agent_id)
96
-
110
+
97
111
  if memory_content and memory_content.strip():
98
112
  # Get existing context data
99
- delegation_context = context.data.get('context', {})
113
+ delegation_context = context.data.get("context", {})
100
114
  if isinstance(delegation_context, str):
101
115
  # If context is a string, convert to dict
102
- delegation_context = {'prompt': delegation_context}
103
-
116
+ delegation_context = {"prompt": delegation_context}
117
+
104
118
  # Add memory with clear formatting
105
119
  memory_section = f"""
106
120
  AGENT MEMORY - PROJECT-SPECIFIC KNOWLEDGE:
@@ -108,34 +122,34 @@ AGENT MEMORY - PROJECT-SPECIFIC KNOWLEDGE:
108
122
 
109
123
  INSTRUCTIONS: Review your memory above before proceeding. Apply learned patterns and avoid known mistakes.
110
124
  """
111
-
125
+
112
126
  # Add to context
113
- delegation_context['agent_memory'] = memory_section
114
-
127
+ delegation_context["agent_memory"] = memory_section
128
+
115
129
  # Update the context data
116
130
  updated_data = context.data.copy()
117
- updated_data['context'] = delegation_context
118
-
131
+ updated_data["context"] = delegation_context
132
+
119
133
  logger.info(f"Injected memory for agent '{agent_id}'")
120
-
134
+
121
135
  # Emit Socket.IO event for memory injected
122
136
  try:
123
137
  socketio_server = get_socketio_server()
124
138
  # Calculate size of injected content
125
- injected_size = len(memory_section.encode('utf-8'))
139
+ injected_size = len(memory_section.encode("utf-8"))
126
140
  socketio_server.memory_injected(agent_id, injected_size)
127
141
  except Exception as ws_error:
128
142
  logger.debug(f"Socket.IO notification failed: {ws_error}")
129
-
143
+
130
144
  return HookResult(
131
145
  success=True,
132
146
  data=updated_data,
133
147
  modified=True,
134
- metadata={'memory_injected': True, 'agent_id': agent_id}
148
+ metadata={"memory_injected": True, "agent_id": agent_id},
135
149
  )
136
-
150
+
137
151
  return HookResult(success=True, data=context.data, modified=False)
138
-
152
+
139
153
  except Exception as e:
140
154
  logger.error(f"Memory injection failed: {e}")
141
155
  # Don't fail the delegation if memory injection fails
@@ -143,73 +157,77 @@ INSTRUCTIONS: Review your memory above before proceeding. Apply learned patterns
143
157
  success=True,
144
158
  data=context.data,
145
159
  modified=False,
146
- error=f"Memory injection failed: {str(e)}"
160
+ error=f"Memory injection failed: {str(e)}",
147
161
  )
148
162
 
149
163
 
150
164
  class MemoryPostDelegationHook(PostDelegationHook):
151
165
  """Extract learnings from delegation results using explicit markers.
152
-
166
+
153
167
  WHY: Agents produce valuable insights during task execution. This hook
154
168
  extracts structured learnings from their outputs using explicit markers,
155
169
  building up project-specific knowledge over time.
156
-
170
+
157
171
  DESIGN DECISION: We use explicit markers to give agents full control over
158
172
  what gets memorized. This is more reliable than pattern matching and allows
159
173
  multiple learnings per response. Supports multiple trigger phrases for flexibility.
160
-
174
+
161
175
  Supported formats:
162
176
  # Add To Memory:
163
177
  Type: pattern
164
178
  Content: All services use dependency injection for flexibility
165
179
  #
166
-
180
+
167
181
  # Memorize:
168
182
  Type: guideline
169
183
  Content: Always validate input parameters before processing
170
184
  #
171
-
185
+
172
186
  # Remember:
173
187
  Type: mistake
174
188
  Content: Never hardcode configuration values
175
189
  #
176
190
  """
177
-
191
+
178
192
  def __init__(self, config: Config = None):
179
193
  """Initialize with optional config.
180
-
194
+
181
195
  Args:
182
196
  config: Optional Config object. If not provided, will create default Config.
183
197
  """
184
198
  super().__init__(name="memory_post_delegation", priority=80)
185
199
  self.config = config or Config()
186
-
200
+
187
201
  # Initialize memory manager only if available
188
202
  if MEMORY_MANAGER_AVAILABLE and AgentMemoryManager:
189
203
  try:
190
204
  self.memory_manager = AgentMemoryManager(self.config)
191
205
  except Exception as e:
192
- logger.error(f"Failed to initialize AgentMemoryManager in PostDelegationHook: {e}")
206
+ logger.error(
207
+ f"Failed to initialize AgentMemoryManager in PostDelegationHook: {e}"
208
+ )
193
209
  self.memory_manager = None
194
210
  else:
195
- logger.info("Memory manager not available - post-delegation hook will be inactive")
211
+ logger.info(
212
+ "Memory manager not available - post-delegation hook will be inactive"
213
+ )
196
214
  self.memory_manager = None
197
-
215
+
198
216
  # Map of supported types to memory sections
199
217
  self.type_mapping = {
200
- 'pattern': 'pattern', # Coding Patterns Learned
201
- 'architecture': 'architecture', # Project Architecture
202
- 'guideline': 'guideline', # Implementation Guidelines
203
- 'mistake': 'mistake', # Common Mistakes to Avoid
204
- 'strategy': 'strategy', # Effective Strategies
205
- 'integration': 'integration', # Integration Points
206
- 'performance': 'performance', # Performance Considerations
207
- 'context': 'context' # Current Technical Context
218
+ "pattern": "pattern", # Coding Patterns Learned
219
+ "architecture": "architecture", # Project Architecture
220
+ "guideline": "guideline", # Implementation Guidelines
221
+ "mistake": "mistake", # Common Mistakes to Avoid
222
+ "strategy": "strategy", # Effective Strategies
223
+ "integration": "integration", # Integration Points
224
+ "performance": "performance", # Performance Considerations
225
+ "context": "context", # Current Technical Context
208
226
  }
209
-
227
+
210
228
  def execute(self, context: HookContext) -> HookResult:
211
229
  """Extract and store learnings from delegation result.
212
-
230
+
213
231
  WHY: Capturing learnings immediately after task completion ensures we
214
232
  don't lose valuable insights that agents discover during execution.
215
233
  """
@@ -217,62 +235,74 @@ class MemoryPostDelegationHook(PostDelegationHook):
217
235
  if not self.memory_manager:
218
236
  logger.debug("Memory manager not available - skipping learning extraction")
219
237
  return HookResult(success=True, data=context.data, modified=False)
220
-
238
+
221
239
  try:
222
240
  # Check if auto-learning is enabled
223
- if not self.config.get('memory.auto_learning', True): # Changed default to True
241
+ if not self.config.get(
242
+ "memory.auto_learning", True
243
+ ): # Changed default to True
224
244
  return HookResult(success=True, data=context.data, modified=False)
225
-
245
+
226
246
  # Extract agent ID
227
- agent_name = context.data.get('agent', '')
247
+ agent_name = context.data.get("agent", "")
228
248
  if not agent_name:
229
249
  return HookResult(success=True, data=context.data, modified=False)
230
-
250
+
231
251
  # Normalize agent ID
232
- agent_id = agent_name.lower().replace(' ', '_').replace('_agent', '').replace('agent', '').strip('_')
233
-
252
+ agent_id = (
253
+ agent_name.lower()
254
+ .replace(" ", "_")
255
+ .replace("_agent", "")
256
+ .replace("agent", "")
257
+ .strip("_")
258
+ )
259
+
234
260
  # Check if auto-learning is enabled for this specific agent
235
- agent_overrides = self.config.get('memory.agent_overrides', {})
261
+ agent_overrides = self.config.get("memory.agent_overrides", {})
236
262
  agent_config = agent_overrides.get(agent_id, {})
237
- if 'auto_learning' in agent_config and not agent_config['auto_learning']:
263
+ if "auto_learning" in agent_config and not agent_config["auto_learning"]:
238
264
  return HookResult(success=True, data=context.data, modified=False)
239
-
265
+
240
266
  # Extract result content
241
- result = context.data.get('result', {})
267
+ result = context.data.get("result", {})
242
268
  if isinstance(result, dict):
243
- result_text = result.get('content', '') or str(result)
269
+ result_text = result.get("content", "") or str(result)
244
270
  else:
245
271
  result_text = str(result)
246
-
272
+
247
273
  if agent_id and result_text:
248
274
  # Extract learnings using patterns
249
275
  learnings = self._extract_learnings(result_text)
250
-
276
+
251
277
  # Store each learning
252
278
  learnings_stored = 0
253
279
  for learning_type, items in learnings.items():
254
280
  for item in items:
255
281
  try:
256
- self.memory_manager.add_learning(agent_id, learning_type, item)
282
+ self.memory_manager.add_learning(
283
+ agent_id, learning_type, item
284
+ )
257
285
  learnings_stored += 1
258
286
  except Exception as e:
259
287
  logger.warning(f"Failed to store learning: {e}")
260
-
288
+
261
289
  if learnings_stored > 0:
262
- logger.info(f"Extracted {learnings_stored} learnings for agent '{agent_id}'")
263
-
290
+ logger.info(
291
+ f"Extracted {learnings_stored} learnings for agent '{agent_id}'"
292
+ )
293
+
264
294
  return HookResult(
265
295
  success=True,
266
296
  data=context.data,
267
297
  modified=False,
268
298
  metadata={
269
- 'learnings_extracted': learnings_stored,
270
- 'agent_id': agent_id
271
- }
299
+ "learnings_extracted": learnings_stored,
300
+ "agent_id": agent_id,
301
+ },
272
302
  )
273
-
303
+
274
304
  return HookResult(success=True, data=context.data, modified=False)
275
-
305
+
276
306
  except Exception as e:
277
307
  logger.error(f"Learning extraction failed: {e}")
278
308
  # Don't fail the delegation result if learning extraction fails
@@ -280,54 +310,58 @@ class MemoryPostDelegationHook(PostDelegationHook):
280
310
  success=True,
281
311
  data=context.data,
282
312
  modified=False,
283
- error=f"Learning extraction failed: {str(e)}"
313
+ error=f"Learning extraction failed: {str(e)}",
284
314
  )
285
-
315
+
286
316
  def _extract_learnings(self, text: str) -> Dict[str, List[str]]:
287
317
  """Extract structured learnings from text using explicit markers.
288
-
318
+
289
319
  WHY: We limit learnings to 100 characters to keep memory entries
290
320
  concise and actionable. Longer entries tend to be less useful as
291
321
  quick reference points.
292
-
322
+
293
323
  DESIGN DECISION: Using explicit markers gives agents full control and makes
294
324
  extraction reliable. We support multiple memory additions in a single response
295
325
  and multiple trigger phrases (Add To Memory, Memorize, Remember) for flexibility.
296
-
326
+
297
327
  Args:
298
328
  text: The text to extract learnings from
299
-
329
+
300
330
  Returns:
301
331
  Dictionary mapping learning types to lists of extracted learnings
302
332
  """
303
333
  learnings = {learning_type: [] for learning_type in self.type_mapping.keys()}
304
334
  seen_learnings = set() # Avoid duplicates
305
-
335
+
306
336
  # Pattern to find memory blocks with multiple trigger phrases
307
337
  # Matches: # Add To Memory: / # Memorize: / # Remember:\n...\n#
308
338
  # Only matches complete blocks with proper closing markers
309
- memory_pattern = r'#\s*(?:Add\s+To\s+Memory|Memorize|Remember):\s*\n((?:[^#](?:[^#]|#(?!\s*(?:Add\s+To\s+Memory|Memorize|Remember):))*?)?)\n\s*#\s*$'
310
- matches = re.finditer(memory_pattern, text, re.MULTILINE | re.DOTALL | re.IGNORECASE)
311
-
339
+ memory_pattern = r"#\s*(?:Add\s+To\s+Memory|Memorize|Remember):\s*\n((?:[^#](?:[^#]|#(?!\s*(?:Add\s+To\s+Memory|Memorize|Remember):))*?)?)\n\s*#\s*$"
340
+ matches = re.finditer(
341
+ memory_pattern, text, re.MULTILINE | re.DOTALL | re.IGNORECASE
342
+ )
343
+
312
344
  for match in matches:
313
345
  block_content = match.group(1).strip()
314
346
  logger.debug(f"Found memory block: {block_content[:50]}...")
315
-
347
+
316
348
  # Extract type and content from the block
317
- type_match = re.search(r'Type:\s*(\w+)', block_content, re.IGNORECASE)
318
- content_match = re.search(r'Content:\s*(.+)', block_content, re.IGNORECASE | re.DOTALL)
319
-
349
+ type_match = re.search(r"Type:\s*(\w+)", block_content, re.IGNORECASE)
350
+ content_match = re.search(
351
+ r"Content:\s*(.+)", block_content, re.IGNORECASE | re.DOTALL
352
+ )
353
+
320
354
  if type_match and content_match:
321
355
  learning_type = type_match.group(1).lower().strip()
322
356
  content = content_match.group(1).strip()
323
-
357
+
324
358
  # Clean up multi-line content - take first line if multiple
325
- if '\n' in content:
326
- content = content.split('\n')[0].strip()
327
-
359
+ if "\n" in content:
360
+ content = content.split("\n")[0].strip()
361
+
328
362
  # Remove trailing punctuation
329
- content = content.rstrip('.!?,;')
330
-
363
+ content = content.rstrip(".!?,;")
364
+
331
365
  # Validate type is supported
332
366
  if learning_type in self.type_mapping:
333
367
  # Check content length (between 5 and 100 characters)
@@ -337,16 +371,22 @@ class MemoryPostDelegationHook(PostDelegationHook):
337
371
  if normalized not in seen_learnings:
338
372
  learnings[learning_type].append(content)
339
373
  seen_learnings.add(normalized)
340
- logger.debug(f"Extracted learning - Type: {learning_type}, Content: {content}")
374
+ logger.debug(
375
+ f"Extracted learning - Type: {learning_type}, Content: {content}"
376
+ )
341
377
  else:
342
378
  logger.debug(f"Skipping duplicate learning: {content}")
343
379
  else:
344
- logger.debug(f"Skipping learning - invalid length ({len(content)}): {content}")
380
+ logger.debug(
381
+ f"Skipping learning - invalid length ({len(content)}): {content}"
382
+ )
345
383
  else:
346
- logger.warning(f"Unsupported learning type: {learning_type}. Supported types: {list(self.type_mapping.keys())}")
384
+ logger.warning(
385
+ f"Unsupported learning type: {learning_type}. Supported types: {list(self.type_mapping.keys())}"
386
+ )
347
387
  else:
348
388
  logger.debug(f"Invalid memory block format - missing Type or Content")
349
-
389
+
350
390
  # Log summary of extracted learnings
351
391
  total_learnings = sum(len(items) for items in learnings.values())
352
392
  if total_learnings > 0:
@@ -354,5 +394,5 @@ class MemoryPostDelegationHook(PostDelegationHook):
354
394
  for learning_type, items in learnings.items():
355
395
  if items:
356
396
  logger.debug(f" {learning_type}: {len(items)} items")
357
-
358
- return learnings
397
+
398
+ return learnings