Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update openssa.l2.planning.abstract interfaces #162

Merged
merged 14 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
62dba0b
update openssa.l2.agent.abstract.AbstractAgent.solve(...)
TheVinhLuong102 Apr 23, 2024
3a71c49
Merge branch 'main' of https://GitHub.com/Aitomatic/OpenSSA into agen…
TheVinhLuong102 Apr 23, 2024
d2a02e0
add comments to openssa.l2.task.abstract.AbstractTask.decompose(...)
TheVinhLuong102 Apr 23, 2024
47b3a17
Merge branch 'main' of https://GitHub.com/Aitomatic/OpenSSA into task…
TheVinhLuong102 Apr 23, 2024
100ef49
Merge branch 'planning/hierarchical' of https://GitHub.com/Aitomatic/…
TheVinhLuong102 Apr 23, 2024
36b8152
Revert "add comments to openssa.l2.task.abstract.AbstractTask.decompo…
TheVinhLuong102 Apr 24, 2024
e78799c
Revert "fix minor typo in openssa.l2.task.abstract.AbstractTask.decom…
TheVinhLuong102 Apr 24, 2024
8dd1d8d
Revert "update openssa.l2.task.abstract.AbstractTask.decompose(...)"
TheVinhLuong102 Apr 24, 2024
6a39611
enhance assertion/type-checking in openssa.l2.task.abstract.AbstractT…
TheVinhLuong102 Apr 24, 2024
3429ce1
Merge branch 'planning/hierarchical' of https://GitHub.com/Aitomatic/…
TheVinhLuong102 Apr 24, 2024
c8d723d
update openssa.l2.agent.abstract.AbstractAgent.solve_dynamically(...)
TheVinhLuong102 Apr 24, 2024
3f1ce02
update openssa.l2.agent.abstract.AbstractAgent.solve_dynamically(...)
TheVinhLuong102 Apr 24, 2024
19bb94e
update openssa.l2.planning.abstract.AbstractPlan.execute(...) method …
TheVinhLuong102 Apr 24, 2024
ff9842e
change openssa.l2.planning.abstract.planner.AbstractPlanner.max_depth…
TheVinhLuong102 Apr 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions openssa/l2/agent/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from pprint import pprint
from typing import TYPE_CHECKING

from tqdm import tqdm

from openssa.l2.reasoning.base import BaseReasoner
from openssa.l2.task.status import TaskStatus
from openssa.l2.task.task import Task
Expand Down Expand Up @@ -82,13 +84,23 @@ def solve(self, problem: str, plan: APlan | None = None, dynamic: bool = True) -

return result

def solve_dynamically(self, problem: str) -> str:
def solve_dynamically(self, problem: str, planner: APlanner = None) -> str:
"""Solve task dynamically.

When first-pass result from Reasoner is unsatisfactory, decompose problem and recursively solve decomposed plan.
"""
self.reasoner.reason(task := Task(ask=problem, resources=self.resources))

if task.status == TaskStatus.NEEDING_DECOMPOSITION:
task.dynamic_decomposer: APlanner = self.planner.one_level_deep()
if (task.status == TaskStatus.NEEDING_DECOMPOSITION) and (planner := planner or self.planner).max_depth:
sub_planner: APlanner = planner.one_fewer_level_deep()

for sub_plan in tqdm(plan_1_level_deep := (planner.one_level_deep()
.plan(problem=problem, resources=self.resources)).sub_plans):
sub_task: ATask = sub_plan.task
sub_task.result: str = self.solve_dynamically(problem=sub_task.ask, planner=sub_planner)
sub_task.status: TaskStatus = TaskStatus.DONE

for sub_plan in (plan_1_level_deep := task.decompose()).sub_plans:
sub_plan.task.dynamic_decomposer: APlanner = self.planner.one_fewer_level_deep()
task.result: str = plan_1_level_deep.execute(reasoner=self.reasoner)
task.status: TaskStatus = TaskStatus.DONE

plan_1_level_deep.execute(reasoner=self.reasoner)
return task.result
5 changes: 4 additions & 1 deletion openssa/l2/planning/abstract/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
from openssa.l2.task.abstract import ATask


type AskAnsPair = tuple[str, str]


@dataclass
class AbstractPlan(ABC):
"""Abstract plan."""
Expand All @@ -29,7 +32,7 @@ class AbstractPlan(ABC):
kw_only=True)

@abstractmethod
def execute(self, reasoner: AReasoner = BaseReasoner()) -> str:
def execute(self, reasoner: AReasoner = BaseReasoner(), other_results: list[AskAnsPair] | None = None) -> str:
"""Execute and return result, using specified reasoner to reason through involved tasks."""


Expand Down
2 changes: 1 addition & 1 deletion openssa/l2/planning/abstract/planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AbstractPlanner(ABC):

lm: AnLLM = field(default_factory=OpenAILLM.get_gpt_4_1106_preview)

max_depth: int = 3
max_depth: int = 2
max_subtasks_per_decomp: int = 3

@abstractmethod
Expand Down
5 changes: 1 addition & 4 deletions openssa/l2/planning/hierarchical/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from loguru import logger
from tqdm import tqdm

from openssa.l2.planning.abstract.plan import AbstractPlan
from openssa.l2.planning.abstract.plan import AbstractPlan, AskAnsPair
from openssa.l2.planning.abstract.planner import AbstractPlanner
from openssa.l2.reasoning.base import BaseReasoner
from openssa.l2.task.status import TaskStatus
Expand All @@ -30,9 +30,6 @@ class HTPDict(TypedDict, total=False):
sub_plans: NotRequired[list[HTPDict]]


type AskAnsPair = tuple[str, str]


@dataclass
class HTP(AbstractPlan):
"""Hierarchical task plan (HTP)."""
Expand Down
10 changes: 3 additions & 7 deletions openssa/l2/task/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,10 @@ def from_dict_or_str(cls, dict_or_str: TaskDict | str, /) -> Self:

def decompose(self) -> APlan:
"""Decompose task into modular plan."""
assert isinstance(self.dynamic_decomposer, AbstractPlanner), '*** Dynamic Decomposer must be Planner instance ***'
assert isinstance(self.dynamic_decomposer.max_depth), '*** Dynamic Decomposer must have positive Max Depth ***'
assert isinstance(self.dynamic_decomposer, AbstractPlanner), \
TypeError('*** Dynamic Decomposer must be Planner instance ***')

for sub_plan in (plan := self.dynamic_decomposer.plan(problem=self.ask, resources=self.resources)):
(sub_task := sub_plan.task).resources: set[AResource] = self.resources
sub_task.dynamic_decomposer: APlanner = self.dynamic_decomposer.one_fewer_level_deep()

return plan
return self.dynamic_decomposer.plan(problem=self.ask, resources=self.resources)


ATask: TypeVar = TypeVar('ATask', bound=AbstractTask, covariant=False, contravariant=False)