restrcuted repo

This commit is contained in:
2025-09-26 06:52:27 -07:00
parent 997028f0e1
commit 15974bbac5
26 changed files with 17 additions and 12 deletions

269
README.md Normal file
View File

@@ -0,0 +1,269 @@
# Cycling Workout Analyzer - Clean Architecture
A modular, extensible cycling workout analyzer built with a clean architecture that separates core concerns into focused modules.
## Architecture Overview
The application is structured into distinct, focused modules:
```
├── core_app.py # Main orchestrator
├── config.py # Configuration management
├── llm_client.py # LLM interactions
├── mcp_client.py # MCP server management
├── cache_manager.py # Data caching with TTL
├── template_engine.py # Template loading/rendering
├── cli_interface.py # Command line interface
└── requirements.txt # Dependencies
```
## Core Features
### 🤖 LLM Integration
- OpenRouter API support with multiple models
- Both tool-enabled and tool-free analysis modes
- Async request handling with timeouts
### 🔧 MCP Tool Management
- Automatic MCP server discovery and connection
- Tool listing and direct tool calling
- Garth MCP server integration for Garmin data
### 💾 Smart Caching
- TTL-based caching system
- Pre-loading of common data (user profile, activities)
- Specialized cycling data cache helpers
### 📝 Template System
- Modular template structure
- Section includes and variable substitution
- Auto-creation of default templates
### ⚙️ Configuration
- YAML config files with environment variable fallback
- Automatic sample config generation
- Extensible configuration structure
## Quick Start
### 1. Install Dependencies
```bash
pip install -r requirements.txt
# Install MCP server for Garmin data
npm install -g garth-mcp-server
```
### 2. Configure
```bash
# Run once to create config.yaml
python cli_interface.py
# Edit config.yaml with your API keys
```
### 3. Run
```bash
python cli_interface.py
```
## Usage Examples
### Basic Analysis
```python
from config import load_config
from core_app import CyclingAnalyzerApp
config = load_config()
app = CyclingAnalyzerApp(config)
await app.initialize()
# Analyze last workout
analysis = await app.analyze_workout("analyze_last_workout")
print(analysis)
# Get workout suggestion
suggestion = await app.suggest_next_workout()
print(suggestion)
await app.cleanup()
```
### Custom Analysis
```python
# Enhanced analysis with tools
analysis = await app.enhanced_analysis(
"performance_trends",
training_rules="Custom rules here"
)
# Check what tools are available
tools = app.list_available_tools()
for tool in tools:
print(f"- {tool.name}: {tool.description}")
```
### Cache Management
```python
# Check cached data
cached = app.get_cached_data()
print("Cached keys:", list(cached.keys()))
# Cache custom data
app.cache_manager.set("custom_key", {"data": "value"}, ttl=600)
```
## Configuration
### config.yaml
```yaml
# LLM Settings
openrouter_api_key: "your_api_key_here"
openrouter_model: "deepseek/deepseek-r1-0528:free"
# MCP Settings
garth_token: "your_garth_token_here"
garth_mcp_server_path: "uvx"
# Application Settings
templates_dir: "templates"
rules_file: "rules.yaml"
cache_ttl: 300
log_level: "INFO"
```
### Environment Variables
```bash
export OPENROUTER_API_KEY="your_key"
export GARTH_TOKEN="your_token"
export LOG_LEVEL="DEBUG"
```
## Extension Points
### Custom Analysis Types
```python
# Add new analysis in core_app.py
async def custom_analysis(self, **kwargs) -> str:
template = "workflows/custom_analysis.txt"
context = {"custom_data": kwargs}
prompt = self.template_engine.render(template, **context)
return await self.llm_client.generate(prompt)
```
### Custom MCP Tools
```python
# Add new tool support in mcp_client.py
async def call_custom_tool(self, parameters: dict) -> dict:
return await self.call_tool("custom_tool", parameters)
```
### Custom Templates
Create new templates in `templates/workflows/`:
```
templates/
├── workflows/
│ ├── my_analysis.txt
│ └── custom_report.txt
├── base/
│ ├── data_sections/
│ └── analysis_frameworks/
```
### Custom Cache Strategies
```python
from cache_manager import CacheManager
class CustomCache(CacheManager):
def cache_performance_data(self, data, athlete_id):
self.set(f"performance_{athlete_id}", data, ttl=1800)
```
## Architecture Benefits
### Separation of Concerns
- **Config**: Handles all configuration logic
- **LLM Client**: Pure LLM interactions
- **MCP Client**: Tool management only
- **Cache**: Data persistence with TTL
- **Templates**: Prompt composition
- **CLI**: User interface
### Extensibility
- Easy to add new LLM providers
- Plugin-style MCP tool additions
- Template-based prompt customization
- Configurable caching strategies
### Testability
- Each module has single responsibility
- Clear interfaces between components
- Mock-friendly async design
- Dependency injection ready
### Maintainability
- Small, focused files
- Clear naming conventions
- Comprehensive logging
- Error handling at boundaries
## Advanced Features
### Template Inheritance
Templates can include sections and inherit from base templates:
```
{activity_summary_section} # Includes base/data_sections/activity_summary.txt
{assessment_points} # Includes base/analysis_frameworks/assessment_points.txt
```
### Dynamic Tool Selection
The app automatically detects available tools and adjusts functionality:
```python
if await self.mcp_client.has_tool("hrv_data"):
hrv_data = await self.mcp_client.call_tool("hrv_data", {})
```
### Cache Warming
Common data is pre-loaded during initialization:
- User profile (1 hour TTL)
- Recent activities (15 min TTL)
- Last cycling activity details (1 hour TTL)
## Troubleshooting
### MCP Connection Issues
```bash
# Check if garth-mcp-server is installed
which garth-mcp-server
# Test Garth token
uvx garth login
```
### Template Errors
```bash
# List available templates
python -c "from template_engine import TemplateEngine; print(TemplateEngine('templates').list_templates())"
# Check template variables
python -c "from template_engine import TemplateEngine; print(TemplateEngine('templates').get_template_info('workflows/analyze_last_workout.txt'))"
```
### Cache Issues
```bash
# Clear cache
python -c "from cache_manager import CacheManager; CacheManager().clear()"
```
## Contributing
The modular architecture makes contributions straightforward:
1. **New LLM Provider**: Extend `LLMClient`
2. **New Data Source**: Create new MCP client
3. **New Analysis**: Add templates and methods
4. **New Interface**: Create alternative to CLI
5. **New Cache Strategy**: Extend `CacheManager`
Each module is independently testable and can be developed in isolation.