Rahaf2001 commited on
Commit
5afc3c4
·
verified ·
1 Parent(s): 35a36a5

Upload 3 files

Browse files
Files changed (3) hide show
  1. AI_Task_Master.ipynb +584 -0
  2. app.py +378 -0
  3. requirements.txt +5 -0
AI_Task_Master.ipynb ADDED
@@ -0,0 +1,584 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "markdown",
19
+ "source": [
20
+ "# \"AI Task Master\" — Multi-Agent Productivity & Execution System\n",
21
+ "\n",
22
+ "# 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."
23
+ ],
24
+ "metadata": {
25
+ "id": "hMAysKRQphEj"
26
+ }
27
+ },
28
+ {
29
+ "cell_type": "markdown",
30
+ "source": [
31
+ "# 🧱 Step 0: Colab Setup (Install & Imports)"
32
+ ],
33
+ "metadata": {
34
+ "id": "IRKP3gswqJSu"
35
+ }
36
+ },
37
+ {
38
+ "cell_type": "code",
39
+ "source": [
40
+ "#!pip install --quiet crewai langchain-openai gradio python-dotenv pydantic -q"
41
+ ],
42
+ "metadata": {
43
+ "id": "58wVUNhZnxQh"
44
+ },
45
+ "execution_count": null,
46
+ "outputs": []
47
+ },
48
+ {
49
+ "cell_type": "markdown",
50
+ "source": [],
51
+ "metadata": {
52
+ "id": "sH9afYAjqdCa"
53
+ }
54
+ },
55
+ {
56
+ "cell_type": "code",
57
+ "source": [
58
+ "import os, json, textwrap, datetime as dt\n",
59
+ "from typing import Optional, List, Dict, Any\n",
60
+ "\n",
61
+ "from crewai import Agent, Task, Crew, Process\n",
62
+ "from langchain_openai import ChatOpenAI\n"
63
+ ],
64
+ "metadata": {
65
+ "id": "EwHFD9RSnsRg"
66
+ },
67
+ "execution_count": null,
68
+ "outputs": []
69
+ },
70
+ {
71
+ "cell_type": "markdown",
72
+ "source": [
73
+ "# 🔐 Step 1: Configure API Key (OpenAI)\n"
74
+ ],
75
+ "metadata": {
76
+ "id": "qiL6nGlGqe_w"
77
+ }
78
+ },
79
+ {
80
+ "cell_type": "code",
81
+ "source": [
82
+ "from google.colab import userdata\n",
83
+ "\n",
84
+ "# Retrieve the API key from Colab secrets\n",
85
+ "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')\n",
86
+ "\n",
87
+ "# Model defaults (you can change)\n",
88
+ "MODEL_NAME = \"gpt-4o-mini\" # fast & smart\n",
89
+ "TEMPERATURE = 0.2\n",
90
+ "llm = ChatOpenAI(model=MODEL_NAME, temperature=TEMPERATURE)"
91
+ ],
92
+ "metadata": {
93
+ "id": "3A7Xcn2Qn81O"
94
+ },
95
+ "execution_count": null,
96
+ "outputs": []
97
+ },
98
+ {
99
+ "cell_type": "markdown",
100
+ "source": [
101
+ "# 🧩 Step 2: Project Inputs Helper"
102
+ ],
103
+ "metadata": {
104
+ "id": "aFEecuUqqiiQ"
105
+ }
106
+ },
107
+ {
108
+ "cell_type": "code",
109
+ "source": [
110
+ "# Light helper to bundle inputs\n",
111
+ "def default_inputs(\n",
112
+ " goal: str,\n",
113
+ " deadline_days: int = 14,\n",
114
+ " hours_per_day: int = 2,\n",
115
+ " start_date: Optional[str] = None,\n",
116
+ ") -> Dict[str, Any]:\n",
117
+ " if not start_date:\n",
118
+ " start_date = dt.date.today().isoformat()\n",
119
+ " return {\n",
120
+ " \"goal\": goal.strip(),\n",
121
+ " \"deadline_days\": int(deadline_days),\n",
122
+ " \"hours_per_day\": int(hours_per_day),\n",
123
+ " \"start_date\": start_date,\n",
124
+ " }\n"
125
+ ],
126
+ "metadata": {
127
+ "id": "RUHRmzmwoM6E"
128
+ },
129
+ "execution_count": null,
130
+ "outputs": []
131
+ },
132
+ {
133
+ "cell_type": "markdown",
134
+ "source": [
135
+ "# 🎭 Step 3: Define Agents (Roles + Personalities)\n"
136
+ ],
137
+ "metadata": {
138
+ "id": "mt9NZfhlqmEd"
139
+ }
140
+ },
141
+ {
142
+ "cell_type": "code",
143
+ "source": [
144
+ "# Agent: Understand the user's goal & constraints\n",
145
+ "goal_understanding = Agent(\n",
146
+ " role=\"Goal Understanding Agent\",\n",
147
+ " backstory=(\n",
148
+ " \"You are a thoughtful strategist. You clarify objectives, constraints, \"\n",
149
+ " \"and success criteria. You avoid fluff and get to the essence.\"\n",
150
+ " ),\n",
151
+ " goal=(\n",
152
+ " \"Rewrite the user's goal clearly and identify assumptions, scope, \"\n",
153
+ " \"success criteria, hard constraints, and risks.\"\n",
154
+ " ),\n",
155
+ " allow_delegation=False,\n",
156
+ " llm=llm,\n",
157
+ ")\n",
158
+ "\n",
159
+ "# Agent: Break the goal into milestones & tasks\n",
160
+ "task_breakdown = Agent(\n",
161
+ " role=\"Task Breakdown Agent\",\n",
162
+ " backstory=(\n",
163
+ " \"You are a senior project planner. You decompose work into milestones \"\n",
164
+ " \"and concrete tasks that are testable and deliver value.\"\n",
165
+ " ),\n",
166
+ " goal=(\n",
167
+ " \"Produce milestones and detailed subtasks with crisp deliverables.\"\n",
168
+ " ),\n",
169
+ " allow_delegation=False,\n",
170
+ " llm=llm,\n",
171
+ ")\n",
172
+ "\n",
173
+ "# Agent: Estimate effort & prioritize\n",
174
+ "effort_priority = Agent(\n",
175
+ " role=\"Effort & Priority Agent\",\n",
176
+ " backstory=(\n",
177
+ " \"You are a pragmatic PM. You estimate realistic time and difficulty, \"\n",
178
+ " \"sequence tasks, and surface dependencies.\"\n",
179
+ " ),\n",
180
+ " goal=(\n",
181
+ " \"Estimate time per task, difficulty (1-5), dependencies, and propose a priority order.\"\n",
182
+ " ),\n",
183
+ " allow_delegation=False,\n",
184
+ " llm=llm,\n",
185
+ ")\n",
186
+ "\n",
187
+ "# Agent: Build a calendar-style plan\n",
188
+ "scheduler = Agent(\n",
189
+ " role=\"Schedule Maker Agent\",\n",
190
+ " backstory=(\n",
191
+ " \"You create practical schedules given time budgets per day and deadlines.\"\n",
192
+ " ),\n",
193
+ " goal=(\n",
194
+ " \"Map tasks to days from start_date within deadline_days, respecting hours_per_day.\"\n",
195
+ " ),\n",
196
+ " allow_delegation=False,\n",
197
+ " llm=llm,\n",
198
+ ")\n",
199
+ "\n",
200
+ "# Agent: Motivation & execution tips (optional spice)\n",
201
+ "motivator = Agent(\n",
202
+ " role=\"Motivator Agent\",\n",
203
+ " backstory=(\n",
204
+ " \"You coach users with specific, actionable tips, accountability tactics, and small rewards.\"\n",
205
+ " ),\n",
206
+ " goal=\"Provide short, concrete advice to keep momentum high.\",\n",
207
+ " allow_delegation=False,\n",
208
+ " llm=llm,\n",
209
+ ")\n",
210
+ "\n",
211
+ "# Agent: Final synthesis for export\n",
212
+ "synthesizer = Agent(\n",
213
+ " role=\"Synthesis Agent\",\n",
214
+ " backstory=(\n",
215
+ " \"You are a concise editor. You assemble a clean, professional plan for download and printing.\"\n",
216
+ " ),\n",
217
+ " goal=\"Create final Markdown + JSON outputs for the user.\",\n",
218
+ " allow_delegation=False,\n",
219
+ " llm=llm,\n",
220
+ ")\n"
221
+ ],
222
+ "metadata": {
223
+ "id": "U9Wvk1DqoYwx"
224
+ },
225
+ "execution_count": null,
226
+ "outputs": []
227
+ },
228
+ {
229
+ "cell_type": "markdown",
230
+ "source": [
231
+ "# 🧠 Step 4: Define Tasks (with JSON-first outputs\n"
232
+ ],
233
+ "metadata": {
234
+ "id": "_jgH0_8TqprY"
235
+ }
236
+ },
237
+ {
238
+ "cell_type": "code",
239
+ "source": [
240
+ "def make_tasks(inputs: Dict[str, Any]) -> List[Task]:\n",
241
+ " common_vars = (\n",
242
+ " f\"GOAL: {inputs['goal']}\\n\"\n",
243
+ " f\"START_DATE: {inputs['start_date']}\\n\"\n",
244
+ " f\"DEADLINE_DAYS: {inputs['deadline_days']}\\n\"\n",
245
+ " f\"HOURS_PER_DAY: {inputs['hours_per_day']}\\n\"\n",
246
+ " )\n",
247
+ "\n",
248
+ " t1 = Task(\n",
249
+ " description=textwrap.dedent(f\"\"\"\n",
250
+ " Clarify the user's goal.\n",
251
+ "\n",
252
+ " Context:\n",
253
+ " {common_vars}\n",
254
+ "\n",
255
+ " Return STRICT JSON with keys:\n",
256
+ " {{\n",
257
+ " \"clarified_goal\": \"...\",\n",
258
+ " \"assumptions\": [\"...\"],\n",
259
+ " \"scope\": [\"in-scope\", \"...\"],\n",
260
+ " \"success_criteria\": [\"...\"],\n",
261
+ " \"constraints\": [\"...\"],\n",
262
+ " \"risks\": [\"...\"]\n",
263
+ " }}\n",
264
+ " \"\"\").strip(),\n",
265
+ " agent=goal_understanding,\n",
266
+ " expected_output=\"JSON only.\",\n",
267
+ " )\n",
268
+ "\n",
269
+ " t2 = Task(\n",
270
+ " description=textwrap.dedent(f\"\"\"\n",
271
+ " Break the clarified goal into milestones and granular tasks.\n",
272
+ "\n",
273
+ " Input is the JSON from the previous step.\n",
274
+ " Return STRICT JSON:\n",
275
+ " {{\n",
276
+ " \"milestones\": [\n",
277
+ " {{\n",
278
+ " \"name\": \"...\",\n",
279
+ " \"description\": \"...\",\n",
280
+ " \"tasks\": [\n",
281
+ " {{\n",
282
+ " \"id\": \"T1\",\n",
283
+ " \"title\": \"...\",\n",
284
+ " \"definition_of_done\": \"...\",\n",
285
+ " \"dependencies\": [],\n",
286
+ " \"tags\": [\"...\"]\n",
287
+ " }}\n",
288
+ " ]\n",
289
+ " }}\n",
290
+ " ]\n",
291
+ " }}\n",
292
+ " \"\"\").strip(),\n",
293
+ " agent=task_breakdown,\n",
294
+ " expected_output=\"JSON only.\",\n",
295
+ " )\n",
296
+ "\n",
297
+ " t3 = Task(\n",
298
+ " description=textwrap.dedent(f\"\"\"\n",
299
+ " Estimate effort and priority for EACH task id from the previous output.\n",
300
+ "\n",
301
+ " Respect HOURS_PER_DAY={inputs['hours_per_day']} and DEADLINE_DAYS={inputs['deadline_days']}.\n",
302
+ " Return STRICT JSON:\n",
303
+ " {{\n",
304
+ " \"estimates\": [\n",
305
+ " {{\n",
306
+ " \"id\": \"T1\",\n",
307
+ " \"hours\": 2.5,\n",
308
+ " \"difficulty_1to5\": 3,\n",
309
+ " \"priority_1to5\": 1\n",
310
+ " }}\n",
311
+ " ]\n",
312
+ " }}\n",
313
+ " \"\"\").strip(),\n",
314
+ " agent=effort_priority,\n",
315
+ " expected_output=\"JSON only.\",\n",
316
+ " )\n",
317
+ "\n",
318
+ " t4 = Task(\n",
319
+ " description=textwrap.dedent(f\"\"\"\n",
320
+ " Create a day-by-day schedule mapping tasks to calendar dates.\n",
321
+ "\n",
322
+ " Use START_DATE and DEADLINE_DAYS. Do not exceed HOURS_PER_DAY per day.\n",
323
+ " Return STRICT JSON:\n",
324
+ " {{\n",
325
+ " \"schedule\": [\n",
326
+ " {{\n",
327
+ " \"date\": \"YYYY-MM-DD\",\n",
328
+ " \"allocated_hours\": 2,\n",
329
+ " \"tasks\": [{{\"id\":\"T1\",\"title\":\"...\",\"hours\":1.5}}]\n",
330
+ " }}\n",
331
+ " ],\n",
332
+ " \"summary\": {{\n",
333
+ " \"total_hours\": 0,\n",
334
+ " \"days_planned\": 0,\n",
335
+ " \"buffer_hours\": 0\n",
336
+ " }}\n",
337
+ " }}\n",
338
+ " \"\"\").strip(),\n",
339
+ " agent=scheduler,\n",
340
+ " expected_output=\"JSON only.\",\n",
341
+ " )\n",
342
+ "\n",
343
+ " t5 = Task(\n",
344
+ " description=textwrap.dedent(f\"\"\"\n",
345
+ " Provide 5 short motivation or execution tactics tailored to the plan.\n",
346
+ "\n",
347
+ " Return STRICT JSON:\n",
348
+ " {{\n",
349
+ " \"tips\": [\n",
350
+ " \"Keep daily sessions short & focused with a single visible deliverable.\",\n",
351
+ " \"...\"\n",
352
+ " ]\n",
353
+ " }}\n",
354
+ " \"\"\").strip(),\n",
355
+ " agent=motivator,\n",
356
+ " expected_output=\"JSON only.\",\n",
357
+ " )\n",
358
+ "\n",
359
+ " t6 = Task(\n",
360
+ " description=textwrap.dedent(f\"\"\"\n",
361
+ " Synthesize a final MARKDOWN report AND a JSON bundle.\n",
362
+ "\n",
363
+ " Inputs are the JSONs from all prior tasks. Build:\n",
364
+ " 1) Markdown (for printing) with sections:\n",
365
+ " - Goal Summary\n",
366
+ " - Milestones & Tasks\n",
367
+ " - Estimates & Priorities\n",
368
+ " - Day-by-Day Plan (table)\n",
369
+ " - Tips (bulleted)\n",
370
+ " 2) JSON bundle containing all prior JSON merged into one: keys:\n",
371
+ " {{\n",
372
+ " \"goal_context\": ...,\n",
373
+ " \"work_breakdown\": ...,\n",
374
+ " \"estimates\": ...,\n",
375
+ " \"schedule\": ...,\n",
376
+ " \"tips\": ...\n",
377
+ " }}\n",
378
+ "\n",
379
+ " Return STRICT JSON:\n",
380
+ " {{\n",
381
+ " \"markdown\": \"....\",\n",
382
+ " \"bundle\": {{ /* merged JSON object */ }}\n",
383
+ " }}\n",
384
+ " \"\"\").strip(),\n",
385
+ " agent=synthesizer,\n",
386
+ " expected_output=\"JSON only.\",\n",
387
+ " )\n",
388
+ "\n",
389
+ " return [t1, t2, t3, t4, t5, t6]\n"
390
+ ],
391
+ "metadata": {
392
+ "id": "bULXBMGZoacv"
393
+ },
394
+ "execution_count": null,
395
+ "outputs": []
396
+ },
397
+ {
398
+ "cell_type": "markdown",
399
+ "source": [
400
+ "# 🏃‍♂️ Step 5: Run the Crew"
401
+ ],
402
+ "metadata": {
403
+ "id": "CBxM7WSqrFzR"
404
+ }
405
+ },
406
+ {
407
+ "cell_type": "code",
408
+ "source": [
409
+ "def run_planner(goal: str, deadline_days: int = 14, hours_per_day: int = 2, start_date: Optional[str] = None):\n",
410
+ " inputs = default_inputs(goal, deadline_days, hours_per_day, start_date)\n",
411
+ "\n",
412
+ " tasks = make_tasks(inputs)\n",
413
+ " crew = Crew(\n",
414
+ " agents=[goal_understanding, task_breakdown, effort_priority, scheduler, motivator, synthesizer],\n",
415
+ " tasks=tasks,\n",
416
+ " process=Process.sequential, # run in order\n",
417
+ " verbose=True,\n",
418
+ " memory=True,\n",
419
+ " cache=True,\n",
420
+ " )\n",
421
+ "\n",
422
+ " result = crew.kickoff(inputs=inputs)\n",
423
+ "\n",
424
+ " # The final task returns JSON with 'markdown' and 'bundle'\n",
425
+ " # crewai often returns extra text around json; ensure it's valid JSON:\n",
426
+ " def coerce_json(text: str) -> Dict[str, Any]:\n",
427
+ " try:\n",
428
+ " return json.loads(text)\n",
429
+ " except Exception:\n",
430
+ " # Try to extract JSON block heuristically\n",
431
+ " start = text.find(\"{\")\n",
432
+ " end = text.rfind(\"}\")\n",
433
+ " if start != -1 and end != -1:\n",
434
+ " return json.loads(text[start:end+1])\n",
435
+ " raise\n",
436
+ "\n",
437
+ " final = coerce_json(str(result))\n",
438
+ " md = final.get(\"markdown\", \"# Plan\\n\\n(No markdown received)\")\n",
439
+ " bundle = final.get(\"bundle\", {})\n",
440
+ "\n",
441
+ " # Save artifacts\n",
442
+ " out_dir = \"/content/task_master_outputs\"\n",
443
+ " os.makedirs(out_dir, exist_ok=True)\n",
444
+ " stamp = dt.datetime.now().strftime(\"%Y%m%d_%H%M%S\")\n",
445
+ "\n",
446
+ " md_path = os.path.join(out_dir, f\"plan_{stamp}.md\")\n",
447
+ " json_path = os.path.join(out_dir, f\"plan_{stamp}.json\")\n",
448
+ "\n",
449
+ " with open(md_path, \"w\", encoding=\"utf-8\") as f:\n",
450
+ " f.write(md)\n",
451
+ " with open(json_path, \"w\", encoding=\"utf-8\") as f:\n",
452
+ " json.dump(bundle, f, indent=2, ensure_ascii=False)\n",
453
+ "\n",
454
+ " return {\n",
455
+ " \"markdown_path\": md_path,\n",
456
+ " \"json_path\": json_path,\n",
457
+ " \"markdown_preview\": md[:1500] + (\"\\n\\n...[truncated]...\" if len(md) > 1500 else \"\"),\n",
458
+ " }\n"
459
+ ],
460
+ "metadata": {
461
+ "id": "wikuoefWoc0Z"
462
+ },
463
+ "execution_count": null,
464
+ "outputs": []
465
+ },
466
+ {
467
+ "cell_type": "markdown",
468
+ "source": [
469
+ "# Step 6: Minimal Gradio UI"
470
+ ],
471
+ "metadata": {
472
+ "id": "bbs5keN2rOAh"
473
+ }
474
+ },
475
+ {
476
+ "cell_type": "code",
477
+ "source": [
478
+ "import gradio as gr\n",
479
+ "\n",
480
+ "def gradio_run(goal, deadline_days, hours_per_day, start_date):\n",
481
+ " out = run_planner(goal, int(deadline_days), int(hours_per_day), start_date or None)\n",
482
+ " md = \"\"\n",
483
+ " with open(out[\"markdown_path\"], \"r\", encoding=\"utf-8\") as f:\n",
484
+ " md = f.read()\n",
485
+ " return md, out[\"markdown_path\"], out[\"json_path\"]\n",
486
+ "\n",
487
+ "with gr.Blocks(title=\"CrewAI Task Master\") as demo_ui:\n",
488
+ " gr.Markdown(\"# 🧠 CrewAI Task Master\\nPlan any goal into a day-by-day schedule.\")\n",
489
+ " with gr.Row():\n",
490
+ " goal = gr.Textbox(label=\"Your Goal\", placeholder=\"e.g., Build an AI portfolio website in 10 days\", lines=3)\n",
491
+ " with gr.Row():\n",
492
+ " deadline = gr.Number(label=\"Deadline (days)\", value=14, precision=0)\n",
493
+ " hours = gr.Number(label=\"Hours per day\", value=2, precision=0)\n",
494
+ " start = gr.Textbox(label=\"Start Date (YYYY-MM-DD, optional)\", placeholder=\"Leave blank for today\")\n",
495
+ " run_btn = gr.Button(\"Run Agents 🚀\")\n",
496
+ "\n",
497
+ " md_out = gr.Markdown(label=\"Plan (Markdown)\")\n",
498
+ " md_file = gr.File(label=\"Download Markdown\")\n",
499
+ " json_file = gr.File(label=\"Download JSON\")\n",
500
+ "\n",
501
+ " run_btn.click(\n",
502
+ " gradio_run,\n",
503
+ " inputs=[goal, deadline, hours, start],\n",
504
+ " outputs=[md_out, md_file, json_file]\n",
505
+ " )\n",
506
+ "\n",
507
+ "demo_ui.launch(share=False)\n"
508
+ ],
509
+ "metadata": {
510
+ "colab": {
511
+ "base_uri": "https://localhost:8080/",
512
+ "height": 599
513
+ },
514
+ "id": "HDJKz5r4oisy",
515
+ "outputId": "1c91172e-6ac4-4d3e-8074-1ad8ced4fc9a"
516
+ },
517
+ "execution_count": null,
518
+ "outputs": [
519
+ {
520
+ "output_type": "stream",
521
+ "name": "stdout",
522
+ "text": [
523
+ "Colab notebook detected. To show errors in colab notebook, set debug=True in launch()\n",
524
+ "Note: opening Chrome Inspector may crash demo inside Colab notebooks.\n",
525
+ "* To create a public link, set `share=True` in `launch()`.\n"
526
+ ]
527
+ },
528
+ {
529
+ "output_type": "display_data",
530
+ "data": {
531
+ "text/plain": [
532
+ "<IPython.core.display.Javascript object>"
533
+ ],
534
+ "application/javascript": [
535
+ "(async (port, path, width, height, cache, element) => {\n",
536
+ " if (!google.colab.kernel.accessAllowed && !cache) {\n",
537
+ " return;\n",
538
+ " }\n",
539
+ " element.appendChild(document.createTextNode(''));\n",
540
+ " const url = await google.colab.kernel.proxyPort(port, {cache});\n",
541
+ "\n",
542
+ " const external_link = document.createElement('div');\n",
543
+ " external_link.innerHTML = `\n",
544
+ " <div style=\"font-family: monospace; margin-bottom: 0.5rem\">\n",
545
+ " Running on <a href=${new URL(path, url).toString()} target=\"_blank\">\n",
546
+ " https://localhost:${port}${path}\n",
547
+ " </a>\n",
548
+ " </div>\n",
549
+ " `;\n",
550
+ " element.appendChild(external_link);\n",
551
+ "\n",
552
+ " const iframe = document.createElement('iframe');\n",
553
+ " iframe.src = new URL(path, url).toString();\n",
554
+ " iframe.height = height;\n",
555
+ " iframe.allow = \"autoplay; camera; microphone; clipboard-read; clipboard-write;\"\n",
556
+ " iframe.width = width;\n",
557
+ " iframe.style.border = 0;\n",
558
+ " element.appendChild(iframe);\n",
559
+ " })(7860, \"/\", \"100%\", 500, false, window.element)"
560
+ ]
561
+ },
562
+ "metadata": {}
563
+ },
564
+ {
565
+ "output_type": "execute_result",
566
+ "data": {
567
+ "text/plain": []
568
+ },
569
+ "metadata": {},
570
+ "execution_count": 11
571
+ }
572
+ ]
573
+ },
574
+ {
575
+ "cell_type": "code",
576
+ "source": [],
577
+ "metadata": {
578
+ "id": "YC9b0G8romnv"
579
+ },
580
+ "execution_count": null,
581
+ "outputs": []
582
+ }
583
+ ]
584
+ }
app.py ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """AI Task Master.ipynb
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1k8oLpD1BlJjWEOTZ0UoJQCVyfl9883bE
8
+
9
+ # "AI Task Master" — Multi-Agent Productivity & Execution System
10
+
11
+ # 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.
12
+
13
+ # 🧱 Step 0: Colab Setup (Install & Imports)
14
+ """
15
+
16
+ #!pip install --quiet crewai langchain-openai gradio python-dotenv pydantic -q
17
+
18
+ import os, json, textwrap, datetime as dt
19
+ from typing import Optional, List, Dict, Any
20
+
21
+ from crewai import Agent, Task, Crew, Process
22
+ from langchain_openai import ChatOpenAI
23
+
24
+ """# 🔐 Step 1: Configure API Key (OpenAI)
25
+
26
+ """
27
+
28
+ import os
29
+
30
+ # Hugging Face Spaces will allow access to secrets like this:
31
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
32
+
33
+ # Model defaults (you can change)
34
+ MODEL_NAME = "gpt-4o-mini" # fast & smart
35
+ TEMPERATURE = 0.2
36
+ llm = ChatOpenAI(model=MODEL_NAME, temperature=TEMPERATURE)
37
+
38
+ """# 🧩 Step 2: Project Inputs Helper"""
39
+
40
+ # Light helper to bundle inputs
41
+ def default_inputs(
42
+ goal: str,
43
+ deadline_days: int = 14,
44
+ hours_per_day: int = 2,
45
+ start_date: Optional[str] = None,
46
+ ) -> Dict[str, Any]:
47
+ if not start_date:
48
+ start_date = dt.date.today().isoformat()
49
+ return {
50
+ "goal": goal.strip(),
51
+ "deadline_days": int(deadline_days),
52
+ "hours_per_day": int(hours_per_day),
53
+ "start_date": start_date,
54
+ }
55
+
56
+ """# 🎭 Step 3: Define Agents (Roles + Personalities)
57
+
58
+ """
59
+
60
+ # Agent: Understand the user's goal & constraints
61
+ goal_understanding = Agent(
62
+ role="Goal Understanding Agent",
63
+ backstory=(
64
+ "You are a thoughtful strategist. You clarify objectives, constraints, "
65
+ "and success criteria. You avoid fluff and get to the essence."
66
+ ),
67
+ goal=(
68
+ "Rewrite the user's goal clearly and identify assumptions, scope, "
69
+ "success criteria, hard constraints, and risks."
70
+ ),
71
+ allow_delegation=False,
72
+ llm=llm,
73
+ )
74
+
75
+ # Agent: Break the goal into milestones & tasks
76
+ task_breakdown = Agent(
77
+ role="Task Breakdown Agent",
78
+ backstory=(
79
+ "You are a senior project planner. You decompose work into milestones "
80
+ "and concrete tasks that are testable and deliver value."
81
+ ),
82
+ goal=(
83
+ "Produce milestones and detailed subtasks with crisp deliverables."
84
+ ),
85
+ allow_delegation=False,
86
+ llm=llm,
87
+ )
88
+
89
+ # Agent: Estimate effort & prioritize
90
+ effort_priority = Agent(
91
+ role="Effort & Priority Agent",
92
+ backstory=(
93
+ "You are a pragmatic PM. You estimate realistic time and difficulty, "
94
+ "sequence tasks, and surface dependencies."
95
+ ),
96
+ goal=(
97
+ "Estimate time per task, difficulty (1-5), dependencies, and propose a priority order."
98
+ ),
99
+ allow_delegation=False,
100
+ llm=llm,
101
+ )
102
+
103
+ # Agent: Build a calendar-style plan
104
+ scheduler = Agent(
105
+ role="Schedule Maker Agent",
106
+ backstory=(
107
+ "You create practical schedules given time budgets per day and deadlines."
108
+ ),
109
+ goal=(
110
+ "Map tasks to days from start_date within deadline_days, respecting hours_per_day."
111
+ ),
112
+ allow_delegation=False,
113
+ llm=llm,
114
+ )
115
+
116
+ # Agent: Motivation & execution tips (optional spice)
117
+ motivator = Agent(
118
+ role="Motivator Agent",
119
+ backstory=(
120
+ "You coach users with specific, actionable tips, accountability tactics, and small rewards."
121
+ ),
122
+ goal="Provide short, concrete advice to keep momentum high.",
123
+ allow_delegation=False,
124
+ llm=llm,
125
+ )
126
+
127
+ # Agent: Final synthesis for export
128
+ synthesizer = Agent(
129
+ role="Synthesis Agent",
130
+ backstory=(
131
+ "You are a concise editor. You assemble a clean, professional plan for download and printing."
132
+ ),
133
+ goal="Create final Markdown + JSON outputs for the user.",
134
+ allow_delegation=False,
135
+ llm=llm,
136
+ )
137
+
138
+ """# 🧠 Step 4: Define Tasks (with JSON-first outputs
139
+
140
+ """
141
+
142
+ def make_tasks(inputs: Dict[str, Any]) -> List[Task]:
143
+ common_vars = (
144
+ f"GOAL: {inputs['goal']}\n"
145
+ f"START_DATE: {inputs['start_date']}\n"
146
+ f"DEADLINE_DAYS: {inputs['deadline_days']}\n"
147
+ f"HOURS_PER_DAY: {inputs['hours_per_day']}\n"
148
+ )
149
+
150
+ t1 = Task(
151
+ description=textwrap.dedent(f"""
152
+ Clarify the user's goal.
153
+
154
+ Context:
155
+ {common_vars}
156
+
157
+ Return STRICT JSON with keys:
158
+ {{
159
+ "clarified_goal": "...",
160
+ "assumptions": ["..."],
161
+ "scope": ["in-scope", "..."],
162
+ "success_criteria": ["..."],
163
+ "constraints": ["..."],
164
+ "risks": ["..."]
165
+ }}
166
+ """).strip(),
167
+ agent=goal_understanding,
168
+ expected_output="JSON only.",
169
+ )
170
+
171
+ t2 = Task(
172
+ description=textwrap.dedent(f"""
173
+ Break the clarified goal into milestones and granular tasks.
174
+
175
+ Input is the JSON from the previous step.
176
+ Return STRICT JSON:
177
+ {{
178
+ "milestones": [
179
+ {{
180
+ "name": "...",
181
+ "description": "...",
182
+ "tasks": [
183
+ {{
184
+ "id": "T1",
185
+ "title": "...",
186
+ "definition_of_done": "...",
187
+ "dependencies": [],
188
+ "tags": ["..."]
189
+ }}
190
+ ]
191
+ }}
192
+ ]
193
+ }}
194
+ """).strip(),
195
+ agent=task_breakdown,
196
+ expected_output="JSON only.",
197
+ )
198
+
199
+ t3 = Task(
200
+ description=textwrap.dedent(f"""
201
+ Estimate effort and priority for EACH task id from the previous output.
202
+
203
+ Respect HOURS_PER_DAY={inputs['hours_per_day']} and DEADLINE_DAYS={inputs['deadline_days']}.
204
+ Return STRICT JSON:
205
+ {{
206
+ "estimates": [
207
+ {{
208
+ "id": "T1",
209
+ "hours": 2.5,
210
+ "difficulty_1to5": 3,
211
+ "priority_1to5": 1
212
+ }}
213
+ ]
214
+ }}
215
+ """).strip(),
216
+ agent=effort_priority,
217
+ expected_output="JSON only.",
218
+ )
219
+
220
+ t4 = Task(
221
+ description=textwrap.dedent(f"""
222
+ Create a day-by-day schedule mapping tasks to calendar dates.
223
+
224
+ Use START_DATE and DEADLINE_DAYS. Do not exceed HOURS_PER_DAY per day.
225
+ Return STRICT JSON:
226
+ {{
227
+ "schedule": [
228
+ {{
229
+ "date": "YYYY-MM-DD",
230
+ "allocated_hours": 2,
231
+ "tasks": [{{"id":"T1","title":"...","hours":1.5}}]
232
+ }}
233
+ ],
234
+ "summary": {{
235
+ "total_hours": 0,
236
+ "days_planned": 0,
237
+ "buffer_hours": 0
238
+ }}
239
+ }}
240
+ """).strip(),
241
+ agent=scheduler,
242
+ expected_output="JSON only.",
243
+ )
244
+
245
+ t5 = Task(
246
+ description=textwrap.dedent(f"""
247
+ Provide 5 short motivation or execution tactics tailored to the plan.
248
+
249
+ Return STRICT JSON:
250
+ {{
251
+ "tips": [
252
+ "Keep daily sessions short & focused with a single visible deliverable.",
253
+ "..."
254
+ ]
255
+ }}
256
+ """).strip(),
257
+ agent=motivator,
258
+ expected_output="JSON only.",
259
+ )
260
+
261
+ t6 = Task(
262
+ description=textwrap.dedent(f"""
263
+ Synthesize a final MARKDOWN report AND a JSON bundle.
264
+
265
+ Inputs are the JSONs from all prior tasks. Build:
266
+ 1) Markdown (for printing) with sections:
267
+ - Goal Summary
268
+ - Milestones & Tasks
269
+ - Estimates & Priorities
270
+ - Day-by-Day Plan (table)
271
+ - Tips (bulleted)
272
+ 2) JSON bundle containing all prior JSON merged into one: keys:
273
+ {{
274
+ "goal_context": ...,
275
+ "work_breakdown": ...,
276
+ "estimates": ...,
277
+ "schedule": ...,
278
+ "tips": ...
279
+ }}
280
+
281
+ Return STRICT JSON:
282
+ {{
283
+ "markdown": "....",
284
+ "bundle": {{ /* merged JSON object */ }}
285
+ }}
286
+ """).strip(),
287
+ agent=synthesizer,
288
+ expected_output="JSON only.",
289
+ )
290
+
291
+ return [t1, t2, t3, t4, t5, t6]
292
+
293
+ """# 🏃‍♂️ Step 5: Run the Crew"""
294
+
295
+ def run_planner(goal: str, deadline_days: int = 14, hours_per_day: int = 2, start_date: Optional[str] = None):
296
+ inputs = default_inputs(goal, deadline_days, hours_per_day, start_date)
297
+
298
+ tasks = make_tasks(inputs)
299
+ crew = Crew(
300
+ agents=[goal_understanding, task_breakdown, effort_priority, scheduler, motivator, synthesizer],
301
+ tasks=tasks,
302
+ process=Process.sequential, # run in order
303
+ verbose=True,
304
+ memory=True,
305
+ cache=True,
306
+ )
307
+
308
+ result = crew.kickoff(inputs=inputs)
309
+
310
+ # The final task returns JSON with 'markdown' and 'bundle'
311
+ # crewai often returns text; ensure it's valid JSON:
312
+ def coerce_json(text: str) -> Dict[str, Any]:
313
+ try:
314
+ return json.loads(text)
315
+ except Exception:
316
+ # Try to extract JSON block heuristically
317
+ start = text.find("{")
318
+ end = text.rfind("}")
319
+ if start != -1 and end != -1:
320
+ return json.loads(text[start:end+1])
321
+ raise
322
+
323
+ final = coerce_json(str(result))
324
+ md = final.get("markdown", "# Plan\n\n(No markdown received)")
325
+ bundle = final.get("bundle", {})
326
+
327
+ # Save artifacts
328
+ out_dir = "task_master_outputs"
329
+ os.makedirs(out_dir, exist_ok=True)
330
+ stamp = dt.datetime.now().strftime("%Y%m%d_%H%M%S")
331
+
332
+ md_path = os.path.join(out_dir, f"plan_{stamp}.md")
333
+ json_path = os.path.join(out_dir, f"plan_{stamp}.json")
334
+
335
+ with open(md_path, "w", encoding="utf-8") as f:
336
+ f.write(md)
337
+ with open(json_path, "w", encoding="utf-8") as f:
338
+ json.dump(bundle, f, indent=2, ensure_ascii=False)
339
+
340
+ return {
341
+ "markdown_path": md_path,
342
+ "json_path": json_path,
343
+ "markdown_preview": md[:1500] + ("\n\n...[truncated]..." if len(md) > 1500 else ""),
344
+ }
345
+
346
+ """# Step 6: Minimal Gradio UI"""
347
+
348
+ import gradio as gr
349
+
350
+ def gradio_run(goal, deadline_days, hours_per_day, start_date):
351
+ out = run_planner(goal, int(deadline_days), int(hours_per_day), start_date or None)
352
+ md = ""
353
+ with open(out["markdown_path"], "r", encoding="utf-8") as f:
354
+ md = f.read()
355
+ return md, out["markdown_path"], out["json_path"]
356
+
357
+ with gr.Blocks(title="CrewAI Task Master") as demo_ui:
358
+ gr.Markdown("# 🧠 CrewAI Task Master\nPlan any goal into a day-by-day schedule.")
359
+ with gr.Row():
360
+ goal = gr.Textbox(label="Your Goal", placeholder="e.g., Build an AI portfolio website in 10 days", lines=3)
361
+ with gr.Row():
362
+ deadline = gr.Number(label="Deadline (days)", value=14, precision=0)
363
+ hours = gr.Number(label="Hours per day", value=2, precision=0)
364
+ start = gr.Textbox(label="Start Date (YYYY-MM-DD, optional)", placeholder="Leave blank for today")
365
+ run_btn = gr.Button("Run Agents 🚀")
366
+
367
+ md_out = gr.Markdown(label="Plan (Markdown)")
368
+ md_file = gr.File(label="Download Markdown")
369
+ json_file = gr.File(label="Download JSON")
370
+
371
+ run_btn.click(
372
+ gradio_run,
373
+ inputs=[goal, deadline, hours, start],
374
+ outputs=[md_out, md_file, json_file]
375
+ )
376
+
377
+ demo_ui.launch(share=False)
378
+
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ crewai
2
+ langchain-openai
3
+ gradio
4
+ python-dotenv
5
+ pydantic