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
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base Model Provider Implementation for Claude MPM Framework
|
|
3
|
+
===========================================================
|
|
4
|
+
|
|
5
|
+
WHY: Provides common functionality for all model providers, reducing
|
|
6
|
+
duplication and ensuring consistent behavior across implementations.
|
|
7
|
+
|
|
8
|
+
DESIGN DECISION: Abstract base class extends both BaseService and IModelProvider,
|
|
9
|
+
providing service lifecycle management plus model-specific utilities.
|
|
10
|
+
|
|
11
|
+
RESPONSIBILITIES:
|
|
12
|
+
- Common error handling and logging
|
|
13
|
+
- Task-specific prompt generation
|
|
14
|
+
- Response formatting and validation
|
|
15
|
+
- Performance metrics tracking
|
|
16
|
+
- Retry logic for transient failures
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import asyncio
|
|
20
|
+
import time
|
|
21
|
+
from abc import abstractmethod
|
|
22
|
+
from typing import Any, Dict, Optional
|
|
23
|
+
|
|
24
|
+
from claude_mpm.core.logger import get_logger
|
|
25
|
+
from claude_mpm.services.core.base import BaseService
|
|
26
|
+
from claude_mpm.services.core.interfaces.model import (
|
|
27
|
+
IModelProvider,
|
|
28
|
+
ModelCapability,
|
|
29
|
+
ModelResponse,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BaseModelProvider(BaseService, IModelProvider):
|
|
34
|
+
"""
|
|
35
|
+
Abstract base class for model providers.
|
|
36
|
+
|
|
37
|
+
WHY: Centralizes common provider functionality like prompt generation,
|
|
38
|
+
error handling, and response formatting.
|
|
39
|
+
|
|
40
|
+
Usage:
|
|
41
|
+
class MyProvider(BaseModelProvider):
|
|
42
|
+
async def analyze_content(self, content, task, model=None, **kwargs):
|
|
43
|
+
prompt = self.get_task_prompt(task, content)
|
|
44
|
+
# Call provider API
|
|
45
|
+
return self.create_response(...)
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
# Task-specific prompt templates
|
|
49
|
+
TASK_PROMPTS: Dict[ModelCapability, str] = {
|
|
50
|
+
ModelCapability.SEO_ANALYSIS: """Analyze the following content for SEO effectiveness. Provide:
|
|
51
|
+
1. Primary and secondary keywords identified
|
|
52
|
+
2. Keyword density analysis
|
|
53
|
+
3. Meta description recommendation
|
|
54
|
+
4. Title tag optimization suggestions
|
|
55
|
+
5. Content structure analysis (H1, H2, etc.)
|
|
56
|
+
6. SEO score (0-100) with justification
|
|
57
|
+
|
|
58
|
+
Content to analyze:
|
|
59
|
+
{content}
|
|
60
|
+
|
|
61
|
+
Provide your analysis in a structured format.""",
|
|
62
|
+
ModelCapability.READABILITY: """Analyze the readability of the following content. Provide:
|
|
63
|
+
1. Readability score (Flesch-Kincaid or similar)
|
|
64
|
+
2. Average sentence length
|
|
65
|
+
3. Complex word count
|
|
66
|
+
4. Grade level assessment
|
|
67
|
+
5. Suggestions for improvement
|
|
68
|
+
6. Overall readability rating (Easy/Medium/Hard)
|
|
69
|
+
|
|
70
|
+
Content to analyze:
|
|
71
|
+
{content}
|
|
72
|
+
|
|
73
|
+
Provide your analysis in a structured format.""",
|
|
74
|
+
ModelCapability.GRAMMAR: """Perform a grammar and style check on the following content. Identify:
|
|
75
|
+
1. Grammatical errors with corrections
|
|
76
|
+
2. Spelling mistakes
|
|
77
|
+
3. Punctuation issues
|
|
78
|
+
4. Style inconsistencies
|
|
79
|
+
5. Clarity improvements
|
|
80
|
+
6. Overall quality score (0-100)
|
|
81
|
+
|
|
82
|
+
Content to analyze:
|
|
83
|
+
{content}
|
|
84
|
+
|
|
85
|
+
Provide your analysis in a structured format.""",
|
|
86
|
+
ModelCapability.SUMMARIZATION: """Provide a comprehensive summary of the following content:
|
|
87
|
+
1. Main topic and key points (3-5 bullet points)
|
|
88
|
+
2. Supporting details
|
|
89
|
+
3. Conclusions or recommendations
|
|
90
|
+
4. One-sentence TL;DR
|
|
91
|
+
|
|
92
|
+
Content to summarize:
|
|
93
|
+
{content}
|
|
94
|
+
|
|
95
|
+
Provide your summary in a structured format.""",
|
|
96
|
+
ModelCapability.KEYWORD_EXTRACTION: """Extract and analyze keywords from the following content:
|
|
97
|
+
1. Primary keywords (top 5-10)
|
|
98
|
+
2. Long-tail keyword phrases
|
|
99
|
+
3. Semantic relationships between keywords
|
|
100
|
+
4. Keyword relevance scores
|
|
101
|
+
5. Suggested additional keywords
|
|
102
|
+
|
|
103
|
+
Content to analyze:
|
|
104
|
+
{content}
|
|
105
|
+
|
|
106
|
+
Provide your keyword analysis in a structured format.""",
|
|
107
|
+
ModelCapability.ACCESSIBILITY: """Analyze the accessibility of the following content:
|
|
108
|
+
1. Language complexity level
|
|
109
|
+
2. Inclusivity assessment
|
|
110
|
+
3. Plain language recommendations
|
|
111
|
+
4. Potential barriers for readers with disabilities
|
|
112
|
+
5. WCAG compliance suggestions
|
|
113
|
+
6. Accessibility score (0-100)
|
|
114
|
+
|
|
115
|
+
Content to analyze:
|
|
116
|
+
{content}
|
|
117
|
+
|
|
118
|
+
Provide your analysis in a structured format.""",
|
|
119
|
+
ModelCapability.SENTIMENT: """Analyze the sentiment and tone of the following content:
|
|
120
|
+
1. Overall sentiment (Positive/Negative/Neutral)
|
|
121
|
+
2. Sentiment score (-1 to +1)
|
|
122
|
+
3. Emotional tone detected
|
|
123
|
+
4. Audience perception analysis
|
|
124
|
+
5. Tone consistency evaluation
|
|
125
|
+
|
|
126
|
+
Content to analyze:
|
|
127
|
+
{content}
|
|
128
|
+
|
|
129
|
+
Provide your analysis in a structured format.""",
|
|
130
|
+
ModelCapability.GENERAL: """Analyze the following content and provide:
|
|
131
|
+
1. Overview and main themes
|
|
132
|
+
2. Quality assessment
|
|
133
|
+
3. Structural analysis
|
|
134
|
+
4. Improvement suggestions
|
|
135
|
+
5. Overall effectiveness rating
|
|
136
|
+
|
|
137
|
+
Content to analyze:
|
|
138
|
+
{content}
|
|
139
|
+
|
|
140
|
+
Provide your analysis in a structured format.""",
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
def __init__(
|
|
144
|
+
self,
|
|
145
|
+
provider_name: str,
|
|
146
|
+
config: Optional[Dict[str, Any]] = None,
|
|
147
|
+
):
|
|
148
|
+
"""
|
|
149
|
+
Initialize base model provider.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
provider_name: Name of the provider (e.g., "ollama", "claude")
|
|
153
|
+
config: Provider-specific configuration
|
|
154
|
+
"""
|
|
155
|
+
super().__init__(service_name=f"{provider_name}_provider", config=config)
|
|
156
|
+
self.provider_name = provider_name
|
|
157
|
+
self.logger = get_logger(f"model.{provider_name}")
|
|
158
|
+
self._request_count = 0
|
|
159
|
+
self._error_count = 0
|
|
160
|
+
self._total_latency = 0.0
|
|
161
|
+
|
|
162
|
+
def get_task_prompt(self, task: ModelCapability, content: str) -> str:
|
|
163
|
+
"""
|
|
164
|
+
Generate task-specific prompt.
|
|
165
|
+
|
|
166
|
+
WHY: Centralizes prompt engineering. Tasks require different analysis
|
|
167
|
+
approaches and output formats.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
task: Type of analysis to perform
|
|
171
|
+
content: Content to analyze
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Formatted prompt string
|
|
175
|
+
"""
|
|
176
|
+
template = self.TASK_PROMPTS.get(
|
|
177
|
+
task, self.TASK_PROMPTS[ModelCapability.GENERAL]
|
|
178
|
+
)
|
|
179
|
+
return template.format(content=content)
|
|
180
|
+
|
|
181
|
+
def create_response(
|
|
182
|
+
self,
|
|
183
|
+
success: bool,
|
|
184
|
+
model: str,
|
|
185
|
+
task: ModelCapability,
|
|
186
|
+
result: str = "",
|
|
187
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
188
|
+
error: Optional[str] = None,
|
|
189
|
+
) -> ModelResponse:
|
|
190
|
+
"""
|
|
191
|
+
Create standardized model response.
|
|
192
|
+
|
|
193
|
+
WHY: Ensures consistent response format across all providers.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
success: Whether operation succeeded
|
|
197
|
+
model: Model used
|
|
198
|
+
task: Task performed
|
|
199
|
+
result: Analysis result
|
|
200
|
+
metadata: Additional metadata
|
|
201
|
+
error: Error message if failed
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
ModelResponse object
|
|
205
|
+
"""
|
|
206
|
+
return ModelResponse(
|
|
207
|
+
success=success,
|
|
208
|
+
provider=self.provider_name,
|
|
209
|
+
model=model,
|
|
210
|
+
task=task.value,
|
|
211
|
+
result=result,
|
|
212
|
+
metadata=metadata or {},
|
|
213
|
+
error=error,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
async def analyze_with_retry(
|
|
217
|
+
self,
|
|
218
|
+
analyze_func,
|
|
219
|
+
content: str,
|
|
220
|
+
task: ModelCapability,
|
|
221
|
+
model: Optional[str] = None,
|
|
222
|
+
max_retries: int = 3,
|
|
223
|
+
**kwargs,
|
|
224
|
+
) -> ModelResponse:
|
|
225
|
+
"""
|
|
226
|
+
Execute analysis with retry logic.
|
|
227
|
+
|
|
228
|
+
WHY: Handles transient failures (network issues, rate limits, etc.)
|
|
229
|
+
without requiring retry logic in each provider implementation.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
analyze_func: Async function to call for analysis
|
|
233
|
+
content: Content to analyze
|
|
234
|
+
task: Task to perform
|
|
235
|
+
model: Optional model to use
|
|
236
|
+
max_retries: Maximum retry attempts
|
|
237
|
+
**kwargs: Additional arguments for analyze_func
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
ModelResponse from successful attempt or final error
|
|
241
|
+
"""
|
|
242
|
+
last_error = None
|
|
243
|
+
|
|
244
|
+
for attempt in range(max_retries):
|
|
245
|
+
try:
|
|
246
|
+
start_time = time.time()
|
|
247
|
+
response = await analyze_func(content, task, model, **kwargs)
|
|
248
|
+
latency = time.time() - start_time
|
|
249
|
+
|
|
250
|
+
# Track metrics
|
|
251
|
+
self._request_count += 1
|
|
252
|
+
self._total_latency += latency
|
|
253
|
+
|
|
254
|
+
if response.success:
|
|
255
|
+
response.metadata["latency_seconds"] = latency
|
|
256
|
+
response.metadata["attempt"] = attempt + 1
|
|
257
|
+
self.log_debug(
|
|
258
|
+
f"Analysis completed in {latency:.2f}s (attempt {attempt + 1})"
|
|
259
|
+
)
|
|
260
|
+
return response
|
|
261
|
+
last_error = response.error
|
|
262
|
+
self._error_count += 1
|
|
263
|
+
|
|
264
|
+
except Exception as e:
|
|
265
|
+
last_error = str(e)
|
|
266
|
+
self._error_count += 1
|
|
267
|
+
self.log_warning(
|
|
268
|
+
f"Analysis attempt {attempt + 1} failed: {e}",
|
|
269
|
+
exc_info=True,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Wait before retry (exponential backoff)
|
|
273
|
+
if attempt < max_retries - 1:
|
|
274
|
+
wait_time = 2**attempt # 1s, 2s, 4s
|
|
275
|
+
self.log_info(f"Retrying in {wait_time}s...")
|
|
276
|
+
await asyncio.sleep(wait_time)
|
|
277
|
+
|
|
278
|
+
# All retries failed
|
|
279
|
+
self.log_error(f"All {max_retries} attempts failed. Last error: {last_error}")
|
|
280
|
+
return self.create_response(
|
|
281
|
+
success=False,
|
|
282
|
+
model=model or "unknown",
|
|
283
|
+
task=task,
|
|
284
|
+
error=f"Failed after {max_retries} attempts: {last_error}",
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def validate_content(self, content: str, max_length: Optional[int] = None) -> bool:
|
|
288
|
+
"""
|
|
289
|
+
Validate content before analysis.
|
|
290
|
+
|
|
291
|
+
WHY: Prevents invalid requests and provides early error detection.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
content: Content to validate
|
|
295
|
+
max_length: Optional maximum length in characters
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
True if valid, False otherwise
|
|
299
|
+
"""
|
|
300
|
+
if not content or not content.strip():
|
|
301
|
+
self.log_warning("Empty content provided for analysis")
|
|
302
|
+
return False
|
|
303
|
+
|
|
304
|
+
if max_length and len(content) > max_length:
|
|
305
|
+
self.log_warning(
|
|
306
|
+
f"Content length {len(content)} exceeds maximum {max_length}"
|
|
307
|
+
)
|
|
308
|
+
return False
|
|
309
|
+
|
|
310
|
+
return True
|
|
311
|
+
|
|
312
|
+
def get_metrics(self) -> Dict[str, Any]:
|
|
313
|
+
"""
|
|
314
|
+
Get provider performance metrics.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Dictionary of metrics (request count, error rate, avg latency)
|
|
318
|
+
"""
|
|
319
|
+
avg_latency = (
|
|
320
|
+
self._total_latency / self._request_count if self._request_count > 0 else 0
|
|
321
|
+
)
|
|
322
|
+
error_rate = (
|
|
323
|
+
self._error_count / self._request_count if self._request_count > 0 else 0
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
"provider": self.provider_name,
|
|
328
|
+
"request_count": self._request_count,
|
|
329
|
+
"error_count": self._error_count,
|
|
330
|
+
"error_rate": error_rate,
|
|
331
|
+
"avg_latency_seconds": avg_latency,
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async def initialize(self) -> bool:
|
|
335
|
+
"""
|
|
336
|
+
Initialize provider.
|
|
337
|
+
|
|
338
|
+
Subclasses should override to perform provider-specific setup.
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
True if initialization successful
|
|
342
|
+
"""
|
|
343
|
+
self.log_info(f"Initializing {self.provider_name} provider")
|
|
344
|
+
self._initialized = True
|
|
345
|
+
return True
|
|
346
|
+
|
|
347
|
+
async def shutdown(self) -> None:
|
|
348
|
+
"""
|
|
349
|
+
Shutdown provider and cleanup resources.
|
|
350
|
+
|
|
351
|
+
Subclasses should override to perform provider-specific cleanup.
|
|
352
|
+
"""
|
|
353
|
+
self.log_info(f"Shutting down {self.provider_name} provider")
|
|
354
|
+
self._shutdown = True
|
|
355
|
+
|
|
356
|
+
@abstractmethod
|
|
357
|
+
async def get_model_info(self, model: str) -> Dict[str, Any]:
|
|
358
|
+
"""
|
|
359
|
+
Get model information.
|
|
360
|
+
|
|
361
|
+
Must be implemented by subclasses.
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
__all__ = ["BaseModelProvider"]
|