Spaces:
Running
Running
File size: 8,077 Bytes
eab332f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# data_models/tasks.py
from enum import Enum
from typing import List, Optional, Literal
from pydantic import BaseModel, Field, field_validator
from datetime import datetime
# Using Literal for more precise string enums if preferred over Enum class for Pydantic
# However, Enum provides better structure and can be used with Field choices.
class EffortLevel(str, Enum):
"""Estimated effort level for a task."""
SMALL = "Small"
MEDIUM = "Medium"
LARGE = "Large"
class TaskType(str, Enum):
"""Type of task, indicating its nature."""
INITIATIVE = "initiative" # Action-oriented, new projects/changes
TRACKING = "tracking" # Measurement-focused, monitoring existing metrics/processes
class DataSubject(str, Enum):
"""Specifies the primary data domain a tracking task relates to."""
FOLLOWER_STATS = "follower_stats"
POSTS = "posts"
MENTIONS = "mentions"
GENERAL = "general" # For initiatives or tasks not tied to a single data type
class TimelineCategory(str, Enum):
"""Categorization of task timelines."""
IMMEDIATE = "Immediate" # (e.g., 1-2 weeks)
SHORT_TERM = "Short-term" # (e.g., rest of current quarter, up to 3 months)
MEDIUM_TERM = "Medium-term" # (e.g., next quarter, 3-6 months)
LONG_TERM = "Long-term" # (e.g., 6+ months)
class PriorityLevel(str, Enum):
"""Priority level for tasks."""
HIGH = "High"
MEDIUM = "Medium"
LOW = "Low"
class Task(BaseModel):
"""
Represents a single actionable task derived from analysis.
"""
task_category: str = Field(
description="The broader category or theme of the task (e.g., Content Strategy, Audience Engagement, Reputation Management, Performance Monitoring)."
)
task_description: str = Field( # Renamed from 'task' for clarity
description="A concise yet clear description of the specific action to be taken."
)
objective_deliverable: str = Field(
description="The clear, measurable objective this task aims to achieve and the specific deliverable(s) expected upon completion."
)
effort: EffortLevel = Field(
description="Estimated effort required to complete the task (Small, Medium, Large)."
)
timeline: TimelineCategory = Field(
description="Projected timeline for task completion, considering urgency and dependencies."
)
responsible_party: str = Field(
description="The team, role, or individual suggested to be responsible for executing this task (e.g., Marketing Team, Content Creation Lead, Social Media Manager)."
)
success_criteria_metrics: str = Field(
description="Specific, measurable criteria and metrics that will be used to determine if the task was successfully completed and achieved its objective."
)
dependencies_prerequisites: Optional[str] = Field(
default=None,
description="Any other tasks, resources, or conditions that must be met before this task can begin or be completed."
)
priority: PriorityLevel = Field(
description="The priority level of the task (High, Medium, Low)."
)
priority_justification: str = Field(
description="A brief explanation for the assigned priority level, linking it to impact or urgency."
)
why_proposed: str = Field(
description="The rationale behind proposing this task, clearly linking it back to specific findings or insights from the data analysis."
)
task_type: TaskType = Field(
description="Indicates whether this task is a new 'initiative' or ongoing 'tracking' of performance/metrics."
)
data_subject: Optional[DataSubject] = Field(
default=None,
description="For 'tracking' tasks, specifies the primary data subject (e.g., follower_stats, posts, mentions). Can be 'general' or null for 'initiative' tasks."
)
@field_validator('data_subject')
@classmethod
def check_data_subject_for_tracking(cls, value: Optional[DataSubject], values) -> Optional[DataSubject]:
# Pydantic v2 uses `values.data` to get other field values if needed before validation
# For Pydantic v1, it would be `values.get('task_type')`
# This example assumes Pydantic v2 structure for `values` if needed, but here we only need `task_type`
# which should already be validated or available.
# For simplicity, accessing it via `values.data.get('task_type')` in Pydantic v2 context.
# If using Pydantic v1, it's `values.get('task_type')`.
# Let's assume `values` is a dict-like object containing other fields.
# The validator structure depends on Pydantic version.
# For Pydantic v2, it's `info: ValidationInfo` and `info.data.get('task_type')`
# For Pydantic v1, `values` is a dict.
# For this example, let's assume `values` is a dict of the fields.
task_type_value = None
if hasattr(values, 'data'): # Pydantic v2 way
task_type_value = values.data.get('task_type')
elif isinstance(values, dict): # Pydantic v1 way (or if it's passed as a dict)
task_type_value = values.get('task_type')
if task_type_value == TaskType.TRACKING and value is None:
raise ValueError("For 'tracking' tasks, 'data_subject' must be specified.")
if task_type_value == TaskType.INITIATIVE and value is DataSubject.GENERAL:
# This is acceptable, or you might want to enforce it to be None
pass
return value
class KeyResult(BaseModel):
"""
A measurable outcome that contributes to an Objective.
"""
key_result_description: str = Field( # Renamed from 'key_result'
description="A clear, specific, and measurable description of the key result."
)
tasks: List[Task] = Field(
default_factory=list,
description="A list of specific tasks that will be undertaken to achieve this key result."
)
target_metric: Optional[str] = Field(
default=None,
description="The primary metric used to measure the achievement of this key result (e.g., 'Follower Growth Rate', 'Average Engagement Rate')."
)
target_value: Optional[str] = Field( # Can be numeric or descriptive (e.g., "Increase by 10%", "Achieve 5%")
default=None,
description="The specific target value for the metric (e.g., '5%', '1000 new followers')."
)
class OKR(BaseModel):
"""
Defines an Objective and its associated Key Results (OKRs).
"""
objective_description: str = Field( # Renamed from 'objective'
description="A high-level, qualitative goal that the team aims to achieve. Should be aspirational and motivating."
)
key_results: List[KeyResult] = Field(
default_factory=list,
description="A list of 2-5 specific, measurable, achievable, relevant, and time-bound (SMART) key results that define success for the objective."
)
objective_timeline: TimelineCategory = Field(
description="The overall timeline category for achieving this objective."
)
objective_owner: Optional[str] = Field(
default=None,
description="The team or individual primarily responsible for this objective."
)
class TaskExtractionOutput(BaseModel):
"""
Structured output from the TaskExtractionAgent, including context and OKRs.
"""
current_quarter_info: str = Field(
description="Information about the current quarter and days remaining (e.g., 'Q2 2025, 45 days remaining')."
)
okrs: List[OKR] = Field(
default_factory=list,
description="A list of Objectives and Key Results (OKRs) derived from the analysis."
)
overall_strategic_focus: Optional[str] = Field(
default=None,
description="A brief summary of the main strategic focus areas identified from the tasks."
)
generation_timestamp: str = Field(
default_factory=lambda: datetime.utcnow().isoformat(),
description="Timestamp of when this task extraction output was generated."
)
|