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.
- claude_mpm/BUILD_NUMBER +1 -0
- claude_mpm/VERSION +1 -0
- claude_mpm/__init__.py +50 -12
- claude_mpm/__main__.py +7 -2
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -0
- claude_mpm/agents/WORKFLOW.md +111 -0
- claude_mpm/agents/__init__.py +92 -80
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +560 -745
- claude_mpm/agents/agent_loader_integration.py +53 -55
- claude_mpm/agents/agents_metadata.py +186 -27
- claude_mpm/agents/async_agent_loader.py +436 -0
- claude_mpm/agents/base_agent.json +8 -4
- claude_mpm/agents/frontmatter_validator.py +754 -0
- claude_mpm/agents/system_agent_config.py +222 -155
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/__init__.py +17 -13
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/git-file-tracking.md +584 -0
- claude_mpm/agents/templates/pm-examples.md +474 -0
- claude_mpm/agents/templates/pm-red-flags.md +310 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/response-format.md +583 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/agents/templates/validation-templates.md +312 -0
- claude_mpm/cli/__init__.py +94 -128
- claude_mpm/cli/__main__.py +33 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +36 -12
- claude_mpm/cli/commands/agent_manager.py +1403 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +335 -0
- claude_mpm/cli/commands/agents.py +2501 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/aggregate.py +540 -0
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +1053 -0
- claude_mpm/cli/commands/cleanup.py +588 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/config.py +586 -0
- claude_mpm/cli/commands/configure.py +3253 -0
- claude_mpm/cli/commands/configure_agent_display.py +282 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +184 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +243 -0
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/info.py +195 -74
- claude_mpm/cli/commands/local_deploy.py +534 -0
- claude_mpm/cli/commands/mcp.py +205 -0
- claude_mpm/cli/commands/mcp_command_router.py +161 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +346 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
- claude_mpm/cli/commands/mcp_server_commands.py +155 -0
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +585 -846
- claude_mpm/cli/commands/monitor.py +228 -310
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +759 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +910 -488
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +1398 -0
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/commands/tickets.py +536 -53
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +298 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +31 -0
- claude_mpm/cli/interactive/agent_wizard.py +1927 -0
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +87 -563
- claude_mpm/cli/parsers/__init__.py +35 -0
- claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +575 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
- claude_mpm/cli/parsers/base_parser.py +649 -0
- claude_mpm/cli/parsers/config_parser.py +208 -0
- claude_mpm/cli/parsers/configure_parser.py +138 -0
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +195 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +142 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +157 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +277 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +205 -0
- claude_mpm/cli/shared/base_command.py +242 -0
- claude_mpm/cli/shared/error_handling.py +242 -0
- claude_mpm/cli/shared/output_formatters.py +241 -0
- claude_mpm/cli/startup.py +1578 -0
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/startup_logging.py +839 -0
- claude_mpm/cli/utils.py +136 -47
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +42 -64
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +20 -0
- claude_mpm/commands/mpm-help.md +20 -0
- claude_mpm/commands/mpm-init.md +120 -0
- claude_mpm/commands/mpm-monitor.md +31 -0
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +20 -0
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +20 -0
- claude_mpm/commands/mpm.md +31 -0
- claude_mpm/config/__init__.py +42 -2
- claude_mpm/config/agent_config.py +402 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +258 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/config/socketio_config.py +125 -83
- claude_mpm/constants.py +133 -22
- claude_mpm/core/__init__.py +62 -36
- claude_mpm/core/agent_name_normalizer.py +71 -73
- claude_mpm/core/agent_registry.py +385 -492
- claude_mpm/core/agent_session_manager.py +81 -70
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +159 -122
- claude_mpm/core/cache.py +560 -0
- claude_mpm/core/claude_runner.py +696 -916
- claude_mpm/core/config.py +613 -122
- claude_mpm/core/config_aliases.py +74 -73
- claude_mpm/core/config_constants.py +314 -0
- claude_mpm/core/constants.py +361 -0
- claude_mpm/core/container.py +646 -104
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/exceptions.py +536 -0
- claude_mpm/core/factories.py +105 -109
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +25 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +278 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +213 -0
- claude_mpm/core/framework/loaders/file_loader.py +176 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +485 -414
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +246 -86
- claude_mpm/core/hook_performance_config.py +147 -0
- claude_mpm/core/injectable_service.py +72 -63
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +670 -0
- claude_mpm/core/interfaces.py +570 -164
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/log_manager.py +707 -0
- claude_mpm/core/logger.py +295 -134
- claude_mpm/core/logging_config.py +474 -0
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/minimal_framework_loader.py +24 -22
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +594 -0
- claude_mpm/core/optimized_agent_loader.py +479 -0
- claude_mpm/core/optimized_startup.py +554 -0
- claude_mpm/core/output_style_manager.py +491 -0
- claude_mpm/core/pm_hook_interceptor.py +197 -82
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/service_registry.py +153 -116
- claude_mpm/core/session_manager.py +179 -64
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +326 -0
- claude_mpm/core/shared/path_resolver.py +281 -0
- claude_mpm/core/shared/singleton_manager.py +221 -0
- claude_mpm/core/socketio_pool.py +400 -137
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/tool_access_control.py +64 -57
- claude_mpm/core/types.py +307 -0
- claude_mpm/core/typing_utils.py +553 -0
- claude_mpm/core/unified_agent_registry.py +969 -0
- claude_mpm/core/unified_config.py +612 -0
- claude_mpm/core/unified_paths.py +958 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +104 -89
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +76 -66
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +37 -32
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
- claude_mpm/hooks/claude_hooks/installer.py +806 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
- claude_mpm/hooks/failure_learning/__init__.py +54 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +179 -0
- claude_mpm/hooks/memory_integration_hook.py +201 -107
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +92 -76
- claude_mpm/hooks/validation_hooks.py +62 -54
- claude_mpm/init.py +518 -83
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +40 -23
- claude_mpm/models/agent_session.py +538 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/claude-hook-handler.sh +227 -0
- claude_mpm/scripts/launch_monitor.py +165 -0
- claude_mpm/scripts/mpm_doctor.py +322 -0
- claude_mpm/scripts/socketio_daemon.py +189 -200
- claude_mpm/scripts/start_activity_logging.py +91 -0
- claude_mpm/services/__init__.py +208 -39
- claude_mpm/services/agent_capabilities_service.py +266 -0
- claude_mpm/services/agents/__init__.py +89 -0
- claude_mpm/services/agents/agent_builder.py +514 -0
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/__init__.py +21 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +1377 -0
- claude_mpm/services/agents/deployment/agent_validator.py +376 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
- claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
- claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
- claude_mpm/services/agents/git_source_manager.py +682 -0
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
- claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
- claude_mpm/services/agents/local_template_manager.py +784 -0
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
- claude_mpm/services/agents/memory/__init__.py +22 -0
- claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
- claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
- claude_mpm/services/agents/memory/content_manager.py +470 -0
- claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
- claude_mpm/services/agents/memory/memory_file_service.py +129 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
- claude_mpm/services/agents/memory/template_generator.py +83 -0
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +617 -0
- claude_mpm/services/agents/registry/__init__.py +30 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1205 -0
- claude_mpm/services/agents/startup_sync.py +262 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/async_session_logger.py +665 -0
- claude_mpm/services/claude_session_logger.py +321 -0
- claude_mpm/services/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +408 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +590 -0
- claude_mpm/services/cli/memory_crud_service.py +622 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +604 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +362 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +446 -0
- claude_mpm/services/command_handler_service.py +221 -0
- claude_mpm/services/communication/__init__.py +22 -0
- claude_mpm/services/core/__init__.py +108 -0
- claude_mpm/services/core/base.py +269 -0
- claude_mpm/services/core/cache_manager.py +309 -0
- claude_mpm/services/core/interfaces/__init__.py +273 -0
- claude_mpm/services/core/interfaces/agent.py +514 -0
- claude_mpm/services/core/interfaces/communication.py +316 -0
- claude_mpm/services/core/interfaces/health.py +169 -0
- claude_mpm/services/core/interfaces/infrastructure.py +357 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/service.py +405 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +81 -0
- claude_mpm/services/core/memory_manager.py +682 -0
- claude_mpm/services/core/models/__init__.py +70 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +517 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +38 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/base_check.py +60 -0
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
- claude_mpm/services/diagnostics/models.py +138 -0
- claude_mpm/services/event_aggregator.py +582 -0
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +186 -0
- claude_mpm/services/event_bus/direct_relay.py +312 -0
- claude_mpm/services/event_bus/event_bus.py +396 -0
- claude_mpm/services/event_bus/relay.py +326 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +306 -0
- claude_mpm/services/events/consumers/logging.py +184 -0
- claude_mpm/services/events/consumers/metrics.py +241 -0
- claude_mpm/services/events/consumers/socketio.py +377 -0
- claude_mpm/services/events/core.py +480 -0
- claude_mpm/services/events/interfaces.py +214 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +329 -0
- claude_mpm/services/exceptions.py +433 -353
- claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
- claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +159 -111
- claude_mpm/services/infrastructure/__init__.py +52 -0
- claude_mpm/services/infrastructure/context_preservation.py +569 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +209 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
- claude_mpm/services/infrastructure/monitoring/base.py +122 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +219 -0
- claude_mpm/services/infrastructure/monitoring/process.py +343 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
- claude_mpm/services/infrastructure/monitoring/service.py +368 -0
- claude_mpm/services/infrastructure/monitoring.py +71 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +155 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +427 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1542 -0
- claude_mpm/services/mcp_service_verifier.py +732 -0
- claude_mpm/services/memory/__init__.py +19 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
- claude_mpm/services/memory/cache/simple_cache.py +331 -0
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
- claude_mpm/services/memory/router.py +951 -0
- claude_mpm/services/memory_hook_service.py +470 -0
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +452 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +698 -0
- claude_mpm/services/monitor/daemon_manager.py +1076 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +730 -0
- claude_mpm/services/monitor/server.py +1493 -0
- claude_mpm/services/monitor_build_service.py +349 -0
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/port_manager.py +597 -0
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/__init__.py +44 -0
- claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +554 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +407 -0
- claude_mpm/services/project/project_organizer.py +1009 -0
- claude_mpm/services/project/registry.py +636 -0
- claude_mpm/services/project/toolchain_analyzer.py +583 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/recovery_manager.py +293 -240
- claude_mpm/services/response_tracker.py +267 -0
- claude_mpm/services/runner_configuration_service.py +605 -0
- claude_mpm/services/self_upgrade_service.py +608 -0
- claude_mpm/services/session_management_service.py +314 -0
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +21 -0
- claude_mpm/services/shared/async_service_base.py +216 -0
- claude_mpm/services/shared/config_service_base.py +301 -0
- claude_mpm/services/shared/lifecycle_service_base.py +308 -0
- claude_mpm/services/shared/manager_base.py +315 -0
- claude_mpm/services/shared/service_factory.py +309 -0
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1340 -0
- claude_mpm/services/skills/selective_skill_deployer.py +743 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1168 -0
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/client_proxy.py +229 -0
- claude_mpm/services/socketio/dashboard_server.py +362 -0
- claude_mpm/services/socketio/event_normalizer.py +798 -0
- claude_mpm/services/socketio/handlers/__init__.py +30 -0
- claude_mpm/services/socketio/handlers/base.py +136 -0
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +643 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
- claude_mpm/services/socketio/handlers/file.py +263 -0
- claude_mpm/services/socketio/handlers/git.py +962 -0
- claude_mpm/services/socketio/handlers/hook.py +211 -0
- claude_mpm/services/socketio/handlers/memory.py +26 -0
- claude_mpm/services/socketio/handlers/project.py +24 -0
- claude_mpm/services/socketio/handlers/registry.py +214 -0
- claude_mpm/services/socketio/migration_utils.py +343 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +569 -0
- claude_mpm/services/socketio/server/connection_manager.py +579 -0
- claude_mpm/services/socketio/server/core.py +1079 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
- claude_mpm/services/socketio/server/main.py +501 -0
- claude_mpm/services/socketio_client_manager.py +173 -143
- claude_mpm/services/socketio_server.py +38 -1657
- claude_mpm/services/subprocess_launcher_service.py +322 -0
- claude_mpm/services/system_instructions_service.py +270 -0
- claude_mpm/services/ticket_manager.py +25 -209
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +466 -0
- claude_mpm/services/utility_service.py +280 -0
- claude_mpm/services/version_control/__init__.py +34 -37
- claude_mpm/services/version_control/branch_strategy.py +26 -17
- claude_mpm/services/version_control/conflict_resolution.py +52 -36
- claude_mpm/services/version_control/git_operations.py +183 -49
- claude_mpm/services/version_control/semantic_versioning.py +172 -61
- claude_mpm/services/version_control/version_parser.py +546 -0
- claude_mpm/services/version_service.py +379 -0
- claude_mpm/services/visualization/__init__.py +15 -0
- claude_mpm/services/visualization/mermaid_generator.py +937 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +405 -0
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +546 -0
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/__init__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +1189 -0
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +168 -126
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +373 -0
- claude_mpm/utils/dependency_manager.py +60 -59
- claude_mpm/utils/dependency_strategies.py +381 -0
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +313 -0
- claude_mpm/utils/error_handler.py +78 -66
- claude_mpm/utils/file_utils.py +305 -0
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/path_operations.py +110 -104
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +844 -0
- claude_mpm/utils/session_logging.py +121 -0
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm/utils/subprocess_utils.py +343 -0
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +214 -108
- claude_mpm/validation/frontmatter_validator.py +252 -0
- claude_mpm-5.4.85.dist-info/METADATA +1023 -0
- claude_mpm-5.4.85.dist-info/RECORD +980 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.85.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
- claude_mpm/agents/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/base_agent_loader.py +0 -529
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/data_engineer.json +0 -110
- claude_mpm/agents/templates/documentation.json +0 -109
- claude_mpm/agents/templates/engineer.json +0 -113
- claude_mpm/agents/templates/ops.json +0 -109
- claude_mpm/agents/templates/pm.json +0 -25
- claude_mpm/agents/templates/qa.json +0 -111
- claude_mpm/agents/templates/research.json +0 -65
- claude_mpm/agents/templates/security.json +0 -113
- claude_mpm/agents/templates/test_integration.json +0 -112
- claude_mpm/agents/templates/version_control.json +0 -107
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/dashboard/open_dashboard.py +0 -34
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/agent_deployment.py +0 -1534
- claude_mpm/services/agent_lifecycle_manager.py +0 -1169
- claude_mpm/services/agent_memory_manager.py +0 -1415
- claude_mpm/services/agent_registry.py +0 -676
- claude_mpm/services/deployed_agent_discovery.py +0 -226
- claude_mpm/services/framework_agent_loader.py +0 -337
- claude_mpm/services/framework_claude_md_generator.py +0 -621
- claude_mpm/services/health_monitor.py +0 -892
- claude_mpm/services/memory_router.py +0 -538
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -508
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- claude_mpm/utils/paths.py +0 -289
- claude_mpm-3.4.10.dist-info/METADATA +0 -183
- claude_mpm-3.4.10.dist-info/RECORD +0 -201
- claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
- {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
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
37
|
+
from enum import Enum
|
|
63
38
|
from pathlib import Path
|
|
64
|
-
from typing import
|
|
65
|
-
|
|
66
|
-
from
|
|
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
|
-
|
|
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
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
127
|
+
Path: Absolute path to the system agents directory
|
|
102
128
|
"""
|
|
103
129
|
return Path(__file__).parent / "templates"
|
|
104
130
|
|
|
105
131
|
|
|
106
|
-
# Agent
|
|
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",
|
|
129
|
-
ModelType.SONNET: "claude-sonnet-4-20250514",
|
|
130
|
-
ModelType.OPUS: "claude-opus-4-20250514"
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
This class
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
-
|
|
147
|
-
-
|
|
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
|
|
167
|
-
|
|
172
|
+
Initialize the agent loader with the registry.
|
|
173
|
+
|
|
168
174
|
The initialization process:
|
|
169
|
-
1. Creates
|
|
170
|
-
2.
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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:
|
|
268
|
-
|
|
196
|
+
agent_id: Agent identifier
|
|
197
|
+
|
|
269
198
|
Returns:
|
|
270
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
|
307
|
-
|
|
216
|
+
Retrieve agent instructions/prompt by ID.
|
|
217
|
+
|
|
308
218
|
Args:
|
|
309
|
-
agent_id:
|
|
310
|
-
force_reload:
|
|
311
|
-
|
|
219
|
+
agent_id: Agent identifier
|
|
220
|
+
force_reload: Ignored (kept for API compatibility)
|
|
221
|
+
|
|
312
222
|
Returns:
|
|
313
|
-
|
|
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
|
-
|
|
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
|
|
228
|
+
|
|
229
|
+
# Extract instructions
|
|
359
230
|
instructions = agent_data.get("instructions", "")
|
|
360
231
|
if not instructions:
|
|
361
|
-
logger.warning(f"
|
|
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:
|
|
437
|
-
|
|
242
|
+
agent_id: Agent identifier
|
|
243
|
+
|
|
438
244
|
Returns:
|
|
439
|
-
|
|
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
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
#
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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,
|
|
607
|
-
|
|
608
|
-
if agent_override ==
|
|
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 ==
|
|
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(
|
|
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(
|
|
620
|
-
if hasattr(loader,
|
|
621
|
-
loader._metrics[
|
|
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[
|
|
624
|
-
loader._metrics[
|
|
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(
|
|
630
|
-
|
|
631
|
-
|
|
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":
|
|
639
|
-
|
|
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,
|
|
645
|
-
loader._metrics[
|
|
646
|
-
loader._metrics[
|
|
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(
|
|
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
|
|
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.
|
|
680
|
-
2.
|
|
681
|
-
3.
|
|
682
|
-
4.
|
|
683
|
-
5.
|
|
684
|
-
6.
|
|
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(
|
|
694
|
-
|
|
740
|
+
prompt = load_agent_prompt_from_md(actual_agent_id, force_reload)
|
|
741
|
+
|
|
695
742
|
if prompt is None:
|
|
696
|
-
raise ValueError(
|
|
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(
|
|
701
|
-
enable_analysis = kwargs.get(
|
|
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 = {
|
|
706
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
841
|
-
|
|
842
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
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
|