PlanOpticon

planopticon / video_processor / agent / skills / task_breakdown.py
Blame History Raw 77 lines
1
"""Skill: Break down goals into tasks with dependencies."""
2
3
from video_processor.agent.skills.base import (
4
AgentContext,
5
Artifact,
6
Skill,
7
register_skill,
8
)
9
from video_processor.utils.json_parsing import parse_json_from_response
10
11
12
class TaskBreakdownSkill(Skill):
13
name = "task_breakdown"
14
description = "Break down goals into tasks with dependencies"
15
16
def execute(self, context: AgentContext, **kwargs) -> Artifact:
17
stats = context.query_engine.stats()
18
entities = context.query_engine.entities()
19
relationships = context.query_engine.relationships()
20
21
task_types = {"goal", "feature", "milestone"}
22
relevant = [
23
e for e in context.planning_entities if getattr(e, "type", "").lower() in task_types
24
]
25
26
parts = [
27
"You are a project manager. Using the following knowledge "
28
"graph context, decompose goals and features into tasks.",
29
"",
30
"## Knowledge Graph Overview",
31
stats.to_text(),
32
"",
33
"## Entities",
34
entities.to_text(),
35
"",
36
"## Relationships",
37
relationships.to_text(),
38
"",
39
"## Goals, Features & Milestones",
40
]
41
for e in relevant:
42
parts.append(f"- [{getattr(e, 'type', 'unknown')}] {e}")
43
44
if not relevant:
45
parts.append("(No pre-filtered entities; derive tasks from the full context above.)")
46
47
parts.append(
48
"\nReturn a JSON array of task objects with:\n"
49
'- "id": string (e.g. "T1", "T2")\n'
50
'- "title": string\n'
51
'- "description": string\n'
52
'- "depends_on": list of task id strings\n'
53
'- "priority": "high" | "medium" | "low"\n'
54
'- "estimate": string (e.g. "2d", "1w")\n'
55
'- "assignee_role": string\n\n'
56
"Return ONLY the JSON."
57
)
58
59
prompt = "\n".join(parts)
60
response = context.provider_manager.chat(messages=[{"role": "user", "content": prompt}])
61
parsed = parse_json_from_response(response)
62
63
import json
64
65
content = json.dumps(parsed, indent=2) if isinstance(parsed, list) else response
66
67
return Artifact(
68
name="Task Breakdown",
69
content=content,
70
artifact_type="task_list",
71
format="json",
72
metadata={"tasks": parsed if isinstance(parsed, list) else []},
73
)
74
75
76
register_skill(TaskBreakdownSkill())
77

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button