forked from Rockachopa/Timmy-time-dashboard
docs: add error handling patterns and module dependencies to CLAUDE.md
- Document 3 graceful degradation patterns with code examples - Add Service Fallback Matrix for optional services - Add module dependency tree with change impact guide chore: fix typecheck environment - Add mypy to dev dependencies in pyproject.toml - Fix tox.ini typecheck environment to install mypy explicitly
This commit is contained in:
96
CLAUDE.md
96
CLAUDE.md
@@ -111,6 +111,55 @@ tox -e dev # Start dashboard with auto-reload
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Error Handling Patterns
|
||||||
|
|
||||||
|
All optional services (Ollama, Redis, AirLLM, voice, etc.) must degrade gracefully. Three approved patterns:
|
||||||
|
|
||||||
|
### Pattern 1: Optional Return (data retrieval)
|
||||||
|
```python
|
||||||
|
def get_user_setting(key: str) -> Optional[str]:
|
||||||
|
try:
|
||||||
|
return db.query(...)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning("Setting lookup failed: %s", exc)
|
||||||
|
return None
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 2: Fallback Value (computations)
|
||||||
|
```python
|
||||||
|
def compute_embedding(text: str) -> list[float]:
|
||||||
|
try:
|
||||||
|
return model.encode(text)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning("Embedding failed, using hash: %s", exc)
|
||||||
|
return hash_based_fallback(text)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 3: Feature Disable (optional services)
|
||||||
|
```python
|
||||||
|
async def transcribe_audio(audio: bytes) -> str:
|
||||||
|
try:
|
||||||
|
return await voice_service.transcribe(audio)
|
||||||
|
except ServiceUnavailable:
|
||||||
|
logger.warning("Voice service unavailable — feature disabled")
|
||||||
|
return "" # Silently disable feature
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Fallback Matrix
|
||||||
|
|
||||||
|
| Service | When Unavailable | Fallback Behavior |
|
||||||
|
|---------|------------------|-------------------|
|
||||||
|
| Ollama | No local LLM | Claude backend (if ANTHROPIC_API_KEY set) |
|
||||||
|
| Redis | Cache/storage down | In-memory dict (ephemeral) |
|
||||||
|
| AirLLM | Import error or no Apple Silicon | Ollama backend |
|
||||||
|
| Voice (Piper) | Service down | Browser Web Speech API |
|
||||||
|
| WebSocket | Connection failed | HTTP polling (degraded) |
|
||||||
|
| Telegram/Discord | No token configured | Bot doesn't start (logs only) |
|
||||||
|
|
||||||
|
**Rule:** Never crash the app when an optional service is down. Log at WARNING level and continue.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Frontend Architecture
|
## Frontend Architecture
|
||||||
|
|
||||||
### Stylesheets
|
### Stylesheets
|
||||||
@@ -181,3 +230,50 @@ McToast.show('Request failed', 'error'); // red border
|
|||||||
| `brain/` | Identity system, memory interface |
|
| `brain/` | Identity system, memory interface |
|
||||||
| `timmy_serve/` | API server |
|
| `timmy_serve/` | API server |
|
||||||
| `config.py` | Pydantic settings (foundation for all modules) |
|
| `config.py` | Pydantic settings (foundation for all modules) |
|
||||||
|
|
||||||
|
## Module Dependencies
|
||||||
|
|
||||||
|
```
|
||||||
|
config.py # Foundation — no internal dependencies
|
||||||
|
│
|
||||||
|
├── timmy/ # Core agent
|
||||||
|
│ ├── Uses: config, brain, infrastructure
|
||||||
|
│ └── Impact: 🔴 High — used by dashboard, integrations, timmy_serve
|
||||||
|
│
|
||||||
|
├── brain/ # Memory system
|
||||||
|
│ ├── Uses: config
|
||||||
|
│ └── Impact: 🟡 Medium — used by timmy, spark
|
||||||
|
│
|
||||||
|
├── infrastructure/ # Shared services
|
||||||
|
│ ├── Uses: config
|
||||||
|
│ └── Impact: 🔴 High — used by ALL packages
|
||||||
|
│ ├── ws_manager # WebSocket connections
|
||||||
|
│ ├── notifier # Push notifications
|
||||||
|
│ └── event_bus # Pub/sub events
|
||||||
|
│
|
||||||
|
├── spark/ # Intelligence engine
|
||||||
|
│ ├── Uses: config, brain
|
||||||
|
│ └── Impact: 🟢 Low — self-contained
|
||||||
|
│
|
||||||
|
├── integrations/ # External services
|
||||||
|
│ ├── Uses: config, infrastructure
|
||||||
|
│ └── Impact: 🟡 Medium — isolated by vendor
|
||||||
|
│
|
||||||
|
├── dashboard/ # Web UI
|
||||||
|
│ ├── Uses: ALL packages
|
||||||
|
│ └── Impact: 🔴 High — entry point, orchestrates everything
|
||||||
|
│
|
||||||
|
└── timmy_serve/ # API server
|
||||||
|
├── Uses: config, timmy, infrastructure
|
||||||
|
└── Impact: 🟡 Medium — standalone service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Change Impact Guide
|
||||||
|
|
||||||
|
| If you modify... | You should test... |
|
||||||
|
|------------------|-------------------|
|
||||||
|
| `config.py` | Full suite (`tox -e ci`) — affects everything |
|
||||||
|
| `infrastructure/` | Unit + integration + functional |
|
||||||
|
| `timmy/` | Unit tests + chat/CLI tests |
|
||||||
|
| `dashboard/routes/` | Dashboard route tests (usually isolated) |
|
||||||
|
| `brain/` | Brain client/worker tests + timmy tests |
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ selenium = ">=4.20.0"
|
|||||||
pytest-randomly = "^4.0.1"
|
pytest-randomly = "^4.0.1"
|
||||||
pytest-xdist = "^3.8.0"
|
pytest-xdist = "^3.8.0"
|
||||||
ruff = ">=0.8.0"
|
ruff = ">=0.8.0"
|
||||||
|
mypy = ">=1.0.0"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
timmy = "timmy.cli:main"
|
timmy = "timmy.cli:main"
|
||||||
|
|||||||
3
tox.ini
3
tox.ini
@@ -38,6 +38,9 @@ commands =
|
|||||||
|
|
||||||
[testenv:typecheck]
|
[testenv:typecheck]
|
||||||
description = Static type checking with mypy
|
description = Static type checking with mypy
|
||||||
|
commands_pre =
|
||||||
|
deps =
|
||||||
|
mypy>=1.0.0
|
||||||
commands =
|
commands =
|
||||||
mypy src --ignore-missing-imports --no-error-summary
|
mypy src --ignore-missing-imports --no-error-summary
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user