| |
| """AI Task Master.ipynb |
| |
| Automatically generated by Colab. |
| |
| Original file is located at |
| https://colab.research.google.com/drive/1k8oLpD1BlJjWEOTZ0UoJQCVyfl9883bE |
| |
| # "AI Task Master" β Multi-Agent Productivity & Execution System |
| |
| # Upload a Goal / To-Do List / Project Idea β Agents break it down β Prioritize β Create action steps β Assign estimated time β Generate a Daily Execution Plan with smart suggestions & progress tracking logic. |
| |
| # π§± Step 0: Colab Setup (Install & Imports) |
| """ |
|
|
| |
|
|
| import os, json, textwrap, datetime as dt |
| from typing import Optional, List, Dict, Any |
|
|
| from crewai import Agent, Task, Crew, Process |
| from langchain_openai import ChatOpenAI |
|
|
| """# π Step 1: Configure API Key (OpenAI) |
| |
| """ |
|
|
| import os |
|
|
| |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") |
|
|
| |
| MODEL_NAME = "gpt-4o-mini" |
| TEMPERATURE = 0.2 |
| llm = ChatOpenAI(model=MODEL_NAME, temperature=TEMPERATURE) |
|
|
| """# π§© Step 2: Project Inputs Helper""" |
|
|
| |
| def default_inputs( |
| goal: str, |
| deadline_days: int = 14, |
| hours_per_day: int = 2, |
| start_date: Optional[str] = None, |
| ) -> Dict[str, Any]: |
| if not start_date: |
| start_date = dt.date.today().isoformat() |
| return { |
| "goal": goal.strip(), |
| "deadline_days": int(deadline_days), |
| "hours_per_day": int(hours_per_day), |
| "start_date": start_date, |
| } |
|
|
| """# π Step 3: Define Agents (Roles + Personalities) |
| |
| """ |
|
|
| |
| goal_understanding = Agent( |
| role="Goal Understanding Agent", |
| backstory=( |
| "You are a thoughtful strategist. You clarify objectives, constraints, " |
| "and success criteria. You avoid fluff and get to the essence." |
| ), |
| goal=( |
| "Rewrite the user's goal clearly and identify assumptions, scope, " |
| "success criteria, hard constraints, and risks." |
| ), |
| allow_delegation=False, |
| llm=llm, |
| ) |
|
|
| |
| task_breakdown = Agent( |
| role="Task Breakdown Agent", |
| backstory=( |
| "You are a senior project planner. You decompose work into milestones " |
| "and concrete tasks that are testable and deliver value." |
| ), |
| goal=( |
| "Produce milestones and detailed subtasks with crisp deliverables." |
| ), |
| allow_delegation=False, |
| llm=llm, |
| ) |
|
|
| |
| effort_priority = Agent( |
| role="Effort & Priority Agent", |
| backstory=( |
| "You are a pragmatic PM. You estimate realistic time and difficulty, " |
| "sequence tasks, and surface dependencies." |
| ), |
| goal=( |
| "Estimate time per task, difficulty (1-5), dependencies, and propose a priority order." |
| ), |
| allow_delegation=False, |
| llm=llm, |
| ) |
|
|
| |
| scheduler = Agent( |
| role="Schedule Maker Agent", |
| backstory=( |
| "You create practical schedules given time budgets per day and deadlines." |
| ), |
| goal=( |
| "Map tasks to days from start_date within deadline_days, respecting hours_per_day." |
| ), |
| allow_delegation=False, |
| llm=llm, |
| ) |
|
|
| |
| motivator = Agent( |
| role="Motivator Agent", |
| backstory=( |
| "You coach users with specific, actionable tips, accountability tactics, and small rewards." |
| ), |
| goal="Provide short, concrete advice to keep momentum high.", |
| allow_delegation=False, |
| llm=llm, |
| ) |
|
|
| |
| synthesizer = Agent( |
| role="Synthesis Agent", |
| backstory=( |
| "You are a concise editor. You assemble a clean, professional plan for download and printing." |
| ), |
| goal="Create final Markdown + JSON outputs for the user.", |
| allow_delegation=False, |
| llm=llm, |
| ) |
|
|
| """# π§ Step 4: Define Tasks (with JSON-first outputs |
| |
| """ |
|
|
| def make_tasks(inputs: Dict[str, Any]) -> List[Task]: |
| common_vars = ( |
| f"GOAL: {inputs['goal']}\n" |
| f"START_DATE: {inputs['start_date']}\n" |
| f"DEADLINE_DAYS: {inputs['deadline_days']}\n" |
| f"HOURS_PER_DAY: {inputs['hours_per_day']}\n" |
| ) |
|
|
| t1 = Task( |
| description=textwrap.dedent(f""" |
| Clarify the user's goal. |
| |
| Context: |
| {common_vars} |
| |
| Return STRICT JSON with keys: |
| {{ |
| "clarified_goal": "...", |
| "assumptions": ["..."], |
| "scope": ["in-scope", "..."], |
| "success_criteria": ["..."], |
| "constraints": ["..."], |
| "risks": ["..."] |
| }} |
| """).strip(), |
| agent=goal_understanding, |
| expected_output="JSON only.", |
| ) |
|
|
| t2 = Task( |
| description=textwrap.dedent(f""" |
| Break the clarified goal into milestones and granular tasks. |
| |
| Input is the JSON from the previous step. |
| Return STRICT JSON: |
| {{ |
| "milestones": [ |
| {{ |
| "name": "...", |
| "description": "...", |
| "tasks": [ |
| {{ |
| "id": "T1", |
| "title": "...", |
| "definition_of_done": "...", |
| "dependencies": [], |
| "tags": ["..."] |
| }} |
| ] |
| }} |
| ] |
| }} |
| """).strip(), |
| agent=task_breakdown, |
| expected_output="JSON only.", |
| ) |
|
|
| t3 = Task( |
| description=textwrap.dedent(f""" |
| Estimate effort and priority for EACH task id from the previous output. |
| |
| Respect HOURS_PER_DAY={inputs['hours_per_day']} and DEADLINE_DAYS={inputs['deadline_days']}. |
| Return STRICT JSON: |
| {{ |
| "estimates": [ |
| {{ |
| "id": "T1", |
| "hours": 2.5, |
| "difficulty_1to5": 3, |
| "priority_1to5": 1 |
| }} |
| ] |
| }} |
| """).strip(), |
| agent=effort_priority, |
| expected_output="JSON only.", |
| ) |
|
|
| t4 = Task( |
| description=textwrap.dedent(f""" |
| Create a day-by-day schedule mapping tasks to calendar dates. |
| |
| Use START_DATE and DEADLINE_DAYS. Do not exceed HOURS_PER_DAY per day. |
| Return STRICT JSON: |
| {{ |
| "schedule": [ |
| {{ |
| "date": "YYYY-MM-DD", |
| "allocated_hours": 2, |
| "tasks": [{{"id":"T1","title":"...","hours":1.5}}] |
| }} |
| ], |
| "summary": {{ |
| "total_hours": 0, |
| "days_planned": 0, |
| "buffer_hours": 0 |
| }} |
| }} |
| """).strip(), |
| agent=scheduler, |
| expected_output="JSON only.", |
| ) |
|
|
| t5 = Task( |
| description=textwrap.dedent(f""" |
| Provide 5 short motivation or execution tactics tailored to the plan. |
| |
| Return STRICT JSON: |
| {{ |
| "tips": [ |
| "Keep daily sessions short & focused with a single visible deliverable.", |
| "..." |
| ] |
| }} |
| """).strip(), |
| agent=motivator, |
| expected_output="JSON only.", |
| ) |
|
|
| t6 = Task( |
| description=textwrap.dedent(f""" |
| Synthesize a final MARKDOWN report AND a JSON bundle. |
| |
| Inputs are the JSONs from all prior tasks. Build: |
| 1) Markdown (for printing) with sections: |
| - Goal Summary |
| - Milestones & Tasks |
| - Estimates & Priorities |
| - Day-by-Day Plan (table) |
| - Tips (bulleted) |
| 2) JSON bundle containing all prior JSON merged into one: keys: |
| {{ |
| "goal_context": ..., |
| "work_breakdown": ..., |
| "estimates": ..., |
| "schedule": ..., |
| "tips": ... |
| }} |
| |
| Return STRICT JSON: |
| {{ |
| "markdown": "....", |
| "bundle": {{ /* merged JSON object */ }} |
| }} |
| """).strip(), |
| agent=synthesizer, |
| expected_output="JSON only.", |
| ) |
|
|
| return [t1, t2, t3, t4, t5, t6] |
|
|
| """# πββοΈ Step 5: Run the Crew""" |
|
|
| def run_planner(goal: str, deadline_days: int = 14, hours_per_day: int = 2, start_date: Optional[str] = None): |
| inputs = default_inputs(goal, deadline_days, hours_per_day, start_date) |
|
|
| tasks = make_tasks(inputs) |
| crew = Crew( |
| agents=[goal_understanding, task_breakdown, effort_priority, scheduler, motivator, synthesizer], |
| tasks=tasks, |
| process=Process.sequential, |
| verbose=True, |
| memory=True, |
| cache=True, |
| ) |
|
|
| result = crew.kickoff(inputs=inputs) |
|
|
| |
| |
| def coerce_json(text: str) -> Dict[str, Any]: |
| try: |
| return json.loads(text) |
| except Exception: |
| |
| start = text.find("{") |
| end = text.rfind("}") |
| if start != -1 and end != -1: |
| return json.loads(text[start:end+1]) |
| raise |
|
|
| final = coerce_json(str(result)) |
| md = final.get("markdown", "# Plan\n\n(No markdown received)") |
| bundle = final.get("bundle", {}) |
|
|
| |
| out_dir = "task_master_outputs" |
| os.makedirs(out_dir, exist_ok=True) |
| stamp = dt.datetime.now().strftime("%Y%m%d_%H%M%S") |
|
|
| md_path = os.path.join(out_dir, f"plan_{stamp}.md") |
| json_path = os.path.join(out_dir, f"plan_{stamp}.json") |
|
|
| with open(md_path, "w", encoding="utf-8") as f: |
| f.write(md) |
| with open(json_path, "w", encoding="utf-8") as f: |
| json.dump(bundle, f, indent=2, ensure_ascii=False) |
|
|
| return { |
| "markdown_path": md_path, |
| "json_path": json_path, |
| "markdown_preview": md[:1500] + ("\n\n...[truncated]..." if len(md) > 1500 else ""), |
| } |
|
|
| """# Step 6: Minimal Gradio UI""" |
|
|
| import gradio as gr |
|
|
| def gradio_run(goal, deadline_days, hours_per_day, start_date): |
| out = run_planner(goal, int(deadline_days), int(hours_per_day), start_date or None) |
| md = "" |
| with open(out["markdown_path"], "r", encoding="utf-8") as f: |
| md = f.read() |
| return md, out["markdown_path"], out["json_path"] |
|
|
| with gr.Blocks(title="CrewAI Task Master") as demo_ui: |
| gr.Markdown("# π§ CrewAI Task Master\nPlan any goal into a day-by-day schedule.") |
| with gr.Row(): |
| goal = gr.Textbox(label="Your Goal", placeholder="e.g., Build an AI portfolio website in 10 days", lines=3) |
| with gr.Row(): |
| deadline = gr.Number(label="Deadline (days)", value=14, precision=0) |
| hours = gr.Number(label="Hours per day", value=2, precision=0) |
| start = gr.Textbox(label="Start Date (YYYY-MM-DD, optional)", placeholder="Leave blank for today") |
| run_btn = gr.Button("Run Agents π") |
|
|
| md_out = gr.Markdown(label="Plan (Markdown)") |
| md_file = gr.File(label="Download Markdown") |
| json_file = gr.File(label="Download JSON") |
|
|
| run_btn.click( |
| gradio_run, |
| inputs=[goal, deadline, hours, start], |
| outputs=[md_out, md_file, json_file] |
| ) |
|
|
| demo_ui.launch(share=False) |
|
|
|
|