claude-mpm 4.13.2__py3-none-any.whl → 4.18.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +48 -17
- claude_mpm/agents/OUTPUT_STYLE.md +329 -11
- claude_mpm/agents/PM_INSTRUCTIONS.md +227 -8
- claude_mpm/agents/agent_loader.py +17 -5
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/agents/templates/agentic-coder-optimizer.json +9 -2
- claude_mpm/agents/templates/api_qa.json +7 -1
- claude_mpm/agents/templates/clerk-ops.json +8 -1
- claude_mpm/agents/templates/code_analyzer.json +4 -1
- claude_mpm/agents/templates/dart_engineer.json +11 -1
- claude_mpm/agents/templates/data_engineer.json +11 -1
- claude_mpm/agents/templates/documentation.json +6 -1
- claude_mpm/agents/templates/engineer.json +18 -1
- claude_mpm/agents/templates/gcp_ops_agent.json +8 -1
- claude_mpm/agents/templates/golang_engineer.json +11 -1
- claude_mpm/agents/templates/java_engineer.json +12 -2
- claude_mpm/agents/templates/local_ops_agent.json +1217 -6
- claude_mpm/agents/templates/nextjs_engineer.json +11 -1
- claude_mpm/agents/templates/ops.json +8 -1
- claude_mpm/agents/templates/php-engineer.json +11 -1
- claude_mpm/agents/templates/project_organizer.json +10 -3
- claude_mpm/agents/templates/prompt-engineer.json +5 -1
- claude_mpm/agents/templates/python_engineer.json +11 -1
- claude_mpm/agents/templates/qa.json +7 -1
- claude_mpm/agents/templates/react_engineer.json +11 -1
- claude_mpm/agents/templates/refactoring_engineer.json +8 -1
- claude_mpm/agents/templates/research.json +4 -1
- claude_mpm/agents/templates/ruby-engineer.json +11 -1
- claude_mpm/agents/templates/rust_engineer.json +11 -1
- claude_mpm/agents/templates/security.json +6 -1
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/ticketing.json +6 -1
- claude_mpm/agents/templates/typescript_engineer.json +11 -1
- claude_mpm/agents/templates/vercel_ops_agent.json +8 -1
- claude_mpm/agents/templates/version_control.json +8 -1
- claude_mpm/agents/templates/web_qa.json +7 -1
- claude_mpm/agents/templates/web_ui.json +11 -1
- claude_mpm/cli/__init__.py +34 -706
- claude_mpm/cli/commands/agent_manager.py +25 -12
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +204 -148
- claude_mpm/cli/commands/aggregate.py +7 -3
- claude_mpm/cli/commands/analyze.py +9 -4
- claude_mpm/cli/commands/analyze_code.py +7 -2
- claude_mpm/cli/commands/auto_configure.py +7 -9
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +294 -1788
- claude_mpm/cli/commands/configure_agent_display.py +261 -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 +167 -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/local_deploy.py +537 -0
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init.py +39 -25
- claude_mpm/cli/commands/mpm_init_handler.py +8 -3
- claude_mpm/cli/executor.py +202 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +3 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parsers/__init__.py +7 -1
- claude_mpm/cli/parsers/base_parser.py +98 -3
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +481 -0
- claude_mpm/cli/utils.py +52 -1
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/core/base_service.py +13 -12
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +9 -3
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/types.py +2 -9
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/dashboard/static/js/dashboard.js +0 -14
- claude_mpm/dashboard/templates/index.html +3 -41
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +10 -11
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/agents/registry/modification_tracker.py +5 -2
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/interfaces/__init__.py +74 -2
- claude_mpm/services/core/interfaces/health.py +172 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/models/__init__.py +33 -0
- claude_mpm/services/core/models/agent_config.py +12 -28
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +235 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/path_resolver.py +23 -7
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
- claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
- claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +36 -31
- claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
- claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
- claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
- claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
- claude_mpm/services/diagnostics/models.py +19 -24
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +163 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +28 -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 +430 -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 +9 -4
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +18 -31
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +71 -24
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
- claude_mpm/services/memory_hook_service.py +4 -1
- 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 +453 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/daemon_manager.py +3 -2
- claude_mpm/services/monitor/handlers/dashboard.py +2 -1
- claude_mpm/services/monitor/handlers/hooks.py +2 -1
- claude_mpm/services/monitor/management/lifecycle.py +3 -2
- claude_mpm/services/monitor/server.py +2 -1
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/hook.py +13 -2
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/server/main.py +10 -8
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
- claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
- claude_mpm/services/unified/deployment_strategies/local.py +6 -5
- claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +14 -10
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +9 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +21 -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/database-migration.md +199 -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/json-data-handling.md +223 -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 +567 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -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 +310 -0
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +117 -8
- {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +238 -174
- claude_mpm/dashboard/static/css/code-tree.css +0 -1639
- claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
|
@@ -8,25 +8,12 @@ Part of ISS-0034: Infrastructure Setup - MCP Gateway Project Foundation
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import asyncio
|
|
11
|
-
from enum import Enum
|
|
12
11
|
from typing import Any, Dict, Optional
|
|
13
12
|
|
|
13
|
+
from claude_mpm.core.enums import ServiceState
|
|
14
14
|
from claude_mpm.services.core.base import BaseService
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class MCPServiceState(Enum):
|
|
18
|
-
"""MCP service lifecycle states."""
|
|
19
|
-
|
|
20
|
-
UNINITIALIZED = "uninitialized"
|
|
21
|
-
INITIALIZING = "initializing"
|
|
22
|
-
INITIALIZED = "initialized"
|
|
23
|
-
STARTING = "starting"
|
|
24
|
-
RUNNING = "running"
|
|
25
|
-
STOPPING = "stopping"
|
|
26
|
-
STOPPED = "stopped"
|
|
27
|
-
ERROR = "error"
|
|
28
|
-
|
|
29
|
-
|
|
30
17
|
class BaseMCPService(BaseService):
|
|
31
18
|
"""
|
|
32
19
|
Base class for all MCP Gateway services.
|
|
@@ -53,7 +40,7 @@ class BaseMCPService(BaseService):
|
|
|
53
40
|
config: Service-specific configuration
|
|
54
41
|
"""
|
|
55
42
|
super().__init__(service_name or "MCPService", config)
|
|
56
|
-
self._state =
|
|
43
|
+
self._state = ServiceState.UNINITIALIZED
|
|
57
44
|
self._health_status = {
|
|
58
45
|
"healthy": False,
|
|
59
46
|
"state": self._state.value,
|
|
@@ -76,13 +63,13 @@ class BaseMCPService(BaseService):
|
|
|
76
63
|
"""
|
|
77
64
|
async with self._state_lock:
|
|
78
65
|
if self._state not in [
|
|
79
|
-
|
|
80
|
-
|
|
66
|
+
ServiceState.UNINITIALIZED,
|
|
67
|
+
ServiceState.STOPPED,
|
|
81
68
|
]:
|
|
82
69
|
self.log_warning(f"Cannot initialize from state {self._state.value}")
|
|
83
70
|
return False
|
|
84
71
|
|
|
85
|
-
self._state =
|
|
72
|
+
self._state = ServiceState.INITIALIZING
|
|
86
73
|
self.log_info("Initializing MCP service")
|
|
87
74
|
|
|
88
75
|
try:
|
|
@@ -91,13 +78,13 @@ class BaseMCPService(BaseService):
|
|
|
91
78
|
|
|
92
79
|
async with self._state_lock:
|
|
93
80
|
if success:
|
|
94
|
-
self._state =
|
|
81
|
+
self._state = ServiceState.INITIALIZED
|
|
95
82
|
self._initialized = True
|
|
96
83
|
self._health_status["healthy"] = True
|
|
97
84
|
self._health_status["state"] = self._state.value
|
|
98
85
|
self.log_info("MCP service initialized successfully")
|
|
99
86
|
else:
|
|
100
|
-
self._state =
|
|
87
|
+
self._state = ServiceState.ERROR
|
|
101
88
|
self._health_status["healthy"] = False
|
|
102
89
|
self._health_status["state"] = self._state.value
|
|
103
90
|
self.log_error("MCP service initialization failed")
|
|
@@ -106,7 +93,7 @@ class BaseMCPService(BaseService):
|
|
|
106
93
|
|
|
107
94
|
except Exception as e:
|
|
108
95
|
async with self._state_lock:
|
|
109
|
-
self._state =
|
|
96
|
+
self._state = ServiceState.ERROR
|
|
110
97
|
self._health_status["healthy"] = False
|
|
111
98
|
self._health_status["state"] = self._state.value
|
|
112
99
|
self._health_status["details"]["error"] = str(e)
|
|
@@ -134,11 +121,11 @@ class BaseMCPService(BaseService):
|
|
|
134
121
|
True if startup successful
|
|
135
122
|
"""
|
|
136
123
|
async with self._state_lock:
|
|
137
|
-
if self._state !=
|
|
124
|
+
if self._state != ServiceState.INITIALIZED:
|
|
138
125
|
self.log_warning(f"Cannot start from state {self._state.value}")
|
|
139
126
|
return False
|
|
140
127
|
|
|
141
|
-
self._state =
|
|
128
|
+
self._state = ServiceState.STARTING
|
|
142
129
|
self.log_info("Starting MCP service")
|
|
143
130
|
|
|
144
131
|
try:
|
|
@@ -146,12 +133,12 @@ class BaseMCPService(BaseService):
|
|
|
146
133
|
|
|
147
134
|
async with self._state_lock:
|
|
148
135
|
if success:
|
|
149
|
-
self._state =
|
|
136
|
+
self._state = ServiceState.RUNNING
|
|
150
137
|
self._health_status["healthy"] = True
|
|
151
138
|
self._health_status["state"] = self._state.value
|
|
152
139
|
self.log_info("MCP service started successfully")
|
|
153
140
|
else:
|
|
154
|
-
self._state =
|
|
141
|
+
self._state = ServiceState.ERROR
|
|
155
142
|
self._health_status["healthy"] = False
|
|
156
143
|
self._health_status["state"] = self._state.value
|
|
157
144
|
self.log_error("MCP service startup failed")
|
|
@@ -160,7 +147,7 @@ class BaseMCPService(BaseService):
|
|
|
160
147
|
|
|
161
148
|
except Exception as e:
|
|
162
149
|
async with self._state_lock:
|
|
163
|
-
self._state =
|
|
150
|
+
self._state = ServiceState.ERROR
|
|
164
151
|
self._health_status["healthy"] = False
|
|
165
152
|
self._health_status["state"] = self._state.value
|
|
166
153
|
self._health_status["details"]["error"] = str(e)
|
|
@@ -188,18 +175,18 @@ class BaseMCPService(BaseService):
|
|
|
188
175
|
Subclasses should override _do_shutdown() for custom shutdown logic.
|
|
189
176
|
"""
|
|
190
177
|
async with self._state_lock:
|
|
191
|
-
if self._state in [
|
|
178
|
+
if self._state in [ServiceState.STOPPED, ServiceState.STOPPING]:
|
|
192
179
|
self.log_warning(f"Already in state {self._state.value}")
|
|
193
180
|
return
|
|
194
181
|
|
|
195
|
-
self._state =
|
|
182
|
+
self._state = ServiceState.STOPPING
|
|
196
183
|
self.log_info("Shutting down MCP service")
|
|
197
184
|
|
|
198
185
|
try:
|
|
199
186
|
await self._do_shutdown()
|
|
200
187
|
|
|
201
188
|
async with self._state_lock:
|
|
202
|
-
self._state =
|
|
189
|
+
self._state = ServiceState.STOPPED
|
|
203
190
|
self._shutdown = True
|
|
204
191
|
self._health_status["healthy"] = False
|
|
205
192
|
self._health_status["state"] = self._state.value
|
|
@@ -207,7 +194,7 @@ class BaseMCPService(BaseService):
|
|
|
207
194
|
|
|
208
195
|
except Exception as e:
|
|
209
196
|
async with self._state_lock:
|
|
210
|
-
self._state =
|
|
197
|
+
self._state = ServiceState.ERROR
|
|
211
198
|
self._health_status["healthy"] = False
|
|
212
199
|
self._health_status["state"] = self._state.value
|
|
213
200
|
self._health_status["details"]["error"] = str(e)
|
|
@@ -232,7 +219,7 @@ class BaseMCPService(BaseService):
|
|
|
232
219
|
self.log_info("Restarting MCP service")
|
|
233
220
|
|
|
234
221
|
# Shutdown if running
|
|
235
|
-
if self._state ==
|
|
222
|
+
if self._state == ServiceState.RUNNING:
|
|
236
223
|
await self.shutdown()
|
|
237
224
|
|
|
238
225
|
# Re-initialize
|
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
External MCP Services Integration
|
|
3
3
|
==================================
|
|
4
4
|
|
|
5
|
-
Manages
|
|
5
|
+
Manages detection and setup of external MCP services like mcp-vector-search
|
|
6
6
|
and mcp-browser. These services run as separate MCP servers in Claude Code,
|
|
7
7
|
not as part of the Claude MPM MCP Gateway.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
IMPORTANT: External services are NOT auto-installed. Users must manually install
|
|
10
|
+
them using pipx or pip. This gives users explicit control over which optional
|
|
11
|
+
services they want to enable.
|
|
12
|
+
|
|
13
|
+
Installation:
|
|
14
|
+
pipx install mcp-vector-search
|
|
15
|
+
pipx install mcp-browser
|
|
16
|
+
pipx install kuzu-memory
|
|
17
|
+
pipx install mcp-ticketer
|
|
18
|
+
|
|
19
|
+
Note: External services are registered as separate MCP servers in Claude Code
|
|
20
|
+
configuration, not as tools within the gateway.
|
|
11
21
|
"""
|
|
12
22
|
|
|
13
23
|
import json
|
|
@@ -20,7 +30,12 @@ from claude_mpm.services.mcp_gateway.tools.base_adapter import BaseToolAdapter
|
|
|
20
30
|
|
|
21
31
|
|
|
22
32
|
class ExternalMCPService(BaseToolAdapter):
|
|
23
|
-
"""Base class for external MCP service integration.
|
|
33
|
+
"""Base class for external MCP service integration.
|
|
34
|
+
|
|
35
|
+
External services are detected if already installed but are NOT
|
|
36
|
+
automatically installed. Users must install them manually using
|
|
37
|
+
pipx or pip to enable these optional features.
|
|
38
|
+
"""
|
|
24
39
|
|
|
25
40
|
def __init__(self, service_name: str, package_name: str):
|
|
26
41
|
"""
|
|
@@ -65,27 +80,37 @@ class ExternalMCPService(BaseToolAdapter):
|
|
|
65
80
|
)
|
|
66
81
|
|
|
67
82
|
async def initialize(
|
|
68
|
-
self, auto_install: bool =
|
|
83
|
+
self, auto_install: bool = False, interactive: bool = False
|
|
69
84
|
) -> bool:
|
|
70
85
|
"""Initialize the external service.
|
|
71
86
|
|
|
87
|
+
NOTE: Auto-installation is disabled by default (v4.9.0+). Users must
|
|
88
|
+
manually install external services using pipx or pip.
|
|
89
|
+
|
|
72
90
|
Args:
|
|
73
|
-
auto_install: Whether to automatically install if not found
|
|
74
|
-
|
|
91
|
+
auto_install: Whether to automatically install if not found (default: False)
|
|
92
|
+
Deprecated - will be removed in future versions
|
|
93
|
+
interactive: Whether to prompt user for installation preferences (default: False)
|
|
94
|
+
Only used if auto_install=True
|
|
75
95
|
"""
|
|
76
96
|
try:
|
|
77
97
|
# Check if package is installed
|
|
78
98
|
self._is_installed = await self._check_installation()
|
|
79
99
|
|
|
80
100
|
if not self._is_installed and auto_install:
|
|
81
|
-
|
|
82
|
-
|
|
101
|
+
# This path is deprecated but kept for backward compatibility
|
|
102
|
+
self.logger.warning(
|
|
103
|
+
f"Auto-installation is deprecated. Please install {self.package_name} manually: "
|
|
104
|
+
f"pipx install {self.package_name}"
|
|
83
105
|
)
|
|
84
106
|
await self._install_package(interactive=interactive)
|
|
85
107
|
self._is_installed = await self._check_installation()
|
|
86
108
|
|
|
87
109
|
if not self._is_installed:
|
|
88
|
-
self.logger.
|
|
110
|
+
self.logger.debug(
|
|
111
|
+
f"{self.package_name} is not available. "
|
|
112
|
+
f"Install manually with: pipx install {self.package_name}"
|
|
113
|
+
)
|
|
89
114
|
return False
|
|
90
115
|
|
|
91
116
|
self.logger.info(f"{self.package_name} is available")
|
|
@@ -522,13 +547,20 @@ class MCPBrowserService(ExternalMCPService):
|
|
|
522
547
|
class ExternalMCPServiceManager:
|
|
523
548
|
"""Manager for external MCP services.
|
|
524
549
|
|
|
525
|
-
This manager is responsible for
|
|
526
|
-
for external MCP services. The actual registration of these services
|
|
527
|
-
|
|
550
|
+
This manager is responsible for detecting (but NOT installing) Python packages
|
|
551
|
+
for external MCP services. The actual registration of these services happens
|
|
552
|
+
in Claude Code configuration as separate MCP servers.
|
|
553
|
+
|
|
554
|
+
IMPORTANT: As of v4.9.0, this manager NO LONGER auto-installs missing services.
|
|
555
|
+
Users must manually install external services using pipx or pip:
|
|
556
|
+
- pipx install mcp-vector-search
|
|
557
|
+
- pipx install mcp-browser
|
|
558
|
+
- pipx install kuzu-memory
|
|
559
|
+
- pipx install mcp-ticketer
|
|
528
560
|
|
|
529
|
-
Note: This class is maintained for backward compatibility and
|
|
530
|
-
|
|
531
|
-
|
|
561
|
+
Note: This class is maintained for backward compatibility and service detection.
|
|
562
|
+
The actual tool registration is handled by separate MCP server instances in
|
|
563
|
+
Claude Code.
|
|
532
564
|
"""
|
|
533
565
|
|
|
534
566
|
def __init__(self):
|
|
@@ -539,20 +571,34 @@ class ExternalMCPServiceManager:
|
|
|
539
571
|
async def initialize_services(self) -> List[ExternalMCPService]:
|
|
540
572
|
"""Initialize all external MCP services.
|
|
541
573
|
|
|
542
|
-
This method checks if external service packages are installed
|
|
543
|
-
and
|
|
544
|
-
|
|
574
|
+
This method checks if external service packages are already installed
|
|
575
|
+
and registers them if available. It does NOT auto-install missing services.
|
|
576
|
+
|
|
577
|
+
External MCP services (mcp-vector-search, mcp-browser, kuzu-memory, mcp-ticketer)
|
|
578
|
+
must be manually installed by users. This gives users explicit control over
|
|
579
|
+
which services they want to use.
|
|
580
|
+
|
|
581
|
+
Installation instructions:
|
|
582
|
+
- mcp-vector-search: pipx install mcp-vector-search
|
|
583
|
+
- mcp-browser: pipx install mcp-browser
|
|
584
|
+
- kuzu-memory: pipx install kuzu-memory
|
|
585
|
+
- mcp-ticketer: pipx install mcp-ticketer
|
|
586
|
+
|
|
587
|
+
Services run as separate MCP servers in Claude Code, not as tools within
|
|
588
|
+
the gateway.
|
|
545
589
|
"""
|
|
546
590
|
# Create service instances
|
|
547
|
-
# Note: kuzu-memory
|
|
548
|
-
#
|
|
591
|
+
# Note: kuzu-memory and mcp-ticketer are configured via MCPConfigManager
|
|
592
|
+
# and run as separate MCP servers. They don't need to be included here
|
|
593
|
+
# since they're already set up through the MCP config.
|
|
549
594
|
services = [MCPVectorSearchService(), MCPBrowserService()]
|
|
550
595
|
|
|
551
|
-
# Initialize each service
|
|
596
|
+
# Initialize each service (check if installed, but DO NOT auto-install)
|
|
552
597
|
initialized_services = []
|
|
553
598
|
for service in services:
|
|
554
599
|
try:
|
|
555
|
-
|
|
600
|
+
# Pass auto_install=False to prevent automatic installation
|
|
601
|
+
if await service.initialize(auto_install=False, interactive=False):
|
|
556
602
|
initialized_services.append(service)
|
|
557
603
|
if self.logger:
|
|
558
604
|
self.logger.info(
|
|
@@ -560,7 +606,8 @@ class ExternalMCPServiceManager:
|
|
|
560
606
|
)
|
|
561
607
|
elif self.logger:
|
|
562
608
|
self.logger.debug(
|
|
563
|
-
f"Service not available (optional): {service.service_name}"
|
|
609
|
+
f"Service not available (optional): {service.service_name}. "
|
|
610
|
+
f"Install manually with: pipx install {service.package_name}"
|
|
564
611
|
)
|
|
565
612
|
except Exception as e:
|
|
566
613
|
if self.logger:
|
|
@@ -26,6 +26,7 @@ from typing import Any, Dict
|
|
|
26
26
|
import psutil
|
|
27
27
|
|
|
28
28
|
from claude_mpm.config.paths import paths
|
|
29
|
+
from claude_mpm.core.enums import HealthStatus, OperationResult, ServiceState
|
|
29
30
|
from claude_mpm.core.logger import get_logger
|
|
30
31
|
from claude_mpm.services.mcp_gateway.core.interfaces import (
|
|
31
32
|
MCPToolDefinition,
|
|
@@ -168,20 +169,20 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
168
169
|
if i < len(check_results):
|
|
169
170
|
if isinstance(check_results[i], Exception):
|
|
170
171
|
results["checks"][check_name] = {
|
|
171
|
-
"status":
|
|
172
|
+
"status": OperationResult.ERROR,
|
|
172
173
|
"error": str(check_results[i]),
|
|
173
174
|
}
|
|
174
175
|
else:
|
|
175
176
|
results["checks"][check_name] = check_results[i]
|
|
176
177
|
else:
|
|
177
178
|
results["checks"][check_name] = {
|
|
178
|
-
"status":
|
|
179
|
+
"status": OperationResult.TIMEOUT,
|
|
179
180
|
"error": "Check timed out",
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
except asyncio.TimeoutError:
|
|
183
184
|
results["checks"]["timeout"] = {
|
|
184
|
-
"status":
|
|
185
|
+
"status": OperationResult.ERROR,
|
|
185
186
|
"error": f"Health checks timed out after {timeout} seconds",
|
|
186
187
|
}
|
|
187
188
|
|
|
@@ -194,7 +195,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
194
195
|
async def _check_system_health(self, detailed: bool) -> Dict[str, Any]:
|
|
195
196
|
"""Check system health (CPU, memory, disk, etc.)."""
|
|
196
197
|
check_result = {
|
|
197
|
-
"status":
|
|
198
|
+
"status": ServiceState.RUNNING,
|
|
198
199
|
"checks": {},
|
|
199
200
|
"warnings": [],
|
|
200
201
|
"errors": [],
|
|
@@ -219,7 +220,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
219
220
|
|
|
220
221
|
if memory_usage > 90:
|
|
221
222
|
check_result["errors"].append("High memory usage detected")
|
|
222
|
-
check_result["status"] =
|
|
223
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
223
224
|
elif memory_usage > 80:
|
|
224
225
|
check_result["warnings"].append("Elevated memory usage")
|
|
225
226
|
|
|
@@ -232,7 +233,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
232
233
|
|
|
233
234
|
if cpu_usage > 95:
|
|
234
235
|
check_result["errors"].append("High CPU usage detected")
|
|
235
|
-
check_result["status"] =
|
|
236
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
236
237
|
elif cpu_usage > 80:
|
|
237
238
|
check_result["warnings"].append("Elevated CPU usage")
|
|
238
239
|
|
|
@@ -248,7 +249,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
248
249
|
|
|
249
250
|
if disk_usage_percent > 95:
|
|
250
251
|
check_result["errors"].append("Disk space critically low")
|
|
251
|
-
check_result["status"] =
|
|
252
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
252
253
|
elif disk_usage_percent > 85:
|
|
253
254
|
check_result["warnings"].append("Disk space running low")
|
|
254
255
|
|
|
@@ -262,7 +263,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
except Exception as e:
|
|
265
|
-
check_result["status"] =
|
|
266
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
266
267
|
check_result["errors"].append(f"System health check failed: {e}")
|
|
267
268
|
|
|
268
269
|
return check_result
|
|
@@ -270,7 +271,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
270
271
|
async def _check_gateway_health(self, detailed: bool) -> Dict[str, Any]:
|
|
271
272
|
"""Check MCP Gateway health."""
|
|
272
273
|
check_result = {
|
|
273
|
-
"status":
|
|
274
|
+
"status": ServiceState.RUNNING,
|
|
274
275
|
"checks": {},
|
|
275
276
|
"warnings": [],
|
|
276
277
|
"errors": [],
|
|
@@ -302,10 +303,10 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
302
303
|
|
|
303
304
|
if not mcp_dir.exists():
|
|
304
305
|
check_result["errors"].append("MCP directory does not exist")
|
|
305
|
-
check_result["status"] =
|
|
306
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
306
307
|
|
|
307
308
|
except Exception as e:
|
|
308
|
-
check_result["status"] =
|
|
309
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
309
310
|
check_result["errors"].append(f"Gateway health check failed: {e}")
|
|
310
311
|
|
|
311
312
|
return check_result
|
|
@@ -313,7 +314,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
313
314
|
async def _check_tools_health(self, detailed: bool) -> Dict[str, Any]:
|
|
314
315
|
"""Check MCP tools health."""
|
|
315
316
|
check_result = {
|
|
316
|
-
"status":
|
|
317
|
+
"status": ServiceState.RUNNING,
|
|
317
318
|
"checks": {},
|
|
318
319
|
"warnings": [],
|
|
319
320
|
"errors": [],
|
|
@@ -353,11 +354,11 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
353
354
|
)
|
|
354
355
|
|
|
355
356
|
if len(available_essential) == 0:
|
|
356
|
-
check_result["status"] =
|
|
357
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
357
358
|
check_result["errors"].append("No essential tools available")
|
|
358
359
|
|
|
359
360
|
except Exception as e:
|
|
360
|
-
check_result["status"] =
|
|
361
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
361
362
|
check_result["errors"].append(f"Tools health check failed: {e}")
|
|
362
363
|
|
|
363
364
|
return check_result
|
|
@@ -365,7 +366,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
365
366
|
async def _check_config_health(self, detailed: bool) -> Dict[str, Any]:
|
|
366
367
|
"""Check configuration health."""
|
|
367
368
|
check_result = {
|
|
368
|
-
"status":
|
|
369
|
+
"status": ServiceState.RUNNING,
|
|
369
370
|
"checks": {},
|
|
370
371
|
"warnings": [],
|
|
371
372
|
"errors": [],
|
|
@@ -401,7 +402,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
401
402
|
}
|
|
402
403
|
|
|
403
404
|
except Exception as e:
|
|
404
|
-
check_result["status"] =
|
|
405
|
+
check_result["status"] = HealthStatus.UNHEALTHY
|
|
405
406
|
check_result["errors"].append(f"Config health check failed: {e}")
|
|
406
407
|
|
|
407
408
|
return check_result
|
|
@@ -413,13 +414,13 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
413
414
|
|
|
414
415
|
statuses = [check.get("status", "unknown") for check in checks.values()]
|
|
415
416
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if "unhealthy" in statuses:
|
|
417
|
+
# Check for unhealthy (handle both string and enum)
|
|
418
|
+
if HealthStatus.UNHEALTHY in statuses or "unhealthy" in statuses:
|
|
419
419
|
return "unhealthy"
|
|
420
420
|
if "warning" in statuses:
|
|
421
421
|
return "warning"
|
|
422
|
-
|
|
422
|
+
# Check for healthy (handle both string and enum)
|
|
423
|
+
if all(status in (HealthStatus.HEALTHY, "healthy") for status in statuses):
|
|
423
424
|
return "healthy"
|
|
424
425
|
return "unknown"
|
|
425
426
|
|
|
@@ -436,19 +437,20 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
436
437
|
for check_name, check_result in checks.items():
|
|
437
438
|
status = check_result.get("status", "unknown")
|
|
438
439
|
|
|
439
|
-
|
|
440
|
+
# Check for healthy (handle both string and enum)
|
|
441
|
+
if status in (HealthStatus.HEALTHY, "healthy"):
|
|
440
442
|
summary["healthy"] += 1
|
|
441
|
-
elif status in ["warning", "unhealthy"]:
|
|
443
|
+
elif status in ["warning", HealthStatus.UNHEALTHY, "unhealthy"]:
|
|
442
444
|
summary["warnings"] += 1
|
|
443
445
|
# Collect warning messages
|
|
444
446
|
warnings = check_result.get("warnings", [])
|
|
445
447
|
for warning in warnings:
|
|
446
448
|
summary["issues"].append(f"{check_name}: {warning}")
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
449
|
+
# Collect error messages if status is unhealthy
|
|
450
|
+
if status in (HealthStatus.UNHEALTHY, "unhealthy"):
|
|
451
|
+
summary["errors"] += 1
|
|
452
|
+
errors = check_result.get("errors", [])
|
|
453
|
+
for error in errors:
|
|
454
|
+
summary["issues"].append(f"{check_name}: {error}")
|
|
453
455
|
|
|
454
456
|
return summary
|
|
@@ -11,6 +11,7 @@ Extracted from ClaudeRunner to follow Single Responsibility Principle.
|
|
|
11
11
|
from typing import Any, Dict
|
|
12
12
|
|
|
13
13
|
from claude_mpm.core.base_service import BaseService
|
|
14
|
+
from claude_mpm.core.enums import ServiceState
|
|
14
15
|
from claude_mpm.services.core.interfaces import MemoryHookInterface
|
|
15
16
|
|
|
16
17
|
|
|
@@ -463,5 +464,7 @@ class MemoryHookService(BaseService, MemoryHookInterface):
|
|
|
463
464
|
"hook_service_available": self.hook_service is not None,
|
|
464
465
|
"memory_enabled": self.is_memory_enabled(),
|
|
465
466
|
"total_hooks": len(self.registered_hooks),
|
|
466
|
-
"status":
|
|
467
|
+
"status": (
|
|
468
|
+
ServiceState.RUNNING if self.registered_hooks else ServiceState.IDLE
|
|
469
|
+
),
|
|
467
470
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Model Services Package for Claude MPM Framework
|
|
3
|
+
================================================
|
|
4
|
+
|
|
5
|
+
WHY: Provides hybrid local/cloud content processing with intelligent routing
|
|
6
|
+
and automatic fallback. Enables privacy-preserving local model execution via
|
|
7
|
+
Ollama with cloud fallback to Claude for reliability.
|
|
8
|
+
|
|
9
|
+
ARCHITECTURE:
|
|
10
|
+
- Interfaces: Core contracts for model providers and routing (IModelProvider, IModelRouter)
|
|
11
|
+
- Base Provider: Common functionality for all providers (BaseModelProvider)
|
|
12
|
+
- Providers: Ollama (local) and Claude (cloud) implementations
|
|
13
|
+
- Router: Intelligent routing with fallback logic (ModelRouter)
|
|
14
|
+
- Configuration: Centralized config management (model_config.py)
|
|
15
|
+
|
|
16
|
+
USAGE:
|
|
17
|
+
|
|
18
|
+
Basic Usage with Auto-Routing:
|
|
19
|
+
```python
|
|
20
|
+
from claude_mpm.services.model import ModelRouter
|
|
21
|
+
from claude_mpm.services.core.interfaces.model import ModelCapability
|
|
22
|
+
|
|
23
|
+
# Create router with default config (auto mode)
|
|
24
|
+
router = ModelRouter()
|
|
25
|
+
await router.initialize()
|
|
26
|
+
|
|
27
|
+
# Analyze content (tries Ollama first, falls back to Claude)
|
|
28
|
+
response = await router.analyze_content(
|
|
29
|
+
content="Your article text here...",
|
|
30
|
+
task=ModelCapability.SEO_ANALYSIS
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if response.success:
|
|
34
|
+
print(f"Analysis by {response.provider}:")
|
|
35
|
+
print(response.result)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Direct Provider Usage:
|
|
39
|
+
```python
|
|
40
|
+
from claude_mpm.services.model import OllamaProvider
|
|
41
|
+
|
|
42
|
+
# Use Ollama directly
|
|
43
|
+
provider = OllamaProvider(config={
|
|
44
|
+
"host": "http://localhost:11434"
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
if await provider.is_available():
|
|
48
|
+
response = await provider.analyze_content(
|
|
49
|
+
content="Text to analyze",
|
|
50
|
+
task=ModelCapability.READABILITY
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Configuration-Based Setup:
|
|
55
|
+
```python
|
|
56
|
+
from claude_mpm.config.model_config import ModelConfigManager
|
|
57
|
+
from claude_mpm.services.model import ModelRouter
|
|
58
|
+
|
|
59
|
+
# Load config from file
|
|
60
|
+
config = ModelConfigManager.load_config(".claude/configuration.yaml")
|
|
61
|
+
router_config = ModelConfigManager.get_router_config(config)
|
|
62
|
+
|
|
63
|
+
# Create router with loaded config
|
|
64
|
+
router = ModelRouter(config=router_config)
|
|
65
|
+
await router.initialize()
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
PROVIDER STRATEGIES:
|
|
69
|
+
- AUTO: Try Ollama first, fallback to Claude (default)
|
|
70
|
+
- OLLAMA: Local-only, fail if unavailable (privacy mode)
|
|
71
|
+
- CLAUDE: Cloud-only, always use Claude
|
|
72
|
+
- PRIVACY: Like OLLAMA with privacy-focused messages
|
|
73
|
+
|
|
74
|
+
RECOMMENDED MODELS (Ollama):
|
|
75
|
+
- SEO Analysis: llama3.3:70b - Comprehensive SEO insights
|
|
76
|
+
- Readability: gemma2:9b - Fast, accurate readability scoring
|
|
77
|
+
- Grammar: qwen3:14b - Specialized grammar checking
|
|
78
|
+
- Summarization: mistral:7b - Concise, effective summaries
|
|
79
|
+
- Keyword Extraction: seoassistant - SEO-specialized model
|
|
80
|
+
|
|
81
|
+
CONFIGURATION:
|
|
82
|
+
See claude_mpm.config.model_config for detailed configuration options.
|
|
83
|
+
|
|
84
|
+
Example configuration.yaml:
|
|
85
|
+
```yaml
|
|
86
|
+
content_agent:
|
|
87
|
+
model_provider: auto
|
|
88
|
+
|
|
89
|
+
ollama:
|
|
90
|
+
enabled: true
|
|
91
|
+
host: http://localhost:11434
|
|
92
|
+
fallback_to_cloud: true
|
|
93
|
+
models:
|
|
94
|
+
seo_analysis: llama3.3:70b
|
|
95
|
+
readability: gemma2:9b
|
|
96
|
+
|
|
97
|
+
claude:
|
|
98
|
+
enabled: true
|
|
99
|
+
model: claude-3-5-sonnet-20241022
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
PHASE 1 STATUS (Current):
|
|
103
|
+
✅ Core interfaces and contracts defined
|
|
104
|
+
✅ Base provider with common functionality
|
|
105
|
+
✅ Ollama provider with direct API integration
|
|
106
|
+
✅ Claude provider (Phase 1: mock responses)
|
|
107
|
+
✅ Router with intelligent fallback logic
|
|
108
|
+
✅ Configuration management with validation
|
|
109
|
+
⏳ Claude API integration (Phase 2)
|
|
110
|
+
⏳ Content agent integration (Phase 2)
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
# Re-export interfaces for convenience
|
|
114
|
+
from claude_mpm.services.core.interfaces.model import (
|
|
115
|
+
IModelProvider,
|
|
116
|
+
IModelRouter,
|
|
117
|
+
ModelCapability,
|
|
118
|
+
ModelProvider,
|
|
119
|
+
ModelResponse,
|
|
120
|
+
)
|
|
121
|
+
from claude_mpm.services.model.base_provider import BaseModelProvider
|
|
122
|
+
from claude_mpm.services.model.claude_provider import ClaudeProvider
|
|
123
|
+
from claude_mpm.services.model.model_router import ModelRouter, RoutingStrategy
|
|
124
|
+
from claude_mpm.services.model.ollama_provider import OllamaProvider
|
|
125
|
+
|
|
126
|
+
__all__ = [ # noqa: RUF022 - Semantic grouping preferred over alphabetical
|
|
127
|
+
# Base classes
|
|
128
|
+
"BaseModelProvider",
|
|
129
|
+
# Providers
|
|
130
|
+
"ClaudeProvider",
|
|
131
|
+
"OllamaProvider",
|
|
132
|
+
# Router
|
|
133
|
+
"ModelRouter",
|
|
134
|
+
"RoutingStrategy",
|
|
135
|
+
# Interfaces
|
|
136
|
+
"IModelProvider",
|
|
137
|
+
"IModelRouter",
|
|
138
|
+
# Data types
|
|
139
|
+
"ModelCapability",
|
|
140
|
+
"ModelProvider",
|
|
141
|
+
"ModelResponse",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
# Version and metadata
|
|
145
|
+
__version__ = "1.0.0"
|
|
146
|
+
__phase__ = "1"
|
|
147
|
+
__status__ = "Core Infrastructure Complete"
|