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