|
0981a08…
|
noreply
|
1 |
"""Skill interface for the PlanOpticon planning agent.""" |
|
0981a08…
|
noreply
|
2 |
|
|
0981a08…
|
noreply
|
3 |
from abc import ABC, abstractmethod |
|
0981a08…
|
noreply
|
4 |
from dataclasses import dataclass, field |
|
0981a08…
|
noreply
|
5 |
from typing import Any, Dict, List, Optional |
|
0981a08…
|
noreply
|
6 |
|
|
0981a08…
|
noreply
|
7 |
|
|
0981a08…
|
noreply
|
8 |
@dataclass |
|
0981a08…
|
noreply
|
9 |
class Artifact: |
|
0981a08…
|
noreply
|
10 |
"""Output from a skill execution.""" |
|
0981a08…
|
noreply
|
11 |
|
|
0981a08…
|
noreply
|
12 |
name: str |
|
0981a08…
|
noreply
|
13 |
content: str # The generated content (markdown, json, etc.) |
|
0981a08…
|
noreply
|
14 |
artifact_type: str # "project_plan", "prd", "roadmap", "task_list", "document", "issues" |
|
0981a08…
|
noreply
|
15 |
format: str = "markdown" # "markdown", "json", "mermaid" |
|
0981a08…
|
noreply
|
16 |
metadata: Dict[str, Any] = field(default_factory=dict) |
|
0981a08…
|
noreply
|
17 |
|
|
0981a08…
|
noreply
|
18 |
|
|
0981a08…
|
noreply
|
19 |
@dataclass |
|
0981a08…
|
noreply
|
20 |
class AgentContext: |
|
0981a08…
|
noreply
|
21 |
"""Shared context for agent skills.""" |
|
0981a08…
|
noreply
|
22 |
|
|
0981a08…
|
noreply
|
23 |
knowledge_graph: Any = None # KnowledgeGraph instance |
|
0981a08…
|
noreply
|
24 |
query_engine: Any = None # GraphQueryEngine instance |
|
0981a08…
|
noreply
|
25 |
provider_manager: Any = None # ProviderManager instance |
|
0981a08…
|
noreply
|
26 |
planning_entities: List[Any] = field(default_factory=list) |
|
0981a08…
|
noreply
|
27 |
user_requirements: Dict[str, Any] = field(default_factory=dict) |
|
0981a08…
|
noreply
|
28 |
conversation_history: List[Dict[str, str]] = field(default_factory=list) |
|
0981a08…
|
noreply
|
29 |
artifacts: List[Artifact] = field(default_factory=list) |
|
0981a08…
|
noreply
|
30 |
config: Dict[str, Any] = field(default_factory=dict) |
|
0981a08…
|
noreply
|
31 |
|
|
0981a08…
|
noreply
|
32 |
|
|
0981a08…
|
noreply
|
33 |
class Skill(ABC): |
|
0981a08…
|
noreply
|
34 |
"""Base class for agent skills.""" |
|
0981a08…
|
noreply
|
35 |
|
|
0981a08…
|
noreply
|
36 |
name: str = "" |
|
0981a08…
|
noreply
|
37 |
description: str = "" |
|
0981a08…
|
noreply
|
38 |
|
|
0981a08…
|
noreply
|
39 |
@abstractmethod |
|
0981a08…
|
noreply
|
40 |
def execute(self, context: AgentContext, **kwargs) -> Artifact: |
|
0981a08…
|
noreply
|
41 |
"""Execute this skill and return an artifact.""" |
|
0981a08…
|
noreply
|
42 |
... |
|
0981a08…
|
noreply
|
43 |
|
|
0981a08…
|
noreply
|
44 |
def can_execute(self, context: AgentContext) -> bool: |
|
0981a08…
|
noreply
|
45 |
"""Check if this skill can execute given the current context.""" |
|
0981a08…
|
noreply
|
46 |
return context.knowledge_graph is not None and context.provider_manager is not None |
|
0981a08…
|
noreply
|
47 |
|
|
0981a08…
|
noreply
|
48 |
|
|
0981a08…
|
noreply
|
49 |
# Skill registry |
|
0981a08…
|
noreply
|
50 |
_skills: Dict[str, "Skill"] = {} |
|
0981a08…
|
noreply
|
51 |
|
|
0981a08…
|
noreply
|
52 |
|
|
0981a08…
|
noreply
|
53 |
def register_skill(skill: "Skill") -> None: |
|
0981a08…
|
noreply
|
54 |
"""Register a skill instance in the global registry.""" |
|
0981a08…
|
noreply
|
55 |
_skills[skill.name] = skill |
|
0981a08…
|
noreply
|
56 |
|
|
0981a08…
|
noreply
|
57 |
|
|
0981a08…
|
noreply
|
58 |
def get_skill(name: str) -> Optional["Skill"]: |
|
0981a08…
|
noreply
|
59 |
"""Look up a skill by name.""" |
|
0981a08…
|
noreply
|
60 |
return _skills.get(name) |
|
0981a08…
|
noreply
|
61 |
|
|
0981a08…
|
noreply
|
62 |
|
|
0981a08…
|
noreply
|
63 |
def list_skills() -> List["Skill"]: |
|
0981a08…
|
noreply
|
64 |
"""Return all registered skills.""" |
|
0981a08…
|
noreply
|
65 |
return list(_skills.values()) |