models.py•6.39 kB
"""
Task data models for the Codebuddy MCP server.
Following Clean Code principles:
- Single Responsibility: Each class has one clear purpose
- Descriptive Names: Clear, intention-revealing names
- Small Functions: Each method does one thing well
"""
from datetime import datetime
from enum import Enum
from typing import List, Optional
from uuid import UUID, uuid4
from pydantic import BaseModel, Field
class TaskStatus(str, Enum):
"""
Task status enumeration following the Open/Closed Principle.
New statuses can be added without modifying existing code.
"""
PLANNED = "planned"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
BLOCKED = "blocked"
class Task(BaseModel):
"""
Core Task model with immutable ID and tracked timestamps.
Follows SRP: Represents a single task with its metadata.
Uses composition over inheritance for clean data structure.
Enhanced with cognitive scaffolding for better agentic support.
"""
id: UUID = Field(default_factory=uuid4, description="Unique task identifier")
problem: str = Field(min_length=1, description="Problem description")
steps: List[str] = Field(default_factory=list, description="Task breakdown steps")
status: TaskStatus = Field(default=TaskStatus.PLANNED, description="Current task status")
notes: str = Field(default="", description="Progress notes and updates")
created_at: datetime = Field(default_factory=datetime.utcnow, description="Task creation timestamp")
updated_at: datetime = Field(default_factory=datetime.utcnow, description="Last update timestamp")
# Cognitive scaffolding fields (optional - lightweight)
complexity_level: Optional[str] = Field(default=None, description="Cognitive complexity assessment: simple|moderate|complex")
success_criteria: List[str] = Field(default_factory=list, description="Clear validation criteria for task completion")
dependencies: List[str] = Field(default_factory=list, description="Prerequisites or blocking factors")
risk_factors: List[str] = Field(default_factory=list, description="Potential challenges or failure modes")
learning_notes: List[str] = Field(default_factory=list, description="Insights and patterns discovered during execution")
def update_progress(self, status: TaskStatus, notes: str = "") -> "Task":
"""
Create updated task copy following immutability principle.
Returns new Task instance rather than mutating existing one.
This prevents side effects and makes behavior predictable.
"""
return self.model_copy(update={
"status": status,
"notes": notes,
"updated_at": datetime.utcnow()
})
def add_step(self, step: str) -> "Task":
"""
Add a new step to the task breakdown.
Returns new Task instance with additional step.
"""
new_steps = self.steps + [step]
return self.model_copy(update={
"steps": new_steps,
"updated_at": datetime.utcnow()
})
def matches_query(self, query: str) -> bool:
"""
Check if task matches search query.
Simple keyword matching across problem, steps, and notes.
Case-insensitive for better usability.
"""
search_text = f"{self.problem} {' '.join(self.steps)} {self.notes}".lower()
return query.lower() in search_text
model_config = {
"ser_json_timedelta": "iso8601",
"ser_json_bytes": "base64"
}
class TaskCreateRequest(BaseModel):
"""Request model for creating new tasks with validation."""
problem: str = Field(min_length=1, max_length=1000, description="Problem to solve")
class TaskUpdateRequest(BaseModel):
"""Request model for updating existing tasks."""
task_id: str = Field(description="Task ID to update")
status: TaskStatus = Field(description="New task status")
notes: str = Field(default="", max_length=2000, description="Update notes")
class TaskListResponse(BaseModel):
"""Response model for task listings."""
tasks: List[Task] = Field(description="List of tasks")
total_count: int = Field(description="Total number of tasks in storage")
class CognitiveGuidance(BaseModel):
"""Cognitive scaffolding guidance for agentic users."""
complexity_check: str = Field(description="Cognitive load assessment and guidance")
progress_monitor: str = Field(description="Self-monitoring prompts")
adaptation_prompt: str = Field(description="Guidance when stuck or overwhelmed")
success_pattern: str = Field(description="How to recognize progress and success")
tool_suggestions: List[str] = Field(default_factory=list, description="Recommended tools or next actions")
class ReflectionPrompts(BaseModel):
"""Self-reflection questions for metacognitive thinking."""
assumption_check: str = Field(description="Question about assumptions being made")
simplification_prompt: str = Field(description="How to reduce scope or complexity")
explanation_test: str = Field(description="Can you explain this clearly to someone else?")
class TaskPlanResponse(BaseModel):
"""Enhanced response for task planning with cognitive scaffolding."""
task_id: str = Field(description="Unique identifier for the created task")
cognitive_assessment: dict = Field(description="Complexity and cognitive load analysis")
hierarchical_steps: List[dict] = Field(description="Structured step breakdown with reasoning")
cognitive_guidance: CognitiveGuidance = Field(description="Metacognitive support")
reflection_prompts: ReflectionPrompts = Field(description="Self-reflection questions")
software_engineering_notes: List[str] = Field(description="SE best practices relevant to this task")
class LessonsSummary(BaseModel):
"""Summary of lessons learned from completed tasks."""
success_patterns: List[str] = Field(description="Common patterns in successful tasks")
common_blockers: List[str] = Field(description="Frequent blocking issues")
recommendations: List[str] = Field(description="Actionable recommendations")
tasks_analyzed: int = Field(description="Number of tasks analyzed")
cognitive_insights: List[str] = Field(default_factory=list, description="Patterns about thinking and problem-solving approaches")