claude-mpm 3.4.10__py3-none-any.whl → 5.4.85__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 (1062) hide show
  1. claude_mpm/BUILD_NUMBER +1 -0
  2. claude_mpm/VERSION +1 -0
  3. claude_mpm/__init__.py +50 -12
  4. claude_mpm/__main__.py +7 -2
  5. claude_mpm/agents/BASE_AGENT.md +164 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
  8. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
  9. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
  10. claude_mpm/agents/MEMORY.md +72 -0
  11. claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -0
  12. claude_mpm/agents/WORKFLOW.md +111 -0
  13. claude_mpm/agents/__init__.py +92 -80
  14. claude_mpm/agents/agent-template.yaml +83 -0
  15. claude_mpm/agents/agent_loader.py +560 -745
  16. claude_mpm/agents/agent_loader_integration.py +53 -55
  17. claude_mpm/agents/agents_metadata.py +186 -27
  18. claude_mpm/agents/async_agent_loader.py +436 -0
  19. claude_mpm/agents/base_agent.json +8 -4
  20. claude_mpm/agents/frontmatter_validator.py +754 -0
  21. claude_mpm/agents/system_agent_config.py +222 -155
  22. claude_mpm/agents/templates/README.md +465 -0
  23. claude_mpm/agents/templates/__init__.py +17 -13
  24. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  25. claude_mpm/agents/templates/context-management-examples.md +544 -0
  26. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  27. claude_mpm/agents/templates/pm-examples.md +474 -0
  28. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  29. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  30. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  31. claude_mpm/agents/templates/response-format.md +583 -0
  32. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  33. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  34. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  35. claude_mpm/agents/templates/validation-templates.md +312 -0
  36. claude_mpm/cli/__init__.py +94 -128
  37. claude_mpm/cli/__main__.py +33 -0
  38. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  39. claude_mpm/cli/commands/__init__.py +36 -12
  40. claude_mpm/cli/commands/agent_manager.py +1403 -0
  41. claude_mpm/cli/commands/agent_source.py +774 -0
  42. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  43. claude_mpm/cli/commands/agents.py +2501 -168
  44. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  45. claude_mpm/cli/commands/agents_discover.py +338 -0
  46. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  47. claude_mpm/cli/commands/aggregate.py +540 -0
  48. claude_mpm/cli/commands/analyze.py +553 -0
  49. claude_mpm/cli/commands/analyze_code.py +528 -0
  50. claude_mpm/cli/commands/auto_configure.py +1053 -0
  51. claude_mpm/cli/commands/cleanup.py +588 -0
  52. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  53. claude_mpm/cli/commands/config.py +586 -0
  54. claude_mpm/cli/commands/configure.py +3253 -0
  55. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  56. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  57. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  58. claude_mpm/cli/commands/configure_models.py +18 -0
  59. claude_mpm/cli/commands/configure_navigation.py +184 -0
  60. claude_mpm/cli/commands/configure_paths.py +104 -0
  61. claude_mpm/cli/commands/configure_persistence.py +254 -0
  62. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  63. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  64. claude_mpm/cli/commands/configure_validators.py +73 -0
  65. claude_mpm/cli/commands/dashboard.py +286 -0
  66. claude_mpm/cli/commands/debug.py +1386 -0
  67. claude_mpm/cli/commands/doctor.py +243 -0
  68. claude_mpm/cli/commands/hook_errors.py +277 -0
  69. claude_mpm/cli/commands/info.py +195 -74
  70. claude_mpm/cli/commands/local_deploy.py +534 -0
  71. claude_mpm/cli/commands/mcp.py +205 -0
  72. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  73. claude_mpm/cli/commands/mcp_config.py +154 -0
  74. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  75. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  76. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  77. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  78. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  79. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  80. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  81. claude_mpm/cli/commands/memory.py +585 -846
  82. claude_mpm/cli/commands/monitor.py +228 -310
  83. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  84. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  85. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  86. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  87. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  88. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  89. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  90. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  91. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  92. claude_mpm/cli/commands/postmortem.py +401 -0
  93. claude_mpm/cli/commands/profile.py +276 -0
  94. claude_mpm/cli/commands/run.py +910 -488
  95. claude_mpm/cli/commands/search.py +458 -0
  96. claude_mpm/cli/commands/skill_source.py +694 -0
  97. claude_mpm/cli/commands/skills.py +1398 -0
  98. claude_mpm/cli/commands/summarize.py +413 -0
  99. claude_mpm/cli/commands/tickets.py +536 -53
  100. claude_mpm/cli/commands/uninstall.py +176 -0
  101. claude_mpm/cli/commands/upgrade.py +152 -0
  102. claude_mpm/cli/commands/verify.py +119 -0
  103. claude_mpm/cli/executor.py +298 -0
  104. claude_mpm/cli/helpers.py +105 -0
  105. claude_mpm/cli/interactive/__init__.py +31 -0
  106. claude_mpm/cli/interactive/agent_wizard.py +1927 -0
  107. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  108. claude_mpm/cli/interactive/skill_selector.py +481 -0
  109. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  110. claude_mpm/cli/parser.py +87 -563
  111. claude_mpm/cli/parsers/__init__.py +35 -0
  112. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  113. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  114. claude_mpm/cli/parsers/agents_parser.py +575 -0
  115. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  116. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  117. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  118. claude_mpm/cli/parsers/base_parser.py +649 -0
  119. claude_mpm/cli/parsers/config_parser.py +208 -0
  120. claude_mpm/cli/parsers/configure_parser.py +138 -0
  121. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  122. claude_mpm/cli/parsers/debug_parser.py +319 -0
  123. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  124. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  125. claude_mpm/cli/parsers/memory_parser.py +138 -0
  126. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  127. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  128. claude_mpm/cli/parsers/profile_parser.py +147 -0
  129. claude_mpm/cli/parsers/run_parser.py +157 -0
  130. claude_mpm/cli/parsers/search_parser.py +245 -0
  131. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  132. claude_mpm/cli/parsers/skills_parser.py +277 -0
  133. claude_mpm/cli/parsers/source_parser.py +138 -0
  134. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  135. claude_mpm/cli/shared/__init__.py +40 -0
  136. claude_mpm/cli/shared/argument_patterns.py +205 -0
  137. claude_mpm/cli/shared/base_command.py +242 -0
  138. claude_mpm/cli/shared/error_handling.py +242 -0
  139. claude_mpm/cli/shared/output_formatters.py +241 -0
  140. claude_mpm/cli/startup.py +1578 -0
  141. claude_mpm/cli/startup_display.py +480 -0
  142. claude_mpm/cli/startup_logging.py +839 -0
  143. claude_mpm/cli/utils.py +136 -47
  144. claude_mpm/cli_module/__init__.py +6 -6
  145. claude_mpm/cli_module/args.py +188 -140
  146. claude_mpm/cli_module/commands.py +79 -70
  147. claude_mpm/cli_module/migration_example.py +42 -64
  148. claude_mpm/commands/__init__.py +14 -0
  149. claude_mpm/commands/mpm-config.md +28 -0
  150. claude_mpm/commands/mpm-doctor.md +20 -0
  151. claude_mpm/commands/mpm-help.md +20 -0
  152. claude_mpm/commands/mpm-init.md +120 -0
  153. claude_mpm/commands/mpm-monitor.md +31 -0
  154. claude_mpm/commands/mpm-organize.md +120 -0
  155. claude_mpm/commands/mpm-postmortem.md +21 -0
  156. claude_mpm/commands/mpm-session-resume.md +30 -0
  157. claude_mpm/commands/mpm-status.md +20 -0
  158. claude_mpm/commands/mpm-ticket-view.md +109 -0
  159. claude_mpm/commands/mpm-version.md +20 -0
  160. claude_mpm/commands/mpm.md +31 -0
  161. claude_mpm/config/__init__.py +42 -2
  162. claude_mpm/config/agent_config.py +402 -0
  163. claude_mpm/config/agent_presets.py +488 -0
  164. claude_mpm/config/agent_sources.py +352 -0
  165. claude_mpm/config/experimental_features.py +217 -0
  166. claude_mpm/config/model_config.py +428 -0
  167. claude_mpm/config/paths.py +258 -0
  168. claude_mpm/config/skill_presets.py +392 -0
  169. claude_mpm/config/skill_sources.py +590 -0
  170. claude_mpm/config/socketio_config.py +125 -83
  171. claude_mpm/constants.py +133 -22
  172. claude_mpm/core/__init__.py +62 -36
  173. claude_mpm/core/agent_name_normalizer.py +71 -73
  174. claude_mpm/core/agent_registry.py +385 -492
  175. claude_mpm/core/agent_session_manager.py +81 -70
  176. claude_mpm/core/api_validator.py +330 -0
  177. claude_mpm/core/base_service.py +159 -122
  178. claude_mpm/core/cache.py +560 -0
  179. claude_mpm/core/claude_runner.py +696 -916
  180. claude_mpm/core/config.py +613 -122
  181. claude_mpm/core/config_aliases.py +74 -73
  182. claude_mpm/core/config_constants.py +314 -0
  183. claude_mpm/core/constants.py +361 -0
  184. claude_mpm/core/container.py +646 -104
  185. claude_mpm/core/enums.py +452 -0
  186. claude_mpm/core/error_handler.py +623 -0
  187. claude_mpm/core/exceptions.py +536 -0
  188. claude_mpm/core/factories.py +105 -109
  189. claude_mpm/core/file_utils.py +764 -0
  190. claude_mpm/core/framework/__init__.py +25 -0
  191. claude_mpm/core/framework/formatters/__init__.py +11 -0
  192. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  193. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  194. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  195. claude_mpm/core/framework/loaders/__init__.py +13 -0
  196. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  197. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  198. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  199. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  200. claude_mpm/core/framework/processors/__init__.py +11 -0
  201. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  202. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  203. claude_mpm/core/framework/processors/template_processor.py +244 -0
  204. claude_mpm/core/framework_loader.py +485 -414
  205. claude_mpm/core/hook_error_memory.py +381 -0
  206. claude_mpm/core/hook_manager.py +246 -86
  207. claude_mpm/core/hook_performance_config.py +147 -0
  208. claude_mpm/core/injectable_service.py +72 -63
  209. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  210. claude_mpm/core/interactive_session.py +670 -0
  211. claude_mpm/core/interfaces.py +570 -164
  212. claude_mpm/core/lazy.py +467 -0
  213. claude_mpm/core/log_manager.py +707 -0
  214. claude_mpm/core/logger.py +295 -134
  215. claude_mpm/core/logging_config.py +474 -0
  216. claude_mpm/core/logging_utils.py +520 -0
  217. claude_mpm/core/minimal_framework_loader.py +24 -22
  218. claude_mpm/core/mixins.py +30 -29
  219. claude_mpm/core/oneshot_session.py +594 -0
  220. claude_mpm/core/optimized_agent_loader.py +479 -0
  221. claude_mpm/core/optimized_startup.py +554 -0
  222. claude_mpm/core/output_style_manager.py +491 -0
  223. claude_mpm/core/pm_hook_interceptor.py +197 -82
  224. claude_mpm/core/protocols/__init__.py +23 -0
  225. claude_mpm/core/protocols/runner_protocol.py +103 -0
  226. claude_mpm/core/protocols/session_protocol.py +131 -0
  227. claude_mpm/core/service_registry.py +153 -116
  228. claude_mpm/core/session_manager.py +179 -64
  229. claude_mpm/core/shared/__init__.py +17 -0
  230. claude_mpm/core/shared/config_loader.py +326 -0
  231. claude_mpm/core/shared/path_resolver.py +281 -0
  232. claude_mpm/core/shared/singleton_manager.py +221 -0
  233. claude_mpm/core/socketio_pool.py +400 -137
  234. claude_mpm/core/system_context.py +38 -0
  235. claude_mpm/core/tool_access_control.py +64 -57
  236. claude_mpm/core/types.py +307 -0
  237. claude_mpm/core/typing_utils.py +553 -0
  238. claude_mpm/core/unified_agent_registry.py +969 -0
  239. claude_mpm/core/unified_config.py +612 -0
  240. claude_mpm/core/unified_paths.py +958 -0
  241. claude_mpm/dashboard/__init__.py +12 -0
  242. claude_mpm/dashboard/api/simple_directory.py +261 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  305. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  306. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  307. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  308. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  309. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  310. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  312. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  313. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  314. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  315. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  316. claude_mpm/experimental/__init__.py +10 -0
  317. claude_mpm/experimental/cli_enhancements.py +104 -89
  318. claude_mpm/generators/__init__.py +1 -1
  319. claude_mpm/generators/agent_profile_generator.py +76 -66
  320. claude_mpm/hooks/__init__.py +37 -1
  321. claude_mpm/hooks/base_hook.py +37 -32
  322. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  323. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  324. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  325. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  326. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  327. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  328. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  329. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  330. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  331. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  332. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  333. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  334. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  335. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  336. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  337. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  338. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  339. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  340. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  341. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  342. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  343. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  344. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  345. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  346. claude_mpm/hooks/memory_integration_hook.py +201 -107
  347. claude_mpm/hooks/session_resume_hook.py +121 -0
  348. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  349. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  350. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  351. claude_mpm/hooks/validation_hooks.py +62 -54
  352. claude_mpm/init.py +518 -83
  353. claude_mpm/models/__init__.py +9 -9
  354. claude_mpm/models/agent_definition.py +40 -23
  355. claude_mpm/models/agent_session.py +538 -0
  356. claude_mpm/models/git_repository.py +198 -0
  357. claude_mpm/models/resume_log.py +340 -0
  358. claude_mpm/schemas/__init__.py +12 -0
  359. claude_mpm/scripts/__init__.py +15 -0
  360. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  361. claude_mpm/scripts/launch_monitor.py +165 -0
  362. claude_mpm/scripts/mpm_doctor.py +322 -0
  363. claude_mpm/scripts/socketio_daemon.py +189 -200
  364. claude_mpm/scripts/start_activity_logging.py +91 -0
  365. claude_mpm/services/__init__.py +208 -39
  366. claude_mpm/services/agent_capabilities_service.py +266 -0
  367. claude_mpm/services/agents/__init__.py +89 -0
  368. claude_mpm/services/agents/agent_builder.py +514 -0
  369. claude_mpm/services/agents/agent_preset_service.py +238 -0
  370. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  371. claude_mpm/services/agents/agent_review_service.py +280 -0
  372. claude_mpm/services/agents/agent_selection_service.py +484 -0
  373. claude_mpm/services/agents/auto_config_manager.py +796 -0
  374. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  375. claude_mpm/services/agents/cache_git_manager.py +621 -0
  376. claude_mpm/services/agents/deployment/__init__.py +21 -0
  377. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  378. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  379. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  380. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  381. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  382. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  383. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  384. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  385. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  386. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  387. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  388. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  389. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  390. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  391. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  392. claude_mpm/services/agents/deployment/agent_template_builder.py +1377 -0
  393. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  394. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  395. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  396. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  397. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  398. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  399. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  400. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  401. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  402. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  403. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  404. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  405. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  406. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  407. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  408. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  409. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  410. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  411. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  412. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  413. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  414. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  415. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  416. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  417. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  418. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  419. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  420. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  421. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  422. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  423. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  424. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  425. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  426. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  427. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  428. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  429. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  430. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  431. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  432. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  433. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  434. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  435. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  436. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  437. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  438. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  439. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  440. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  441. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  442. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  443. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  444. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  445. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  446. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  447. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  448. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  449. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  450. claude_mpm/services/agents/git_source_manager.py +682 -0
  451. claude_mpm/services/agents/loading/__init__.py +11 -0
  452. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  453. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  454. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  455. claude_mpm/services/agents/local_template_manager.py +784 -0
  456. claude_mpm/services/agents/management/__init__.py +9 -0
  457. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  458. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  459. claude_mpm/services/agents/memory/__init__.py +22 -0
  460. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  461. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  462. claude_mpm/services/agents/memory/content_manager.py +470 -0
  463. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  464. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  465. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  466. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  467. claude_mpm/services/agents/memory/template_generator.py +83 -0
  468. claude_mpm/services/agents/observers.py +547 -0
  469. claude_mpm/services/agents/recommender.py +617 -0
  470. claude_mpm/services/agents/registry/__init__.py +30 -0
  471. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  472. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  473. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  474. claude_mpm/services/agents/sources/__init__.py +13 -0
  475. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  476. claude_mpm/services/agents/sources/git_source_sync_service.py +1205 -0
  477. claude_mpm/services/agents/startup_sync.py +262 -0
  478. claude_mpm/services/agents/toolchain_detector.py +478 -0
  479. claude_mpm/services/analysis/__init__.py +35 -0
  480. claude_mpm/services/analysis/clone_detector.py +1030 -0
  481. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  482. claude_mpm/services/analysis/postmortem_service.py +765 -0
  483. claude_mpm/services/async_session_logger.py +665 -0
  484. claude_mpm/services/claude_session_logger.py +321 -0
  485. claude_mpm/services/cli/__init__.py +18 -0
  486. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  487. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  488. claude_mpm/services/cli/agent_listing_service.py +463 -0
  489. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  490. claude_mpm/services/cli/agent_validation_service.py +590 -0
  491. claude_mpm/services/cli/memory_crud_service.py +622 -0
  492. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  493. claude_mpm/services/cli/resume_service.py +617 -0
  494. claude_mpm/services/cli/session_manager.py +604 -0
  495. claude_mpm/services/cli/session_pause_manager.py +504 -0
  496. claude_mpm/services/cli/session_resume_helper.py +372 -0
  497. claude_mpm/services/cli/startup_checker.py +362 -0
  498. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  499. claude_mpm/services/command_deployment_service.py +446 -0
  500. claude_mpm/services/command_handler_service.py +221 -0
  501. claude_mpm/services/communication/__init__.py +22 -0
  502. claude_mpm/services/core/__init__.py +108 -0
  503. claude_mpm/services/core/base.py +269 -0
  504. claude_mpm/services/core/cache_manager.py +309 -0
  505. claude_mpm/services/core/interfaces/__init__.py +273 -0
  506. claude_mpm/services/core/interfaces/agent.py +514 -0
  507. claude_mpm/services/core/interfaces/communication.py +316 -0
  508. claude_mpm/services/core/interfaces/health.py +169 -0
  509. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  510. claude_mpm/services/core/interfaces/model.py +281 -0
  511. claude_mpm/services/core/interfaces/process.py +372 -0
  512. claude_mpm/services/core/interfaces/project.py +121 -0
  513. claude_mpm/services/core/interfaces/restart.py +307 -0
  514. claude_mpm/services/core/interfaces/service.py +405 -0
  515. claude_mpm/services/core/interfaces/stability.py +260 -0
  516. claude_mpm/services/core/interfaces.py +81 -0
  517. claude_mpm/services/core/memory_manager.py +682 -0
  518. claude_mpm/services/core/models/__init__.py +70 -0
  519. claude_mpm/services/core/models/agent_config.py +384 -0
  520. claude_mpm/services/core/models/health.py +162 -0
  521. claude_mpm/services/core/models/process.py +239 -0
  522. claude_mpm/services/core/models/restart.py +302 -0
  523. claude_mpm/services/core/models/stability.py +264 -0
  524. claude_mpm/services/core/models/toolchain.py +306 -0
  525. claude_mpm/services/core/path_resolver.py +517 -0
  526. claude_mpm/services/core/service_container.py +520 -0
  527. claude_mpm/services/core/service_interfaces.py +436 -0
  528. claude_mpm/services/diagnostics/__init__.py +18 -0
  529. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  530. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  531. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  532. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  533. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  534. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  535. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  536. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  537. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  538. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  539. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  540. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  541. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  542. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  543. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  544. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  545. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  546. claude_mpm/services/diagnostics/models.py +138 -0
  547. claude_mpm/services/event_aggregator.py +582 -0
  548. claude_mpm/services/event_bus/__init__.py +18 -0
  549. claude_mpm/services/event_bus/config.py +186 -0
  550. claude_mpm/services/event_bus/direct_relay.py +312 -0
  551. claude_mpm/services/event_bus/event_bus.py +396 -0
  552. claude_mpm/services/event_bus/relay.py +326 -0
  553. claude_mpm/services/events/__init__.py +44 -0
  554. claude_mpm/services/events/consumers/__init__.py +18 -0
  555. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  556. claude_mpm/services/events/consumers/logging.py +184 -0
  557. claude_mpm/services/events/consumers/metrics.py +241 -0
  558. claude_mpm/services/events/consumers/socketio.py +377 -0
  559. claude_mpm/services/events/core.py +480 -0
  560. claude_mpm/services/events/interfaces.py +214 -0
  561. claude_mpm/services/events/producers/__init__.py +14 -0
  562. claude_mpm/services/events/producers/hook.py +269 -0
  563. claude_mpm/services/events/producers/system.py +329 -0
  564. claude_mpm/services/exceptions.py +433 -353
  565. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  566. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  567. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  568. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  569. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  570. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  571. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  572. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  573. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  574. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  575. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  576. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  577. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  578. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  579. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  580. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  581. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  582. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  583. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  584. claude_mpm/services/git/__init__.py +21 -0
  585. claude_mpm/services/git/git_operations_service.py +579 -0
  586. claude_mpm/services/github/__init__.py +21 -0
  587. claude_mpm/services/github/github_cli_service.py +397 -0
  588. claude_mpm/services/hook_installer_service.py +506 -0
  589. claude_mpm/services/hook_service.py +159 -111
  590. claude_mpm/services/infrastructure/__init__.py +52 -0
  591. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  592. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  593. claude_mpm/services/infrastructure/logging.py +209 -0
  594. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  595. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  596. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  597. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  598. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  599. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  600. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  601. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  602. claude_mpm/services/infrastructure/monitoring.py +71 -0
  603. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  604. claude_mpm/services/instructions/__init__.py +9 -0
  605. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  606. claude_mpm/services/local_ops/__init__.py +155 -0
  607. claude_mpm/services/local_ops/crash_detector.py +257 -0
  608. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  609. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  610. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  611. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  612. claude_mpm/services/local_ops/health_manager.py +427 -0
  613. claude_mpm/services/local_ops/log_monitor.py +396 -0
  614. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  615. claude_mpm/services/local_ops/process_manager.py +595 -0
  616. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  617. claude_mpm/services/local_ops/restart_manager.py +401 -0
  618. claude_mpm/services/local_ops/restart_policy.py +387 -0
  619. claude_mpm/services/local_ops/state_manager.py +372 -0
  620. claude_mpm/services/local_ops/unified_manager.py +600 -0
  621. claude_mpm/services/mcp_config_manager.py +1542 -0
  622. claude_mpm/services/mcp_service_verifier.py +732 -0
  623. claude_mpm/services/memory/__init__.py +19 -0
  624. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  625. claude_mpm/services/memory/cache/__init__.py +14 -0
  626. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  627. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  628. claude_mpm/services/memory/failure_tracker.py +578 -0
  629. claude_mpm/services/memory/indexed_memory.py +648 -0
  630. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  631. claude_mpm/services/memory/router.py +951 -0
  632. claude_mpm/services/memory_hook_service.py +470 -0
  633. claude_mpm/services/model/__init__.py +147 -0
  634. claude_mpm/services/model/base_provider.py +365 -0
  635. claude_mpm/services/model/claude_provider.py +412 -0
  636. claude_mpm/services/model/model_router.py +452 -0
  637. claude_mpm/services/model/ollama_provider.py +415 -0
  638. claude_mpm/services/monitor/__init__.py +20 -0
  639. claude_mpm/services/monitor/daemon.py +698 -0
  640. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  641. claude_mpm/services/monitor/event_emitter.py +350 -0
  642. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  643. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  644. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  645. claude_mpm/services/monitor/handlers/file.py +264 -0
  646. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  647. claude_mpm/services/monitor/management/__init__.py +18 -0
  648. claude_mpm/services/monitor/management/health.py +124 -0
  649. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  650. claude_mpm/services/monitor/server.py +1493 -0
  651. claude_mpm/services/monitor_build_service.py +349 -0
  652. claude_mpm/services/native_agent_converter.py +356 -0
  653. claude_mpm/services/orphan_detection.py +786 -0
  654. claude_mpm/services/pm_skills_deployer.py +711 -0
  655. claude_mpm/services/port_manager.py +597 -0
  656. claude_mpm/services/pr/__init__.py +14 -0
  657. claude_mpm/services/pr/pr_template_service.py +329 -0
  658. claude_mpm/services/profile_manager.py +337 -0
  659. claude_mpm/services/project/__init__.py +44 -0
  660. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  661. claude_mpm/services/project/analyzer_v2.py +566 -0
  662. claude_mpm/services/project/architecture_analyzer.py +461 -0
  663. claude_mpm/services/project/archive_manager.py +1045 -0
  664. claude_mpm/services/project/dependency_analyzer.py +462 -0
  665. claude_mpm/services/project/detection_strategies.py +719 -0
  666. claude_mpm/services/project/documentation_manager.py +554 -0
  667. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  668. claude_mpm/services/project/language_analyzer.py +265 -0
  669. claude_mpm/services/project/metrics_collector.py +407 -0
  670. claude_mpm/services/project/project_organizer.py +1009 -0
  671. claude_mpm/services/project/registry.py +636 -0
  672. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  673. claude_mpm/services/project_port_allocator.py +596 -0
  674. claude_mpm/services/recovery_manager.py +293 -240
  675. claude_mpm/services/response_tracker.py +267 -0
  676. claude_mpm/services/runner_configuration_service.py +605 -0
  677. claude_mpm/services/self_upgrade_service.py +608 -0
  678. claude_mpm/services/session_management_service.py +314 -0
  679. claude_mpm/services/session_manager.py +380 -0
  680. claude_mpm/services/shared/__init__.py +21 -0
  681. claude_mpm/services/shared/async_service_base.py +216 -0
  682. claude_mpm/services/shared/config_service_base.py +301 -0
  683. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  684. claude_mpm/services/shared/manager_base.py +315 -0
  685. claude_mpm/services/shared/service_factory.py +309 -0
  686. claude_mpm/services/skills/__init__.py +21 -0
  687. claude_mpm/services/skills/git_skill_source_manager.py +1340 -0
  688. claude_mpm/services/skills/selective_skill_deployer.py +743 -0
  689. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  690. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  691. claude_mpm/services/skills_config.py +547 -0
  692. claude_mpm/services/skills_deployer.py +1168 -0
  693. claude_mpm/services/socketio/__init__.py +25 -0
  694. claude_mpm/services/socketio/client_proxy.py +229 -0
  695. claude_mpm/services/socketio/dashboard_server.py +362 -0
  696. claude_mpm/services/socketio/event_normalizer.py +798 -0
  697. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  698. claude_mpm/services/socketio/handlers/base.py +136 -0
  699. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  700. claude_mpm/services/socketio/handlers/connection.py +643 -0
  701. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  702. claude_mpm/services/socketio/handlers/file.py +263 -0
  703. claude_mpm/services/socketio/handlers/git.py +962 -0
  704. claude_mpm/services/socketio/handlers/hook.py +211 -0
  705. claude_mpm/services/socketio/handlers/memory.py +26 -0
  706. claude_mpm/services/socketio/handlers/project.py +24 -0
  707. claude_mpm/services/socketio/handlers/registry.py +214 -0
  708. claude_mpm/services/socketio/migration_utils.py +343 -0
  709. claude_mpm/services/socketio/monitor_client.py +364 -0
  710. claude_mpm/services/socketio/server/__init__.py +18 -0
  711. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  712. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  713. claude_mpm/services/socketio/server/core.py +1079 -0
  714. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  715. claude_mpm/services/socketio/server/main.py +501 -0
  716. claude_mpm/services/socketio_client_manager.py +173 -143
  717. claude_mpm/services/socketio_server.py +38 -1657
  718. claude_mpm/services/subprocess_launcher_service.py +322 -0
  719. claude_mpm/services/system_instructions_service.py +270 -0
  720. claude_mpm/services/ticket_manager.py +25 -209
  721. claude_mpm/services/ticket_services/__init__.py +26 -0
  722. claude_mpm/services/ticket_services/crud_service.py +328 -0
  723. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  724. claude_mpm/services/ticket_services/search_service.py +324 -0
  725. claude_mpm/services/ticket_services/validation_service.py +303 -0
  726. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  727. claude_mpm/services/unified/__init__.py +65 -0
  728. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  729. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  730. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  731. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  732. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  733. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  734. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  735. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  736. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  737. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  738. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  739. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  740. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  741. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  742. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  743. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  744. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  745. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  746. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  747. claude_mpm/services/unified/interfaces.py +475 -0
  748. claude_mpm/services/unified/migration.py +509 -0
  749. claude_mpm/services/unified/strategies.py +534 -0
  750. claude_mpm/services/unified/unified_analyzer.py +542 -0
  751. claude_mpm/services/unified/unified_config.py +691 -0
  752. claude_mpm/services/unified/unified_deployment.py +466 -0
  753. claude_mpm/services/utility_service.py +280 -0
  754. claude_mpm/services/version_control/__init__.py +34 -37
  755. claude_mpm/services/version_control/branch_strategy.py +26 -17
  756. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  757. claude_mpm/services/version_control/git_operations.py +183 -49
  758. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  759. claude_mpm/services/version_control/version_parser.py +546 -0
  760. claude_mpm/services/version_service.py +379 -0
  761. claude_mpm/services/visualization/__init__.py +15 -0
  762. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  763. claude_mpm/skills/__init__.py +42 -0
  764. claude_mpm/skills/agent_skills_injector.py +324 -0
  765. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  766. claude_mpm/skills/bundled/__init__.py +6 -0
  767. claude_mpm/skills/bundled/api-documentation.md +393 -0
  768. claude_mpm/skills/bundled/async-testing.md +571 -0
  769. claude_mpm/skills/bundled/code-review.md +143 -0
  770. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  771. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  772. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  773. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  774. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  775. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  776. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  777. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  778. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  779. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  780. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  781. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  782. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  783. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  784. claude_mpm/skills/bundled/database-migration.md +199 -0
  785. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  786. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  787. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  788. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  789. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  790. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  791. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  792. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  793. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  794. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  795. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  796. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  797. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  798. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  799. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  800. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  801. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  802. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  803. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  804. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  805. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  806. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  807. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  808. claude_mpm/skills/bundled/git-workflow.md +414 -0
  809. claude_mpm/skills/bundled/imagemagick.md +204 -0
  810. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  811. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  812. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  813. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  814. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  815. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  816. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  817. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  818. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  819. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  820. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  821. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  822. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  823. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  824. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  825. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  826. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  827. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  828. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  829. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  830. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  831. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  832. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  833. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  834. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  835. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  836. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  837. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  838. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  839. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  840. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  841. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  842. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  843. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  844. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  845. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  846. claude_mpm/skills/bundled/pdf.md +141 -0
  847. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  848. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  849. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  850. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  851. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  852. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  853. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  854. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  855. claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
  856. claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
  857. claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
  858. claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
  859. claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
  860. claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
  861. claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
  862. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  863. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  864. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  865. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  866. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  867. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  868. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  869. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  870. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  871. claude_mpm/skills/bundled/security-scanning.md +439 -0
  872. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  873. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  874. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  875. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  876. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  877. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  878. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  879. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  880. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  881. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  882. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  883. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  884. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  885. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  886. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  887. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  888. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  889. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  890. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  891. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  892. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  893. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  894. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  895. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  896. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  897. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  898. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  899. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  900. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  901. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  902. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  903. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  904. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  905. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  906. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  907. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  908. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  909. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  910. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  911. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  912. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  913. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  914. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  915. claude_mpm/skills/bundled/xlsx.md +157 -0
  916. claude_mpm/skills/registry.py +286 -0
  917. claude_mpm/skills/skill_manager.py +405 -0
  918. claude_mpm/skills/skills_registry.py +347 -0
  919. claude_mpm/skills/skills_service.py +739 -0
  920. claude_mpm/storage/__init__.py +9 -0
  921. claude_mpm/storage/state_storage.py +546 -0
  922. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  923. claude_mpm/templates/questions/__init__.py +38 -0
  924. claude_mpm/templates/questions/base.py +193 -0
  925. claude_mpm/templates/questions/pr_strategy.py +311 -0
  926. claude_mpm/templates/questions/project_init.py +385 -0
  927. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  928. claude_mpm/ticket_wrapper.py +2 -2
  929. claude_mpm/tools/__init__.py +10 -0
  930. claude_mpm/tools/__main__.py +208 -0
  931. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  932. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  933. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  934. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  935. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  936. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  937. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  938. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  939. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  940. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  941. claude_mpm/tools/code_tree_builder.py +631 -0
  942. claude_mpm/tools/code_tree_events.py +420 -0
  943. claude_mpm/tools/socketio_debug.py +671 -0
  944. claude_mpm/utils/__init__.py +8 -8
  945. claude_mpm/utils/agent_dependency_loader.py +1189 -0
  946. claude_mpm/utils/agent_filters.py +261 -0
  947. claude_mpm/utils/common.py +544 -0
  948. claude_mpm/utils/config_manager.py +168 -126
  949. claude_mpm/utils/console.py +11 -0
  950. claude_mpm/utils/database_connector.py +298 -0
  951. claude_mpm/utils/dependency_cache.py +373 -0
  952. claude_mpm/utils/dependency_manager.py +60 -59
  953. claude_mpm/utils/dependency_strategies.py +381 -0
  954. claude_mpm/utils/display_helper.py +260 -0
  955. claude_mpm/utils/environment_context.py +313 -0
  956. claude_mpm/utils/error_handler.py +78 -66
  957. claude_mpm/utils/file_utils.py +305 -0
  958. claude_mpm/utils/framework_detection.py +12 -11
  959. claude_mpm/utils/git_analyzer.py +407 -0
  960. claude_mpm/utils/gitignore.py +244 -0
  961. claude_mpm/utils/import_migration_example.py +12 -60
  962. claude_mpm/utils/imports.py +48 -45
  963. claude_mpm/utils/log_cleanup.py +627 -0
  964. claude_mpm/utils/migration.py +372 -0
  965. claude_mpm/utils/path_operations.py +110 -104
  966. claude_mpm/utils/progress.py +387 -0
  967. claude_mpm/utils/robust_installer.py +844 -0
  968. claude_mpm/utils/session_logging.py +121 -0
  969. claude_mpm/utils/structured_questions.py +619 -0
  970. claude_mpm/utils/subprocess_utils.py +343 -0
  971. claude_mpm/validation/__init__.py +1 -1
  972. claude_mpm/validation/agent_validator.py +214 -108
  973. claude_mpm/validation/frontmatter_validator.py +252 -0
  974. claude_mpm-5.4.85.dist-info/METADATA +1023 -0
  975. claude_mpm-5.4.85.dist-info/RECORD +980 -0
  976. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
  977. claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
  978. claude_mpm-5.4.85.dist-info/licenses/LICENSE-FAQ.md +153 -0
  979. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  980. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  981. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  982. claude_mpm/agents/base_agent_loader.py +0 -529
  983. claude_mpm/agents/schema/agent_schema.json +0 -314
  984. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  985. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  986. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  987. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  988. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  989. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  990. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  991. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  992. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  993. claude_mpm/agents/templates/data_engineer.json +0 -110
  994. claude_mpm/agents/templates/documentation.json +0 -109
  995. claude_mpm/agents/templates/engineer.json +0 -113
  996. claude_mpm/agents/templates/ops.json +0 -109
  997. claude_mpm/agents/templates/pm.json +0 -25
  998. claude_mpm/agents/templates/qa.json +0 -111
  999. claude_mpm/agents/templates/research.json +0 -65
  1000. claude_mpm/agents/templates/security.json +0 -113
  1001. claude_mpm/agents/templates/test_integration.json +0 -112
  1002. claude_mpm/agents/templates/version_control.json +0 -107
  1003. claude_mpm/cli/commands/ui.py +0 -57
  1004. claude_mpm/core/simple_runner.py +0 -1046
  1005. claude_mpm/dashboard/open_dashboard.py +0 -34
  1006. claude_mpm/deployment_paths.py +0 -261
  1007. claude_mpm/hooks/builtin/__init__.py +0 -1
  1008. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  1009. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  1010. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  1011. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  1012. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  1013. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  1014. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  1015. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  1016. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  1017. claude_mpm/orchestration/__init__.py +0 -6
  1018. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  1019. claude_mpm/orchestration/archive/factory.py +0 -215
  1020. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  1021. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  1022. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  1023. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  1024. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  1025. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  1026. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  1027. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  1028. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  1029. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  1030. claude_mpm/schemas/workflow_validator.py +0 -411
  1031. claude_mpm/services/agent_deployment.py +0 -1534
  1032. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  1033. claude_mpm/services/agent_memory_manager.py +0 -1415
  1034. claude_mpm/services/agent_registry.py +0 -676
  1035. claude_mpm/services/deployed_agent_discovery.py +0 -226
  1036. claude_mpm/services/framework_agent_loader.py +0 -337
  1037. claude_mpm/services/framework_claude_md_generator.py +0 -621
  1038. claude_mpm/services/health_monitor.py +0 -892
  1039. claude_mpm/services/memory_router.py +0 -538
  1040. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  1041. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  1042. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  1043. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  1044. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  1045. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  1046. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  1047. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  1048. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  1049. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  1050. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  1051. claude_mpm/services/standalone_socketio_server.py +0 -1300
  1052. claude_mpm/services/ticket_manager_di.py +0 -318
  1053. claude_mpm/services/ticketing_service_original.py +0 -508
  1054. claude_mpm/ui/__init__.py +0 -1
  1055. claude_mpm/ui/rich_terminal_ui.py +0 -295
  1056. claude_mpm/ui/terminal_ui.py +0 -328
  1057. claude_mpm/utils/paths.py +0 -289
  1058. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  1059. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  1060. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  1061. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
  1062. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
@@ -1,114 +1,137 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Unified Agent Loader System
4
- ==========================
5
-
6
- This module provides a unified system for loading and managing AI agent configurations
7
- from JSON template files. It serves as the central registry for all agent types in the
8
- Claude MPM system, handling discovery, validation, caching, and dynamic model selection.
9
-
10
- Architecture Overview:
11
- ----------------------
12
- The agent loader follows a plugin-like architecture where agents are discovered from
13
- JSON template files in a designated directory. Each agent is validated against a
14
- standardized schema before being registered for use.
15
-
16
- Key Features:
17
- -------------
18
- - Automatic agent discovery from src/claude_mpm/agents/templates/*.json files
19
- - Schema validation ensures all agents conform to the expected structure
20
- - Intelligent caching using SharedPromptCache for performance optimization
21
- - Dynamic model selection based on task complexity analysis
22
- - Backward compatibility with legacy get_*_agent_prompt() functions
23
- - Prepends base instructions to maintain consistency across all agents
24
-
25
- Design Decisions:
26
- -----------------
27
- 1. JSON-based Configuration: We chose JSON over YAML or Python files for:
28
- - Schema validation support
29
- - Language-agnostic configuration
30
- - Easy parsing and generation by tools
31
-
32
- 2. Lazy Loading with Caching: Agents are loaded on-demand and cached to:
33
- - Reduce startup time
34
- - Minimize memory usage for unused agents
35
- - Allow hot-reloading during development
36
-
37
- 3. Dynamic Model Selection: The system can analyze task complexity to:
38
- - Optimize cost by using appropriate model tiers
39
- - Improve performance for simple tasks
40
- - Ensure complex tasks get sufficient model capabilities
3
+ Unified Agent Loader System - Main Entry Point
4
+ ==============================================
5
+
6
+ This module provides the main entry point for the unified agent loading system.
7
+ The system has been refactored into smaller, focused modules for better maintainability:
8
+
9
+ - agent_registry.py: Core agent discovery and registry management
10
+ - agent_cache.py: Caching mechanisms for performance optimization
11
+ - agent_validator.py: Schema validation and error handling
12
+ - model_selector.py: Dynamic model selection based on task complexity
13
+ - legacy_support.py: Backward compatibility functions
14
+ - async_loader.py: High-performance async loading operations
15
+ - metrics_collector.py: Performance monitoring and telemetry
16
+
17
+ This main module provides the unified interface while delegating to specialized modules.
41
18
 
42
19
  Usage Examples:
43
20
  --------------
44
21
  from claude_mpm.agents.agent_loader import get_documentation_agent_prompt
45
-
22
+
46
23
  # Get agent prompt using backward-compatible function
47
24
  prompt = get_documentation_agent_prompt()
48
-
25
+
49
26
  # Get agent with model selection info
50
- prompt, model, config = get_agent_prompt("research_agent",
27
+ prompt, model, config = get_agent_prompt("research_agent",
51
28
  return_model_info=True,
52
29
  task_description="Analyze codebase")
53
-
30
+
54
31
  # List all available agents
55
32
  agents = list_available_agents()
56
33
  """
57
34
 
58
- import json
59
- import logging
60
35
  import os
61
36
  import time
62
- import yaml
37
+ from enum import Enum
63
38
  from pathlib import Path
64
- from typing import Optional, Dict, Any, Tuple, Union, List
65
-
66
- from ..services.shared_prompt_cache import SharedPromptCache
67
- from .base_agent_loader import prepend_base_instructions
68
- from ..validation.agent_validator import AgentValidator, ValidationResult
69
- from ..utils.paths import PathResolver
70
-
71
- # Temporary placeholders for missing module
72
- # WHY: These classes would normally come from a task_complexity module, but
73
- # we've included them here temporarily to avoid breaking dependencies.
74
- # This allows the agent loader to function independently while the full
75
- # complexity analysis system is being developed.
76
- class ComplexityLevel:
77
- """Represents the complexity level of a task for model selection."""
78
- LOW = "LOW" # Simple tasks suitable for fast, economical models
79
- MEDIUM = "MEDIUM" # Standard tasks requiring balanced capabilities
80
- HIGH = "HIGH" # Complex tasks needing advanced reasoning
81
-
82
- class ModelType:
83
- """Claude model tiers used for dynamic selection based on task complexity."""
84
- HAIKU = "haiku" # Fast, economical model for simple tasks
85
- SONNET = "sonnet" # Balanced model for general-purpose tasks
86
- OPUS = "opus" # Most capable model for complex reasoning
39
+ from typing import Any, Dict, List, Optional, Tuple, Union
40
+
41
+ from claude_mpm.core.enums import AgentCategory
87
42
 
88
43
  # Module-level logger
89
- logger = logging.getLogger(__name__)
44
+ from claude_mpm.core.logging_utils import get_logger
45
+
46
+ # Import modular components
47
+ from claude_mpm.core.unified_agent_registry import AgentTier, get_agent_registry
48
+ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
49
+
50
+ from ..core.agent_name_normalizer import AgentNameNormalizer
51
+
52
+ logger = get_logger(__name__)
53
+
54
+
55
+ class ModelType(str, Enum):
56
+ """Claude model types for agent configuration."""
57
+
58
+ HAIKU = "haiku"
59
+ SONNET = "sonnet"
60
+ OPUS = "opus"
61
+
62
+
63
+ class ComplexityLevel(str, Enum):
64
+ """Task complexity levels for model selection."""
65
+
66
+ LOW = "low"
67
+ MEDIUM = "medium"
68
+ HIGH = "high"
69
+
70
+
71
+ # Re-export key classes and functions
72
+ __all__ = [
73
+ "AgentLoader",
74
+ "AgentTier",
75
+ "get_agent_prompt",
76
+ "get_agent_tier",
77
+ "list_agents_by_tier",
78
+ "list_available_agents",
79
+ "reload_agents",
80
+ "validate_agent_files",
81
+ ]
82
+
83
+
84
+ def _get_agent_templates_dirs() -> Dict[AgentTier, Optional[Path]]:
85
+ """
86
+ Get directories containing agent JSON files across all tiers.
87
+
88
+ SIMPLIFIED ARCHITECTURE:
89
+ - SOURCE: ~/.claude-mpm/cache/agents/ (git cache from GitHub)
90
+ - DEPLOYMENT: .claude/agents/ (project-level Claude Code discovery)
91
+
92
+ This function is kept for backward compatibility but the tier-based
93
+ system is being phased out in favor of the simplified architecture.
94
+
95
+ Returns:
96
+ Dict mapping AgentTier to Path (or None if not available)
97
+ """
98
+ dirs = {}
99
+
100
+ # PROJECT tier - Deprecated in simplified architecture
101
+ # Agents are now deployed to .claude/agents/ directly
102
+ project_dir = Path.cwd() / ".claude" / "agents"
103
+ if project_dir.exists():
104
+ dirs[AgentTier.PROJECT] = project_dir
105
+ logger.debug(f"Found PROJECT agents at: {project_dir}")
106
+
107
+ # USER tier - Deprecated in simplified architecture
108
+ # (Kept for backward compatibility but not actively used)
109
+
110
+ # SYSTEM tier - built-in agents
111
+ system_dir = Path(__file__).parent / "templates"
112
+ if system_dir.exists():
113
+ dirs[AgentTier.SYSTEM] = system_dir
114
+ logger.debug(f"Found SYSTEM agents at: {system_dir}")
115
+
116
+ return dirs
90
117
 
91
118
 
92
119
  def _get_agent_templates_dir() -> Path:
93
120
  """
94
- Get the directory containing agent template JSON files.
95
-
96
- WHY: We use a function instead of a direct constant to ensure the path
97
- is always resolved relative to this module's location, making the code
98
- portable across different installation methods (pip install, development mode, etc.).
99
-
121
+ Get the primary directory containing agent JSON files.
122
+
123
+ DEPRECATED: Use _get_agent_templates_dirs() for tier-aware loading.
124
+ This function is kept for backward compatibility.
125
+
100
126
  Returns:
101
- Path: Absolute path to the templates directory
127
+ Path: Absolute path to the system agents directory
102
128
  """
103
129
  return Path(__file__).parent / "templates"
104
130
 
105
131
 
106
- # Agent templates directory - where all agent JSON files are stored
132
+ # Agent directory - where all agent JSON files are stored
107
133
  AGENT_TEMPLATES_DIR = _get_agent_templates_dir()
108
134
 
109
- # Cache prefix for agent prompts - versioned to allow cache invalidation on schema changes
110
- # WHY: The "v2:" suffix allows us to invalidate all cached prompts when we make
111
- # breaking changes to the agent schema format
112
135
  AGENT_CACHE_PREFIX = "agent_prompt:v2:"
113
136
 
114
137
  # Model configuration thresholds for dynamic selection
@@ -118,394 +141,350 @@ AGENT_CACHE_PREFIX = "agent_prompt:v2:"
118
141
  MODEL_THRESHOLDS = {
119
142
  ModelType.HAIKU: {"min_complexity": 0, "max_complexity": 30},
120
143
  ModelType.SONNET: {"min_complexity": 31, "max_complexity": 70},
121
- ModelType.OPUS: {"min_complexity": 71, "max_complexity": 100}
144
+ ModelType.OPUS: {"min_complexity": 71, "max_complexity": 100},
122
145
  }
123
146
 
124
- # Model name mappings for Claude API
125
- # WHY: These map our internal model types to the actual API model identifiers.
126
- # The specific versions are chosen for their stability and feature completeness.
127
147
  MODEL_NAME_MAPPINGS = {
128
- ModelType.HAIKU: "claude-3-haiku-20240307", # Fast, cost-effective
129
- ModelType.SONNET: "claude-sonnet-4-20250514", # Balanced performance
130
- ModelType.OPUS: "claude-opus-4-20250514" # Maximum capability
148
+ ModelType.HAIKU: "claude-3-haiku-20240307", # Fast, cost-effective
149
+ ModelType.SONNET: "claude-sonnet-4-20250514", # Balanced performance
150
+ ModelType.OPUS: "claude-opus-4-20250514", # Maximum capability
131
151
  }
132
152
 
133
153
 
134
154
  class AgentLoader:
135
155
  """
136
- Central registry for loading and managing agent configurations.
137
-
138
- This class implements the core agent discovery and management system. It:
139
- 1. Discovers agent JSON files from the templates directory
140
- 2. Validates each agent against the standardized schema
141
- 3. Maintains an in-memory registry of valid agents
142
- 4. Provides caching for performance optimization
143
- 5. Supports dynamic agent reloading
144
-
145
- METRICS COLLECTION OPPORTUNITIES:
146
- - Agent load times and cache hit rates
147
- - Validation performance by agent type
148
- - Agent usage frequency and patterns
149
- - Model selection distribution
150
- - Task complexity analysis results
151
- - Memory usage for agent templates
152
- - Error rates during loading/validation
153
- - Agent prompt size distributions
154
-
155
- The loader follows a singleton-like pattern through the module-level
156
- _loader instance to ensure consistent state across the application.
157
-
158
- Attributes:
159
- validator: AgentValidator instance for schema validation
160
- cache: SharedPromptCache instance for performance optimization
161
- _agent_registry: Internal dictionary mapping agent IDs to their configurations
156
+ Simplified Agent Loader - Clean interface to agent registry.
157
+
158
+ This class provides a simple, focused interface for agent loading:
159
+ - AgentRegistry: Core agent discovery and registry management
160
+ - Direct file access (no caching complexity)
161
+ - Simple, testable design
162
+
163
+ The simplified design provides:
164
+ - Clean separation of concerns
165
+ - Easy testability
166
+ - Minimal complexity
167
+ - Fast, direct file access
162
168
  """
163
-
169
+
164
170
  def __init__(self):
165
171
  """
166
- Initialize the agent loader and discover available agents.
167
-
172
+ Initialize the agent loader with the registry.
173
+
168
174
  The initialization process:
169
- 1. Creates validator for schema checking
170
- 2. Gets shared cache instance for performance
171
- 3. Initializes empty agent registry
172
- 4. Triggers agent discovery and loading
173
-
174
- METRICS OPPORTUNITIES:
175
- - Track initialization time
176
- - Monitor agent discovery performance
177
- - Count total agents loaded vs validation failures
178
- - Measure memory footprint of loaded agents
179
-
180
- WHY: We load agents eagerly during initialization to:
181
- - Detect configuration errors early
182
- - Build the registry once for efficient access
183
- - Validate all agents before the system starts using them
175
+ 1. Creates the agent registry
176
+ 2. Loads agents from all tiers
184
177
  """
185
- self.validator = AgentValidator()
186
- self.cache = SharedPromptCache.get_instance()
187
- self._agent_registry: Dict[str, Dict[str, Any]] = {}
188
-
189
- # METRICS: Initialize performance tracking
190
- # This structure collects valuable telemetry for AI agent performance
191
- self._metrics = {
192
- 'agents_loaded': 0,
193
- 'validation_failures': 0,
194
- 'cache_hits': 0,
195
- 'cache_misses': 0,
196
- 'load_times': {}, # agent_id -> load time ms
197
- 'usage_counts': {}, # agent_id -> usage count
198
- 'model_selections': {}, # model -> count
199
- 'complexity_scores': [], # Distribution of task complexity
200
- 'prompt_sizes': {}, # agent_id -> prompt size in chars
201
- 'error_types': {}, # error_type -> count
202
- 'initialization_time_ms': 0
203
- }
204
-
205
- # METRICS: Track initialization performance
206
178
  start_time = time.time()
207
- self._load_agents()
208
- self._metrics['initialization_time_ms'] = (time.time() - start_time) * 1000
209
- logger.debug(f"Agent loader initialized in {self._metrics['initialization_time_ms']:.2f}ms")
210
-
211
- def _load_agents(self) -> None:
212
- """
213
- Discover and load all valid agents from the templates directory.
214
-
215
- This method implements the agent discovery mechanism:
216
- 1. Scans the templates directory for JSON files
217
- 2. Skips the schema definition file
218
- 3. Loads and validates each potential agent file
219
- 4. Registers valid agents in the internal registry
220
-
221
- WHY: We use a file-based discovery mechanism because:
222
- - It allows easy addition of new agents without code changes
223
- - Agents can be distributed as simple JSON files
224
- - The system remains extensible and maintainable
225
-
226
- Error Handling:
227
- - Invalid JSON files are logged but don't stop the loading process
228
- - Schema validation failures are logged with details
229
- - The system continues to function with whatever valid agents it finds
230
- """
231
- logger.info(f"Loading agents from {AGENT_TEMPLATES_DIR}")
232
-
233
- for json_file in AGENT_TEMPLATES_DIR.glob("*.json"):
234
- # Skip the schema definition file itself
235
- if json_file.name == "agent_schema.json":
236
- continue
237
-
238
- try:
239
- with open(json_file, 'r') as f:
240
- agent_data = json.load(f)
241
-
242
- # Validate against schema to ensure consistency
243
- validation_result = self.validator.validate_agent(agent_data)
244
-
245
- if validation_result.is_valid:
246
- agent_id = agent_data.get("agent_id")
247
- if agent_id:
248
- self._agent_registry[agent_id] = agent_data
249
- # METRICS: Track successful agent load
250
- self._metrics['agents_loaded'] += 1
251
- logger.debug(f"Loaded agent: {agent_id}")
252
- else:
253
- # Log validation errors but continue loading other agents
254
- # METRICS: Track validation failure
255
- self._metrics['validation_failures'] += 1
256
- logger.warning(f"Invalid agent in {json_file.name}: {validation_result.errors}")
257
-
258
- except Exception as e:
259
- # Log loading errors but don't crash - system should be resilient
260
- logger.error(f"Failed to load {json_file.name}: {e}")
261
-
179
+
180
+ # Initialize the agent registry
181
+ self.registry = get_agent_registry()
182
+
183
+ # Load agents through registry
184
+ self.registry.load_agents()
185
+
186
+ init_time = (time.time() - start_time) * 1000
187
+ logger.debug(
188
+ f"AgentLoader initialized in {init_time:.2f}ms with {len(self.registry._agent_registry)} agents"
189
+ )
190
+
262
191
  def get_agent(self, agent_id: str) -> Optional[Dict[str, Any]]:
263
192
  """
264
193
  Retrieve agent configuration by ID.
265
-
194
+
266
195
  Args:
267
- agent_id: Unique identifier for the agent (e.g., "research_agent")
268
-
196
+ agent_id: Agent identifier
197
+
269
198
  Returns:
270
- Dict containing the full agent configuration, or None if not found
271
-
272
- WHY: Direct dictionary lookup for O(1) performance, essential for
273
- frequently accessed agents during runtime.
199
+ Agent configuration or None if not found
274
200
  """
275
- return self._agent_registry.get(agent_id)
276
-
201
+ return self.registry.get_agent(agent_id)
202
+
277
203
  def list_agents(self) -> List[Dict[str, Any]]:
278
204
  """
279
205
  Get a summary list of all available agents.
280
-
206
+
281
207
  Returns:
282
- List of agent summaries containing key metadata fields
283
-
284
- WHY: We return a summary instead of full configurations to:
285
- - Reduce memory usage when listing many agents
286
- - Provide only the information needed for agent selection
287
- - Keep the API response size manageable
288
-
289
- The returned list is sorted by ID for consistent ordering across calls.
208
+ List of agent summaries with key metadata
290
209
  """
291
- agents = []
292
- for agent_id, agent_data in self._agent_registry.items():
293
- # Extract key fields from nested structure for easy consumption
294
- agents.append({
295
- "id": agent_id,
296
- "name": agent_data.get("metadata", {}).get("name", agent_id),
297
- "description": agent_data.get("metadata", {}).get("description", ""),
298
- "category": agent_data.get("metadata", {}).get("category", ""),
299
- "model": agent_data.get("capabilities", {}).get("model", ""),
300
- "resource_tier": agent_data.get("capabilities", {}).get("resource_tier", "")
301
- })
302
- return sorted(agents, key=lambda x: x["id"])
303
-
304
- def get_agent_prompt(self, agent_id: str, force_reload: bool = False) -> Optional[str]:
210
+ return self.registry.list_agents()
211
+
212
+ def get_agent_prompt(
213
+ self, agent_id: str, force_reload: bool = False
214
+ ) -> Optional[str]:
305
215
  """
306
- Retrieve agent instructions/prompt by ID with caching support.
307
-
216
+ Retrieve agent instructions/prompt by ID.
217
+
308
218
  Args:
309
- agent_id: Unique identifier for the agent
310
- force_reload: If True, bypass cache and reload from registry
311
-
219
+ agent_id: Agent identifier
220
+ force_reload: Ignored (kept for API compatibility)
221
+
312
222
  Returns:
313
- The agent's instruction prompt, or None if not found
314
-
315
- Caching Strategy:
316
- - Prompts are cached for 1 hour (3600 seconds) by default
317
- - Cache keys are versioned (v2:) to allow bulk invalidation
318
- - Force reload bypasses cache for development/debugging
319
-
320
- METRICS TRACKED:
321
- - Cache hit/miss rates for optimization
322
- - Agent usage frequency for popular agents
323
- - Prompt loading times for performance
324
- - Prompt sizes for memory analysis
325
-
326
- WHY: Caching is critical here because:
327
- - Agent prompts can be large (several KB)
328
- - They're accessed frequently during agent execution
329
- - They rarely change in production
330
- - The 1-hour TTL balances freshness with performance
223
+ Agent prompt string or None if not found
331
224
  """
332
- cache_key = f"{AGENT_CACHE_PREFIX}{agent_id}"
333
-
334
- # METRICS: Track usage count for this agent
335
- self._metrics['usage_counts'][agent_id] = self._metrics['usage_counts'].get(agent_id, 0) + 1
336
-
337
- # METRICS: Track load time
338
- load_start = time.time()
339
-
340
- # Check cache first unless force reload is requested
341
- if not force_reload:
342
- cached_content = self.cache.get(cache_key)
343
- if cached_content is not None:
344
- # METRICS: Track cache hit
345
- self._metrics['cache_hits'] += 1
346
- logger.debug(f"Agent prompt for '{agent_id}' loaded from cache")
347
- return str(cached_content)
348
-
349
- # METRICS: Track cache miss
350
- self._metrics['cache_misses'] += 1
351
-
352
- # Get agent data from registry
353
- agent_data = self.get_agent(agent_id)
225
+ agent_data = self.registry.get_agent(agent_id)
354
226
  if not agent_data:
355
- logger.warning(f"Agent not found: {agent_id}")
356
227
  return None
357
-
358
- # Extract instructions from the agent configuration
228
+
229
+ # Extract instructions
359
230
  instructions = agent_data.get("instructions", "")
360
231
  if not instructions:
361
- logger.warning(f"No instructions found for agent: {agent_id}")
232
+ logger.warning(f"Agent '{agent_id}' has no instructions")
362
233
  return None
363
-
364
- # METRICS: Track prompt size for memory analysis
365
- self._metrics['prompt_sizes'][agent_id] = len(instructions)
366
-
367
- # METRICS: Record load time
368
- load_time_ms = (time.time() - load_start) * 1000
369
- self._metrics['load_times'][agent_id] = load_time_ms
370
-
371
- # Cache the content with 1 hour TTL for performance
372
- self.cache.set(cache_key, instructions, ttl=3600)
373
- logger.debug(f"Agent prompt for '{agent_id}' cached successfully")
374
-
234
+
375
235
  return instructions
376
-
377
- def get_metrics(self) -> Dict[str, Any]:
378
- """
379
- Get collected performance metrics.
380
-
381
- Returns:
382
- Dictionary containing:
383
- - Cache performance (hit rate, miss rate)
384
- - Agent usage statistics
385
- - Load time analysis
386
- - Memory usage patterns
387
- - Error tracking
388
-
389
- This data could be:
390
- - Exposed via monitoring endpoints
391
- - Logged periodically for analysis
392
- - Used for capacity planning
393
- - Fed to AI operations platforms
394
- """
395
- cache_total = self._metrics['cache_hits'] + self._metrics['cache_misses']
396
- cache_hit_rate = 0.0
397
- if cache_total > 0:
398
- cache_hit_rate = (self._metrics['cache_hits'] / cache_total) * 100
399
-
400
- # Calculate average load times
401
- avg_load_time = 0.0
402
- if self._metrics['load_times']:
403
- avg_load_time = sum(self._metrics['load_times'].values()) / len(self._metrics['load_times'])
404
-
405
- # Find most used agents
406
- top_agents = sorted(
407
- self._metrics['usage_counts'].items(),
408
- key=lambda x: x[1],
409
- reverse=True
410
- )[:5]
411
-
412
- return {
413
- 'initialization_time_ms': self._metrics['initialization_time_ms'],
414
- 'agents_loaded': self._metrics['agents_loaded'],
415
- 'validation_failures': self._metrics['validation_failures'],
416
- 'cache_hit_rate_percent': cache_hit_rate,
417
- 'cache_hits': self._metrics['cache_hits'],
418
- 'cache_misses': self._metrics['cache_misses'],
419
- 'average_load_time_ms': avg_load_time,
420
- 'top_agents_by_usage': dict(top_agents),
421
- 'model_selection_distribution': self._metrics['model_selections'].copy(),
422
- 'prompt_size_stats': {
423
- 'total_agents': len(self._metrics['prompt_sizes']),
424
- 'average_size': sum(self._metrics['prompt_sizes'].values()) / len(self._metrics['prompt_sizes']) if self._metrics['prompt_sizes'] else 0,
425
- 'max_size': max(self._metrics['prompt_sizes'].values()) if self._metrics['prompt_sizes'] else 0,
426
- 'min_size': min(self._metrics['prompt_sizes'].values()) if self._metrics['prompt_sizes'] else 0
427
- },
428
- 'error_types': self._metrics['error_types'].copy()
429
- }
430
-
236
+
431
237
  def get_agent_metadata(self, agent_id: str) -> Optional[Dict[str, Any]]:
432
238
  """
433
239
  Get comprehensive agent metadata including capabilities and configuration.
434
-
240
+
435
241
  Args:
436
- agent_id: Unique identifier for the agent
437
-
242
+ agent_id: Agent identifier
243
+
438
244
  Returns:
439
- Dictionary containing all agent metadata except instructions,
440
- or None if agent not found
441
-
442
- WHY: This method provides access to agent configuration without
443
- including the potentially large instruction text. This is useful for:
444
- - UI displays showing agent capabilities
445
- - Programmatic agent selection based on features
446
- - Debugging and introspection
447
-
448
- The returned structure mirrors the JSON schema sections for consistency.
245
+ Agent metadata dictionary or None if not found
449
246
  """
450
- agent_data = self.get_agent(agent_id)
247
+ agent_data = self.registry.get_agent(agent_id)
451
248
  if not agent_data:
452
249
  return None
453
-
454
- return {
455
- "id": agent_id,
456
- "version": agent_data.get("version", "1.0.0"),
457
- "metadata": agent_data.get("metadata", {}), # Name, description, category
458
- "capabilities": agent_data.get("capabilities", {}), # Model, tools, features
459
- "knowledge": agent_data.get("knowledge", {}), # Domain expertise
460
- "interactions": agent_data.get("interactions", {}) # User interaction patterns
250
+
251
+ metadata = agent_data.get("metadata", {})
252
+ capabilities = agent_data.get("capabilities", {})
253
+ tier = self.registry.get_agent_tier(agent_id)
254
+
255
+ # Check for project memory
256
+ has_memory = capabilities.get("has_project_memory", False)
257
+
258
+ # Get category with enum validation (fallback to GENERAL if invalid)
259
+ category_str = metadata.get("category", "general")
260
+ try:
261
+ category = AgentCategory(category_str)
262
+ except ValueError:
263
+ logger.warning(
264
+ f"Invalid category '{category_str}' for agent {agent_id}, using GENERAL"
265
+ )
266
+ category = AgentCategory.GENERAL
267
+
268
+ result = {
269
+ "agent_id": agent_id,
270
+ "name": metadata.get("name", agent_id),
271
+ "description": metadata.get("description", ""),
272
+ "category": category.value, # Store as string for backward compatibility
273
+ "version": metadata.get("version", "1.0.0"),
274
+ "model": agent_data.get("model", "claude-sonnet-4-20250514"),
275
+ "resource_tier": agent_data.get("resource_tier", "standard"),
276
+ "tier": tier.value if tier else "unknown",
277
+ "tools": agent_data.get("tools", []),
278
+ "capabilities": capabilities,
279
+ "source_file": agent_data.get("_source_file", "unknown"),
280
+ "has_project_memory": has_memory,
461
281
  }
462
282
 
283
+ # Add memory-specific information if present
284
+ if has_memory:
285
+ result["memory_size_kb"] = capabilities.get("memory_size_kb", 0)
286
+ result["memory_file"] = capabilities.get("memory_file", "")
287
+ result["memory_lines"] = capabilities.get("memory_lines", 0)
288
+ result["memory_enhanced"] = True
289
+
290
+ return result
291
+
292
+ def reload(self) -> None:
293
+ """
294
+ Reload all agents from disk, clearing the registry.
295
+ """
296
+ logger.debug("Reloading agent system...")
463
297
 
464
- # Global loader instance - singleton pattern for consistent state
465
- # WHY: We use a module-level singleton because:
466
- # - Agent configurations should be consistent across the application
467
- # - Loading and validation only needs to happen once
468
- # - Multiple loaders would lead to cache inconsistencies
298
+ # Reload registry
299
+ self.registry.reload()
300
+
301
+ logger.debug(
302
+ f"Agent system reloaded with {len(self.registry._agent_registry)} agents"
303
+ )
304
+
305
+
306
+ # Global loader instance (singleton pattern)
469
307
  _loader: Optional[AgentLoader] = None
470
308
 
471
309
 
472
310
  def _get_loader() -> AgentLoader:
473
311
  """
474
312
  Get or create the global agent loader instance (singleton pattern).
475
-
313
+
476
314
  Returns:
477
- AgentLoader: The single global instance
478
-
479
- WHY: The singleton pattern ensures:
480
- - Agents are loaded and validated only once
481
- - All parts of the application see the same agent registry
482
- - Cache state remains consistent
483
- - Memory usage is minimized
484
-
485
- Thread Safety: Python's GIL makes this simple implementation thread-safe
486
- for the single assignment operation.
315
+ AgentLoader: The global agent loader instance
487
316
  """
488
317
  global _loader
489
318
  if _loader is None:
319
+ logger.debug("Initializing global agent loader")
490
320
  _loader = AgentLoader()
491
321
  return _loader
492
322
 
493
323
 
494
- def load_agent_prompt_from_md(agent_name: str, force_reload: bool = False) -> Optional[str]:
324
+ # Removed duplicate get_agent_prompt function - using the comprehensive version below
325
+
326
+
327
+ def list_available_agents() -> Dict[str, Dict[str, Any]]:
328
+ """
329
+ List all available agents with their key metadata including memory information.
330
+
331
+ Returns:
332
+ Dictionary mapping agent IDs to their metadata
333
+ """
334
+ loader = _get_loader()
335
+ agents_list = loader.list_agents()
336
+
337
+ # Convert list to dictionary for easier access
338
+ agents_dict = {}
339
+ for agent in agents_list:
340
+ agent_id = agent["id"]
341
+ agent_info = {
342
+ "name": agent["name"],
343
+ "description": agent["description"],
344
+ "category": agent["category"],
345
+ "version": agent.get("version", "1.0.0"),
346
+ "model": agent.get("model", "claude-sonnet-4-20250514"),
347
+ "resource_tier": agent.get("resource_tier", "standard"),
348
+ "tier": agent.get("tier", "system"),
349
+ "has_project_memory": agent.get("has_project_memory", False),
350
+ }
351
+
352
+ # Add memory details if present
353
+ if agent.get("has_project_memory", False):
354
+ agent_info["memory_size_kb"] = agent.get("memory_size_kb", 0)
355
+ agent_info["memory_file"] = agent.get("memory_file", "")
356
+ agent_info["memory_lines"] = agent.get("memory_lines", 0)
357
+
358
+ agents_dict[agent_id] = agent_info
359
+
360
+ return agents_dict
361
+
362
+
363
+ def validate_agent_files() -> Dict[str, Dict[str, Any]]:
364
+ """
365
+ Validate all agent template files against the schema.
366
+
367
+ Returns:
368
+ Dictionary mapping agent names to validation results
369
+ """
370
+ loader = _get_loader()
371
+ agents = loader.list_agents()
372
+ results = {}
373
+
374
+ for agent in agents:
375
+ agent_id = agent["id"]
376
+ agent_data = loader.get_agent(agent_id)
377
+ if agent_data:
378
+ results[agent_id] = {"valid": True, "errors": [], "warnings": []}
379
+ else:
380
+ results[agent_id] = {
381
+ "valid": False,
382
+ "errors": ["Agent not found"],
383
+ "warnings": [],
384
+ }
385
+
386
+ return results
387
+
388
+
389
+ def reload_agents() -> None:
390
+ """
391
+ Force reload all agents from disk, clearing the registry.
392
+ """
393
+ global _loader
394
+ if _loader:
395
+ _loader.reload()
396
+ else:
397
+ # Clear the global instance to force reinitialization
398
+ _loader = None
399
+
400
+ logger.debug("Agent registry cleared, will reload on next access")
401
+
402
+
403
+ def get_agent_tier(agent_name: str) -> Optional[str]:
404
+ """
405
+ Get the tier from which an agent was loaded.
406
+
407
+ Args:
408
+ agent_name: Agent identifier
409
+
410
+ Returns:
411
+ Tier name or None if agent not found
412
+ """
413
+ loader = _get_loader()
414
+ tier = loader.registry.get_agent_tier(agent_name)
415
+ return tier.value if tier else None
416
+
417
+
418
+ def list_agents_by_tier() -> Dict[str, List[str]]:
419
+ """
420
+ List available agents organized by their tier.
421
+
422
+ Returns:
423
+ Dictionary mapping tier names to lists of agent IDs
424
+ """
425
+ loader = _get_loader()
426
+ agents = loader.list_agents()
427
+
428
+ result = {tier.value: [] for tier in AgentTier}
429
+
430
+ for agent in agents:
431
+ tier = agent.get("tier", "system")
432
+ if tier in result:
433
+ result[tier].append(agent["id"])
434
+
435
+ return result
436
+
437
+
438
+ # Duplicate functions removed - using the ones defined earlier
439
+
440
+
441
+ def get_agent_metadata(agent_id: str) -> Optional[Dict[str, Any]]:
442
+ """
443
+ Get agent metadata without instruction content.
444
+
445
+ WHY: This method provides access to agent configuration without
446
+ including the potentially large instruction text. This is useful for:
447
+ - UI displays showing agent capabilities
448
+ - Programmatic agent selection based on features
449
+ - Debugging and introspection
450
+
451
+ The returned structure mirrors the JSON schema sections for consistency.
452
+ """
453
+ loader = AgentLoader()
454
+ agent_data = loader.get_agent(agent_id)
455
+ if not agent_data:
456
+ return None
457
+
458
+ return {
459
+ "id": agent_id,
460
+ "version": agent_data.get("version", "1.0.0"),
461
+ "metadata": agent_data.get("metadata", {}), # Name, description, category
462
+ "capabilities": agent_data.get("capabilities", {}), # Model, tools, features
463
+ "knowledge": agent_data.get("knowledge", {}), # Domain expertise
464
+ "interactions": agent_data.get("interactions", {}), # User interaction patterns
465
+ }
466
+
467
+
468
+ # Duplicate _get_loader function removed - using the one defined earlier
469
+
470
+
471
+ def load_agent_prompt_from_md(
472
+ agent_name: str, force_reload: bool = False
473
+ ) -> Optional[str]:
495
474
  """
496
475
  Load agent prompt from JSON template (legacy function name).
497
-
476
+
498
477
  Args:
499
478
  agent_name: Agent name (matches agent ID in new schema)
500
479
  force_reload: Force reload from file, bypassing cache
501
-
480
+
502
481
  Returns:
503
482
  str: Agent instructions from JSON template, or None if not found
504
-
483
+
505
484
  NOTE: Despite the "md" in the function name, this loads from JSON files.
506
485
  The name is kept for backward compatibility with existing code that
507
486
  expects this interface. New code should use get_agent_prompt() directly.
508
-
487
+
509
488
  WHY: This wrapper exists to maintain backward compatibility during the
510
489
  migration from markdown-based agents to JSON-based agents.
511
490
  """
@@ -513,10 +492,12 @@ def load_agent_prompt_from_md(agent_name: str, force_reload: bool = False) -> Op
513
492
  return loader.get_agent_prompt(agent_name, force_reload)
514
493
 
515
494
 
516
- def _analyze_task_complexity(task_description: str, context_size: int = 0, **kwargs: Any) -> Dict[str, Any]:
495
+ def _analyze_task_complexity(
496
+ task_description: str, context_size: int = 0, **kwargs: Any
497
+ ) -> Dict[str, Any]:
517
498
  """
518
499
  Analyze task complexity to determine optimal model selection.
519
-
500
+
520
501
  Args:
521
502
  task_description: Description of the task to analyze
522
503
  context_size: Size of context in characters (affects complexity)
@@ -524,7 +505,7 @@ def _analyze_task_complexity(task_description: str, context_size: int = 0, **kwa
524
505
  - code_analysis: Whether code analysis is required
525
506
  - multi_step: Whether the task involves multiple steps
526
507
  - domain_expertise: Required domain knowledge level
527
-
508
+
528
509
  Returns:
529
510
  Dictionary containing:
530
511
  - complexity_score: Numeric score 0-100
@@ -532,14 +513,14 @@ def _analyze_task_complexity(task_description: str, context_size: int = 0, **kwa
532
513
  - recommended_model: Suggested Claude model tier
533
514
  - optimal_prompt_size: Recommended prompt size range
534
515
  - error: Error message if analysis fails
535
-
516
+
536
517
  WHY: This is a placeholder implementation that returns sensible defaults.
537
518
  The actual TaskComplexityAnalyzer module would use NLP techniques to:
538
519
  - Analyze task description for complexity indicators
539
520
  - Consider context size and memory requirements
540
521
  - Factor in domain-specific requirements
541
522
  - Optimize for cost vs capability trade-offs
542
-
523
+
543
524
  Current Implementation: Returns medium complexity as a safe default that
544
525
  works well for most tasks while the full analyzer is being developed.
545
526
  """
@@ -550,37 +531,39 @@ def _analyze_task_complexity(task_description: str, context_size: int = 0, **kwa
550
531
  "complexity_level": ComplexityLevel.MEDIUM,
551
532
  "recommended_model": ModelType.SONNET,
552
533
  "optimal_prompt_size": (700, 1000),
553
- "error": "TaskComplexityAnalyzer module not available"
534
+ "error": "TaskComplexityAnalyzer module not available",
554
535
  }
555
536
 
556
537
 
557
- def _get_model_config(agent_name: str, complexity_analysis: Optional[Dict[str, Any]] = None) -> Tuple[str, Dict[str, Any]]:
538
+ def _get_model_config(
539
+ agent_name: str, complexity_analysis: Optional[Dict[str, Any]] = None
540
+ ) -> Tuple[str, Dict[str, Any]]:
558
541
  """
559
542
  Determine optimal model configuration based on agent type and task complexity.
560
-
543
+
561
544
  METRICS TRACKED:
562
545
  - Model selection distribution
563
546
  - Complexity score distribution
564
547
  - Dynamic vs static selection rates
565
-
548
+
566
549
  Args:
567
- agent_name: Name of the agent requesting model selection
550
+ agent_name: Name of the agent requesting model selection (already normalized to agent_id format)
568
551
  complexity_analysis: Results from task complexity analysis (if available)
569
-
552
+
570
553
  Returns:
571
554
  Tuple of (selected_model, model_config) where:
572
555
  - selected_model: Claude API model identifier
573
556
  - model_config: Dictionary with selection metadata
574
-
557
+
575
558
  Model Selection Strategy:
576
559
  1. Each agent has a default model defined in its capabilities
577
560
  2. Dynamic selection can override based on task complexity
578
561
  3. Environment variables can control selection behavior
579
-
562
+
580
563
  Environment Variables:
581
564
  - ENABLE_DYNAMIC_MODEL_SELECTION: Global toggle (default: true)
582
565
  - CLAUDE_PM_{AGENT}_MODEL_SELECTION: Per-agent override
583
-
566
+
584
567
  WHY: This flexible approach allows:
585
568
  - Cost optimization by using cheaper models for simple tasks
586
569
  - Performance optimization by using powerful models only when needed
@@ -589,77 +572,99 @@ def _get_model_config(agent_name: str, complexity_analysis: Optional[Dict[str, A
589
572
  """
590
573
  loader = _get_loader()
591
574
  agent_data = loader.get_agent(agent_name)
592
-
575
+
593
576
  if not agent_data:
594
577
  # Fallback for unknown agents - use Sonnet as safe default
595
578
  return "claude-sonnet-4-20250514", {"selection_method": "default"}
596
-
579
+
597
580
  # Get model from agent capabilities (agent's preferred model)
598
- default_model = agent_data.get("capabilities", {}).get("model", "claude-sonnet-4-20250514")
599
-
581
+ default_model = agent_data.get("capabilities", {}).get(
582
+ "model", "claude-sonnet-4-20250514"
583
+ )
584
+
600
585
  # Check if dynamic model selection is enabled globally
601
- enable_dynamic_selection = os.getenv('ENABLE_DYNAMIC_MODEL_SELECTION', 'true').lower() == 'true'
602
-
586
+ enable_dynamic_selection = (
587
+ os.getenv("ENABLE_DYNAMIC_MODEL_SELECTION", "true").lower() == "true"
588
+ )
589
+
603
590
  # Check for per-agent override in environment
604
591
  # This allows fine-grained control over specific agents
605
592
  agent_override_key = f"CLAUDE_PM_{agent_name.upper()}_MODEL_SELECTION"
606
- agent_override = os.getenv(agent_override_key, '').lower()
607
-
608
- if agent_override == 'true':
593
+ agent_override = os.getenv(agent_override_key, "").lower()
594
+
595
+ if agent_override == "true":
609
596
  enable_dynamic_selection = True
610
- elif agent_override == 'false':
597
+ elif agent_override == "false":
611
598
  enable_dynamic_selection = False
612
-
599
+
613
600
  # Apply dynamic model selection based on task complexity
614
601
  if enable_dynamic_selection and complexity_analysis:
615
- recommended_model = complexity_analysis.get('recommended_model', ModelType.SONNET)
602
+ recommended_model = complexity_analysis.get(
603
+ "recommended_model", ModelType.SONNET
604
+ )
616
605
  selected_model = MODEL_NAME_MAPPINGS.get(recommended_model, default_model)
617
-
606
+
618
607
  # METRICS: Track complexity scores for distribution analysis
619
- complexity_score = complexity_analysis.get('complexity_score', 50)
620
- if hasattr(loader, '_metrics'):
621
- loader._metrics['complexity_scores'].append(complexity_score)
608
+ complexity_score = complexity_analysis.get("complexity_score", 50)
609
+ if hasattr(loader, "_metrics"):
610
+ loader._metrics["complexity_scores"].append(complexity_score)
622
611
  # Keep only last 1000 scores for memory efficiency
623
- if len(loader._metrics['complexity_scores']) > 1000:
624
- loader._metrics['complexity_scores'] = loader._metrics['complexity_scores'][-1000:]
625
-
612
+ if len(loader._metrics["complexity_scores"]) > 1000:
613
+ loader._metrics["complexity_scores"] = loader._metrics[
614
+ "complexity_scores"
615
+ ][-1000:]
616
+
626
617
  model_config = {
627
618
  "selection_method": "dynamic_complexity_based",
628
619
  "complexity_score": complexity_score,
629
- "complexity_level": complexity_analysis.get('complexity_level', ComplexityLevel.MEDIUM),
630
- "optimal_prompt_size": complexity_analysis.get('optimal_prompt_size', (700, 1000)),
631
- "default_model": default_model
620
+ "complexity_level": complexity_analysis.get(
621
+ "complexity_level", ComplexityLevel.MEDIUM
622
+ ),
623
+ "optimal_prompt_size": complexity_analysis.get(
624
+ "optimal_prompt_size", (700, 1000)
625
+ ),
626
+ "default_model": default_model,
632
627
  }
633
628
  else:
634
629
  # Use agent's default model when dynamic selection is disabled
635
630
  selected_model = default_model
636
631
  model_config = {
637
632
  "selection_method": "agent_default",
638
- "reason": "dynamic_selection_disabled" if not enable_dynamic_selection else "no_complexity_analysis",
639
- "default_model": default_model
633
+ "reason": (
634
+ "dynamic_selection_disabled"
635
+ if not enable_dynamic_selection
636
+ else "no_complexity_analysis"
637
+ ),
638
+ "default_model": default_model,
640
639
  }
641
-
640
+
642
641
  # METRICS: Track model selection distribution
643
642
  # This helps understand model usage patterns and costs
644
- if hasattr(loader, '_metrics'):
645
- loader._metrics['model_selections'][selected_model] = \
646
- loader._metrics['model_selections'].get(selected_model, 0) + 1
647
-
643
+ if hasattr(loader, "_metrics"):
644
+ loader._metrics["model_selections"][selected_model] = (
645
+ loader._metrics["model_selections"].get(selected_model, 0) + 1
646
+ )
647
+
648
648
  return selected_model, model_config
649
649
 
650
650
 
651
- def get_agent_prompt(agent_name: str, force_reload: bool = False, return_model_info: bool = False, **kwargs: Any) -> Union[str, Tuple[str, str, Dict[str, Any]]]:
651
+ def get_agent_prompt(
652
+ agent_name: str,
653
+ force_reload: bool = False,
654
+ return_model_info: bool = False,
655
+ **kwargs: Any,
656
+ ) -> Union[str, Tuple[str, str, Dict[str, Any]]]:
652
657
  """
653
658
  Get agent prompt with optional dynamic model selection and base instructions.
654
-
659
+
655
660
  This is the primary interface for retrieving agent prompts. It handles:
656
661
  1. Loading the agent's instructions from the registry
657
662
  2. Optionally analyzing task complexity for model selection
658
663
  3. Prepending base instructions for consistency
659
664
  4. Adding metadata about model selection decisions
660
-
665
+
661
666
  Args:
662
- agent_name: Agent ID (e.g., "research_agent", "qa_agent")
667
+ agent_name: Agent name in any format (e.g., "Engineer", "research_agent", "QA")
663
668
  force_reload: Force reload from source, bypassing cache
664
669
  return_model_info: If True, returns extended info tuple
665
670
  **kwargs: Additional arguments:
@@ -667,194 +672,127 @@ def get_agent_prompt(agent_name: str, force_reload: bool = False, return_model_i
667
672
  - context_size: Size of context in characters
668
673
  - enable_complexity_analysis: Toggle complexity analysis (default: True)
669
674
  - Additional task-specific parameters
670
-
675
+
671
676
  Returns:
672
677
  If return_model_info=False: Complete agent prompt string
673
678
  If return_model_info=True: Tuple of (prompt, selected_model, model_config)
674
-
679
+
675
680
  Raises:
676
681
  ValueError: If the requested agent is not found
677
-
682
+
678
683
  Processing Flow:
679
- 1. Load agent instructions (with caching)
680
- 2. Analyze task complexity (if enabled and task_description provided)
681
- 3. Determine optimal model based on complexity
682
- 4. Add model selection metadata to prompt
683
- 5. Prepend base instructions
684
- 6. Return appropriate format based on return_model_info
685
-
684
+ 1. Normalize agent name to correct agent ID
685
+ 2. Load agent instructions (with caching)
686
+ 3. Analyze task complexity (if enabled and task_description provided)
687
+ 4. Determine optimal model based on complexity
688
+ 5. Add model selection metadata to prompt
689
+ 6. Prepend base instructions
690
+ 7. Return appropriate format based on return_model_info
691
+
686
692
  WHY: This comprehensive approach ensures:
687
693
  - Consistent prompt structure across all agents
688
694
  - Optimal model selection for cost/performance
689
695
  - Transparency in model selection decisions
690
696
  - Flexibility for different use cases
691
697
  """
698
+ # Normalize the agent name to handle various formats
699
+ # Convert names like "Engineer", "Research", "QA" to the correct agent IDs
700
+ normalizer = AgentNameNormalizer()
701
+ loader = _get_loader()
702
+
703
+ # First check if agent exists with exact name
704
+ if loader.get_agent(agent_name):
705
+ actual_agent_id = agent_name
706
+ # Then check with _agent suffix
707
+ elif loader.get_agent(f"{agent_name}_agent"):
708
+ actual_agent_id = f"{agent_name}_agent"
709
+ # Check if this looks like it might already be an agent ID
710
+ elif agent_name.endswith("_agent"):
711
+ actual_agent_id = agent_name
712
+ else:
713
+ # Get the normalized key (e.g., "engineer", "research", "qa")
714
+ # First check if the agent name is recognized by the normalizer
715
+ cleaned = agent_name.strip().lower().replace("-", "_")
716
+
717
+ # Check if this is a known alias or canonical name
718
+ if cleaned in normalizer.ALIASES or cleaned in normalizer.CANONICAL_NAMES:
719
+ agent_key = normalizer.to_key(agent_name)
720
+ # Try both with and without _agent suffix
721
+ if loader.get_agent(agent_key):
722
+ actual_agent_id = agent_key
723
+ elif loader.get_agent(f"{agent_key}_agent"):
724
+ actual_agent_id = f"{agent_key}_agent"
725
+ else:
726
+ actual_agent_id = agent_key # Use normalized key
727
+ # Unknown agent name - check both variations
728
+ elif loader.get_agent(cleaned):
729
+ actual_agent_id = cleaned
730
+ elif loader.get_agent(f"{cleaned}_agent"):
731
+ actual_agent_id = f"{cleaned}_agent"
732
+ else:
733
+ actual_agent_id = cleaned # Use cleaned name
734
+
735
+ # Log the normalization for debugging
736
+ if agent_name != actual_agent_id:
737
+ logger.debug(f"Normalized agent name '{agent_name}' to '{actual_agent_id}'")
738
+
692
739
  # Load from JSON template via the loader
693
- prompt = load_agent_prompt_from_md(agent_name, force_reload)
694
-
740
+ prompt = load_agent_prompt_from_md(actual_agent_id, force_reload)
741
+
695
742
  if prompt is None:
696
- raise ValueError(f"No agent found with ID: {agent_name}")
697
-
743
+ raise ValueError(
744
+ f"No agent found with name: {agent_name} (normalized to: {actual_agent_id})"
745
+ )
746
+
698
747
  # Analyze task complexity if task description is provided
699
748
  complexity_analysis = None
700
- task_description = kwargs.get('task_description', '')
701
- enable_analysis = kwargs.get('enable_complexity_analysis', True)
702
-
749
+ task_description = kwargs.get("task_description", "")
750
+ enable_analysis = kwargs.get("enable_complexity_analysis", True)
751
+
703
752
  if task_description and enable_analysis:
704
753
  # Extract relevant kwargs for complexity analysis
705
- complexity_kwargs = {k: v for k, v in kwargs.items()
706
- if k not in ['task_description', 'context_size', 'enable_complexity_analysis']}
754
+ complexity_kwargs = {
755
+ k: v
756
+ for k, v in kwargs.items()
757
+ if k
758
+ not in ["task_description", "context_size", "enable_complexity_analysis"]
759
+ }
707
760
  complexity_analysis = _analyze_task_complexity(
708
761
  task_description=task_description,
709
- context_size=kwargs.get('context_size', 0),
710
- **complexity_kwargs
762
+ context_size=kwargs.get("context_size", 0),
763
+ **complexity_kwargs,
711
764
  )
712
-
765
+
713
766
  # Get model configuration based on agent and complexity
714
- selected_model, model_config = _get_model_config(agent_name, complexity_analysis)
715
-
767
+ # Pass the normalized agent ID to _get_model_config
768
+ selected_model, model_config = _get_model_config(
769
+ actual_agent_id, complexity_analysis
770
+ )
771
+
716
772
  # Add model selection metadata to prompt for transparency
717
773
  # This helps with debugging and understanding model choices
718
- if selected_model and model_config.get('selection_method') == 'dynamic_complexity_based':
774
+ if (
775
+ selected_model
776
+ and model_config.get("selection_method") == "dynamic_complexity_based"
777
+ ):
719
778
  model_metadata = f"\n<!-- Model Selection: {selected_model} (Complexity: {model_config.get('complexity_level', 'UNKNOWN')}) -->\n"
720
779
  prompt = model_metadata + prompt
721
-
722
- # Prepend base instructions with dynamic template based on complexity
723
- # The base instructions provide common guidelines all agents should follow
724
- complexity_score = model_config.get('complexity_score', 50) if model_config else 50
725
- final_prompt = prepend_base_instructions(prompt, complexity_score=complexity_score)
726
-
780
+
727
781
  # Return format based on caller's needs
728
782
  if return_model_info:
729
- return final_prompt, selected_model, model_config
730
- else:
731
- return final_prompt
732
-
733
-
734
- # Backward-compatible functions
735
- # WHY: These functions exist to maintain backward compatibility with existing code
736
- # that expects agent-specific getter functions. New code should use get_agent_prompt()
737
- # directly with the agent_id parameter for more flexibility.
738
- #
739
- # DEPRECATION NOTE: These functions may be removed in a future major version.
740
- # They add maintenance overhead and limit extensibility compared to the generic interface.
741
-
742
- def get_documentation_agent_prompt() -> str:
743
- """
744
- Get the complete Documentation Agent prompt with base instructions.
745
-
746
- Returns:
747
- Complete prompt string ready for use with Claude API
748
-
749
- DEPRECATED: Use get_agent_prompt("documentation_agent") instead
750
- """
751
- prompt = get_agent_prompt("documentation_agent", return_model_info=False)
752
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
753
- return prompt
754
-
755
-
756
- def get_version_control_agent_prompt() -> str:
757
- """
758
- Get the complete Version Control Agent prompt with base instructions.
759
-
760
- Returns:
761
- Complete prompt string ready for use with Claude API
762
-
763
- DEPRECATED: Use get_agent_prompt("version_control_agent") instead
764
- """
765
- prompt = get_agent_prompt("version_control_agent", return_model_info=False)
766
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
767
- return prompt
768
-
769
-
770
- def get_qa_agent_prompt() -> str:
771
- """
772
- Get the complete QA Agent prompt with base instructions.
773
-
774
- Returns:
775
- Complete prompt string ready for use with Claude API
776
-
777
- DEPRECATED: Use get_agent_prompt("qa_agent") instead
778
- """
779
- prompt = get_agent_prompt("qa_agent", return_model_info=False)
780
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
781
- return prompt
782
-
783
-
784
- def get_research_agent_prompt() -> str:
785
- """
786
- Get the complete Research Agent prompt with base instructions.
787
-
788
- Returns:
789
- Complete prompt string ready for use with Claude API
790
-
791
- DEPRECATED: Use get_agent_prompt("research_agent") instead
792
- """
793
- prompt = get_agent_prompt("research_agent", return_model_info=False)
794
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
795
- return prompt
796
-
797
-
798
- def get_ops_agent_prompt() -> str:
799
- """
800
- Get the complete Ops Agent prompt with base instructions.
801
-
802
- Returns:
803
- Complete prompt string ready for use with Claude API
804
-
805
- DEPRECATED: Use get_agent_prompt("ops_agent") instead
806
- """
807
- prompt = get_agent_prompt("ops_agent", return_model_info=False)
808
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
809
- return prompt
810
-
811
-
812
- def get_security_agent_prompt() -> str:
813
- """
814
- Get the complete Security Agent prompt with base instructions.
815
-
816
- Returns:
817
- Complete prompt string ready for use with Claude API
818
-
819
- DEPRECATED: Use get_agent_prompt("security_agent") instead
820
- """
821
- prompt = get_agent_prompt("security_agent", return_model_info=False)
822
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
783
+ return prompt, selected_model, model_config
823
784
  return prompt
824
785
 
825
786
 
826
- def get_engineer_agent_prompt() -> str:
827
- """
828
- Get the complete Engineer Agent prompt with base instructions.
829
-
830
- Returns:
831
- Complete prompt string ready for use with Claude API
832
-
833
- DEPRECATED: Use get_agent_prompt("engineer_agent") instead
834
- """
835
- prompt = get_agent_prompt("engineer_agent", return_model_info=False)
836
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
837
- return prompt
787
+ # Legacy hardcoded agent functions removed - use get_agent_prompt(agent_id) instead
838
788
 
839
789
 
840
- def get_data_engineer_agent_prompt() -> str:
841
- """
842
- Get the complete Data Engineer Agent prompt with base instructions.
843
-
844
- Returns:
845
- Complete prompt string ready for use with Claude API
846
-
847
- DEPRECATED: Use get_agent_prompt("data_engineer_agent") instead
848
- """
849
- prompt = get_agent_prompt("data_engineer_agent", return_model_info=False)
850
- assert isinstance(prompt, str), "Expected string when return_model_info=False"
851
- return prompt
852
-
853
-
854
- def get_agent_prompt_with_model_info(agent_name: str, force_reload: bool = False, **kwargs: Any) -> Tuple[str, str, Dict[str, Any]]:
790
+ def get_agent_prompt_with_model_info(
791
+ agent_name: str, force_reload: bool = False, **kwargs: Any
792
+ ) -> Tuple[str, str, Dict[str, Any]]:
855
793
  """
856
794
  Convenience wrapper to always get agent prompt with model selection information.
857
-
795
+
858
796
  Args:
859
797
  agent_name: Agent ID (e.g., "research_agent")
860
798
  force_reload: Force reload from source, bypassing cache
@@ -862,16 +800,16 @@ def get_agent_prompt_with_model_info(agent_name: str, force_reload: bool = False
862
800
  - task_description: For complexity analysis
863
801
  - context_size: For complexity scoring
864
802
  - Other task-specific parameters
865
-
803
+
866
804
  Returns:
867
805
  Tuple of (prompt, selected_model, model_config) where:
868
806
  - prompt: Complete agent prompt with base instructions
869
807
  - selected_model: Claude API model identifier
870
808
  - model_config: Dictionary with selection metadata
871
-
809
+
872
810
  WHY: This dedicated function ensures type safety for callers that always
873
811
  need model information, avoiding the need to handle Union types.
874
-
812
+
875
813
  Example:
876
814
  prompt, model, config = get_agent_prompt_with_model_info(
877
815
  "research_agent",
@@ -879,12 +817,14 @@ def get_agent_prompt_with_model_info(agent_name: str, force_reload: bool = False
879
817
  )
880
818
  print(f"Using model: {model} (method: {config['selection_method']})")
881
819
  """
882
- result = get_agent_prompt(agent_name, force_reload, return_model_info=True, **kwargs)
883
-
820
+ result = get_agent_prompt(
821
+ agent_name, force_reload, return_model_info=True, **kwargs
822
+ )
823
+
884
824
  # Type narrowing - we know this returns a tuple when return_model_info=True
885
825
  if isinstance(result, tuple):
886
826
  return result
887
-
827
+
888
828
  # Fallback (shouldn't happen with current implementation)
889
829
  # This defensive code ensures we always return the expected tuple format
890
830
  loader = _get_loader()
@@ -892,98 +832,46 @@ def get_agent_prompt_with_model_info(agent_name: str, force_reload: bool = False
892
832
  default_model = "claude-sonnet-4-20250514"
893
833
  if agent_data:
894
834
  default_model = agent_data.get("capabilities", {}).get("model", default_model)
895
-
835
+
896
836
  return result, default_model, {"selection_method": "default"}
897
837
 
898
838
 
899
839
  # Utility functions for agent management
900
840
 
901
- def list_available_agents() -> Dict[str, Dict[str, Any]]:
902
- """
903
- List all available agents with their key metadata.
904
-
905
- Returns:
906
- Dictionary mapping agent IDs to their metadata summaries
907
-
908
- The returned dictionary provides a comprehensive view of all registered
909
- agents, useful for:
910
- - UI agent selection interfaces
911
- - Documentation generation
912
- - System introspection and debugging
913
- - Programmatic agent discovery
914
-
915
- Example Return Value:
916
- {
917
- "research_agent": {
918
- "name": "Research Agent",
919
- "description": "Analyzes codebases...",
920
- "category": "analysis",
921
- "version": "1.0.0",
922
- "model": "claude-opus-4-20250514",
923
- "resource_tier": "standard",
924
- "tools": ["code_analysis", "search"]
925
- },
926
- ...
927
- }
928
-
929
- WHY: This aggregated view is more useful than raw agent data because:
930
- - It provides a consistent interface regardless of schema changes
931
- - It includes only the fields relevant for agent selection
932
- - It's optimized for UI display and decision making
933
- """
934
- loader = _get_loader()
935
- agents = {}
936
-
937
- for agent_info in loader.list_agents():
938
- agent_id = agent_info["id"]
939
- metadata = loader.get_agent_metadata(agent_id)
940
-
941
- if metadata:
942
- # Extract and flatten key information for easy consumption
943
- agents[agent_id] = {
944
- "name": metadata["metadata"].get("name", agent_id),
945
- "description": metadata["metadata"].get("description", ""),
946
- "category": metadata["metadata"].get("category", ""),
947
- "version": metadata["version"],
948
- "model": metadata["capabilities"].get("model", ""),
949
- "resource_tier": metadata["capabilities"].get("resource_tier", ""),
950
- "tools": metadata["capabilities"].get("tools", [])
951
- }
952
-
953
- return agents
841
+ # Duplicate list_available_agents function removed
954
842
 
955
843
 
956
844
  def clear_agent_cache(agent_name: Optional[str] = None) -> None:
957
845
  """
958
846
  Clear cached agent prompts for development or after updates.
959
-
847
+
960
848
  Args:
961
849
  agent_name: Specific agent ID to clear, or None to clear all agents
962
-
850
+
963
851
  This function is useful for:
964
852
  - Development when modifying agent prompts
965
853
  - Forcing reload after agent template updates
966
854
  - Troubleshooting caching issues
967
855
  - Memory management in long-running processes
968
-
856
+
969
857
  Examples:
970
858
  # Clear specific agent cache
971
859
  clear_agent_cache("research_agent")
972
-
860
+
973
861
  # Clear all agent caches
974
862
  clear_agent_cache()
975
-
863
+
976
864
  WHY: Manual cache management is important because:
977
865
  - Agent prompts have a 1-hour TTL but may need immediate refresh
978
866
  - Development requires seeing changes without waiting for TTL
979
867
  - System administrators need cache control for troubleshooting
980
-
868
+
981
869
  Error Handling: Failures are logged but don't raise exceptions to ensure
982
870
  the system remains operational even if cache clearing fails.
983
871
  """
984
872
  try:
985
873
  cache = SharedPromptCache.get_instance()
986
-
874
+
987
875
  if agent_name:
988
876
  # Clear specific agent's cache entry
989
877
  cache_key = f"{AGENT_CACHE_PREFIX}{agent_name}"
@@ -992,93 +880,20 @@ def clear_agent_cache(agent_name: Optional[str] = None) -> None:
992
880
  else:
993
881
  # Clear all agent caches by iterating through registry
994
882
  loader = _get_loader()
995
- for agent_id in loader._agent_registry.keys():
883
+ for agent_id in loader._agent_registry:
996
884
  cache_key = f"{AGENT_CACHE_PREFIX}{agent_id}"
997
885
  cache.invalidate(cache_key)
998
886
  logger.debug("All agent caches cleared")
999
-
887
+
1000
888
  except Exception as e:
1001
889
  # Log but don't raise - cache clearing shouldn't break the system
1002
890
  logger.error(f"Error clearing agent cache: {e}")
1003
891
 
1004
892
 
1005
- def validate_agent_files() -> Dict[str, Dict[str, Any]]:
1006
- """
1007
- Validate all agent template files against the schema.
1008
-
1009
- Returns:
1010
- Dictionary mapping agent names to validation results
1011
-
1012
- This function performs comprehensive validation of all agent files,
1013
- checking for:
1014
- - JSON syntax errors
1015
- - Schema compliance
1016
- - Required fields presence
1017
- - Data type correctness
1018
- - Constraint violations
1019
-
1020
- Return Format:
1021
- {
1022
- "agent_name": {
1023
- "valid": bool,
1024
- "errors": [list of error messages],
1025
- "warnings": [list of warning messages],
1026
- "file_path": "/full/path/to/file.json"
1027
- },
1028
- ...
1029
- }
1030
-
1031
- Use Cases:
1032
- - Pre-deployment validation in CI/CD
1033
- - Development-time agent verification
1034
- - Troubleshooting agent loading issues
1035
- - Automated testing of agent configurations
1036
-
1037
- WHY: Separate validation allows checking agents without loading them,
1038
- useful for CI/CD pipelines and development workflows where we want to
1039
- catch errors before runtime.
1040
- """
1041
- validator = AgentValidator()
1042
- results = {}
1043
-
1044
- for json_file in AGENT_TEMPLATES_DIR.glob("*.json"):
1045
- # Skip the schema definition file itself
1046
- if json_file.name == "agent_schema.json":
1047
- continue
1048
-
1049
- validation_result = validator.validate_file(json_file)
1050
- results[json_file.stem] = {
1051
- "valid": validation_result.is_valid,
1052
- "errors": validation_result.errors,
1053
- "warnings": validation_result.warnings,
1054
- "file_path": str(json_file)
1055
- }
1056
-
1057
- return results
893
+ # Duplicate list_agents_by_tier function removed
1058
894
 
895
+ # Duplicate validate_agent_files function removed
1059
896
 
1060
- def reload_agents() -> None:
1061
- """
1062
- Force reload all agents from disk, clearing the registry and cache.
1063
-
1064
- This function completely resets the agent loader state, causing:
1065
- 1. The global loader instance to be destroyed
1066
- 2. All cached agent prompts to be invalidated
1067
- 3. Fresh agent discovery on next access
1068
-
1069
- Use Cases:
1070
- - Hot-reloading during development
1071
- - Picking up new agent files without restart
1072
- - Recovering from corrupted state
1073
- - Testing agent loading logic
1074
-
1075
- WHY: Hot-reloading is essential for development productivity and
1076
- allows dynamic agent updates in production without service restart.
1077
-
1078
- Implementation Note: We simply clear the global loader reference.
1079
- The next call to _get_loader() will create a fresh instance that
1080
- re-discovers and re-validates all agents.
1081
- """
1082
- global _loader
1083
- _loader = None
1084
- logger.info("Agent registry cleared, will reload on next access")
897
+ # Duplicate reload_agents function removed
898
+
899
+ # Duplicate get_agent_tier function removed - using the one defined earlier