From 7e9dff545d1cd6485975539addea1ecd6ca3067c Mon Sep 17 00:00:00 2001 From: femto Date: Mon, 5 Aug 2024 17:21:23 +0800 Subject: [PATCH] rm sk agent --- examples/sk_agent.py | 82 ----------------- metagpt/actions/research.py | 1 - metagpt/roles/sk_agent.py | 87 ------------------- metagpt/tools/search_engine.py | 22 ----- .../serialize_deserialize/test_sk_agent.py | 17 ---- 5 files changed, 209 deletions(-) delete mode 100644 examples/sk_agent.py delete mode 100644 metagpt/roles/sk_agent.py delete mode 100644 tests/metagpt/serialize_deserialize/test_sk_agent.py diff --git a/examples/sk_agent.py b/examples/sk_agent.py deleted file mode 100644 index 647ea4380..000000000 --- a/examples/sk_agent.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -@Time : 2023/9/13 12:36 -@Author : femto Zheng -@File : sk_agent.py -""" -import asyncio - -from semantic_kernel.core_skills import FileIOSkill, MathSkill, TextSkill, TimeSkill -from semantic_kernel.planning import SequentialPlanner - -# from semantic_kernel.planning import SequentialPlanner -from semantic_kernel.planning.action_planner.action_planner import ActionPlanner - -from metagpt.actions import UserRequirement -from metagpt.const import SKILL_DIRECTORY -from metagpt.roles.sk_agent import SkAgent -from metagpt.schema import Message -from metagpt.tools.search_engine import SkSearchEngine - - -async def main(): - # await basic_planner_example() - # await action_planner_example() - - # await sequential_planner_example() - await basic_planner_web_search_example() - - -async def basic_planner_example(): - task = """ - Tomorrow is Valentine's day. I need to come up with a few date ideas. She speaks French so write it in French. - Convert the text to uppercase""" - role = SkAgent() - - # let's give the agent some skills - role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "SummarizeSkill") - role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "WriterSkill") - role.import_skill(TextSkill(), "TextSkill") - # using BasicPlanner - await role.run(Message(content=task, cause_by=UserRequirement)) - - -async def sequential_planner_example(): - task = """ - Tomorrow is Valentine's day. I need to come up with a few date ideas. She speaks French so write it in French. - Convert the text to uppercase""" - role = SkAgent(planner_cls=SequentialPlanner) - - # let's give the agent some skills - role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "SummarizeSkill") - role.import_semantic_skill_from_directory(SKILL_DIRECTORY, "WriterSkill") - role.import_skill(TextSkill(), "TextSkill") - # using BasicPlanner - await role.run(Message(content=task, cause_by=UserRequirement)) - - -async def basic_planner_web_search_example(): - task = """ - Question: Who made the 1989 comic book, the film version of which Jon Raymond Polito appeared in?""" - role = SkAgent() - - role.import_skill(SkSearchEngine(), "WebSearchSkill") - # role.import_semantic_skill_from_directory(skills_directory, "QASkill") - - await role.run(Message(content=task, cause_by=UserRequirement)) - - -async def action_planner_example(): - role = SkAgent(planner_cls=ActionPlanner) - # let's give the agent 4 skills - role.import_skill(MathSkill(), "math") - role.import_skill(FileIOSkill(), "fileIO") - role.import_skill(TimeSkill(), "time") - role.import_skill(TextSkill(), "text") - task = "What is the sum of 110 and 990?" - await role.run(Message(content=task, cause_by=UserRequirement)) # it will choose mathskill.Add - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/metagpt/actions/research.py b/metagpt/actions/research.py index 5086f10cf..bad8f139c 100644 --- a/metagpt/actions/research.py +++ b/metagpt/actions/research.py @@ -10,7 +10,6 @@ from pydantic import TypeAdapter, model_validator from metagpt.actions import Action from metagpt.config2 import config from metagpt.logs import logger -from metagpt.tools.search_engine import SearchEngine from metagpt.tools.web_browser_engine import WebBrowserEngine from metagpt.utils.common import OutputParser from metagpt.utils.text import generate_prompt_chunk, reduce_message_length diff --git a/metagpt/roles/sk_agent.py b/metagpt/roles/sk_agent.py deleted file mode 100644 index 71df55fcc..000000000 --- a/metagpt/roles/sk_agent.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -@Time : 2023/9/13 12:23 -@Author : femto Zheng -@File : sk_agent.py -@Modified By: mashenquan, 2023-11-1. In accordance with Chapter 2.2.1 and 2.2.2 of RFC 116, utilize the new message - distribution feature for message filtering. -""" -from typing import Any, Callable, Union - -from pydantic import Field -from semantic_kernel import Kernel -from semantic_kernel.planning import SequentialPlanner -from semantic_kernel.planning.action_planner.action_planner import ActionPlanner -from semantic_kernel.planning.basic_planner import BasicPlanner, Plan - -from metagpt.actions import UserRequirement -from metagpt.actions.execute_task import ExecuteTask -from metagpt.logs import logger -from metagpt.roles import Role -from metagpt.schema import Message -from metagpt.utils.make_sk_kernel import make_sk_kernel - - -class SkAgent(Role): - """ - Represents an SkAgent implemented using semantic kernel - - Attributes: - name (str): Name of the SkAgent. - profile (str): Role profile, default is 'sk_agent'. - goal (str): Goal of the SkAgent. - constraints (str): Constraints for the SkAgent. - """ - - name: str = "Sunshine" - profile: str = "sk_agent" - goal: str = "Execute task based on passed in task description" - constraints: str = "" - - plan: Plan = Field(default=None, exclude=True) - planner_cls: Any = None - planner: Union[BasicPlanner, SequentialPlanner, ActionPlanner] = None - kernel: Kernel = Field(default_factory=Kernel) - import_semantic_skill_from_directory: Callable = Field(default=None, exclude=True) - import_skill: Callable = Field(default=None, exclude=True) - - def __init__(self, **data: Any) -> None: - """Initializes the Engineer role with given attributes.""" - super().__init__(**data) - self.set_actions([ExecuteTask()]) - self._watch([UserRequirement]) - self.kernel = make_sk_kernel() - - # how funny the interface is inconsistent - if self.planner_cls == BasicPlanner or self.planner_cls is None: - self.planner = BasicPlanner() - elif self.planner_cls in [SequentialPlanner, ActionPlanner]: - self.planner = self.planner_cls(self.kernel) - else: - raise Exception(f"Unsupported planner of type {self.planner_cls}") - - self.import_semantic_skill_from_directory = self.kernel.import_semantic_skill_from_directory - self.import_skill = self.kernel.import_skill - - async def _think(self) -> None: - self._set_state(0) - # how funny the interface is inconsistent - if isinstance(self.planner, BasicPlanner): - self.plan = await self.planner.create_plan_async(self.rc.important_memory[-1].content, self.kernel) - logger.info(self.plan.generated_plan) - elif any(isinstance(self.planner, cls) for cls in [SequentialPlanner, ActionPlanner]): - self.plan = await self.planner.create_plan_async(self.rc.important_memory[-1].content) - - async def _act(self) -> Message: - # how funny the interface is inconsistent - result = None - if isinstance(self.planner, BasicPlanner): - result = await self.planner.execute_plan_async(self.plan, self.kernel) - elif any(isinstance(self.planner, cls) for cls in [SequentialPlanner, ActionPlanner]): - result = (await self.plan.invoke_async()).result - logger.info(result) - - msg = Message(content=result, role=self.profile, cause_by=self.rc.todo) - self.rc.memory.add(msg) - return msg diff --git a/metagpt/tools/search_engine.py b/metagpt/tools/search_engine.py index 767f4aaba..1372a8c7a 100644 --- a/metagpt/tools/search_engine.py +++ b/metagpt/tools/search_engine.py @@ -9,34 +9,12 @@ import importlib from typing import Callable, Coroutine, Literal, Optional, Union, overload from pydantic import BaseModel, ConfigDict, model_validator -from semantic_kernel.skill_definition import sk_function from metagpt.configs.search_config import SearchConfig from metagpt.logs import logger from metagpt.tools import SearchEngineType -class SkSearchEngine: - """A search engine class for executing searches. - - Attributes: - search_engine: The search engine instance used for executing searches. - """ - - def __init__(self, **kwargs): - self.search_engine = SearchEngine(**kwargs) - - @sk_function( - description="searches results from Google. Useful when you need to find short " - "and succinct answers about a specific topic. Input should be a search query.", - name="searchAsync", - input_description="search", - ) - async def run(self, query: str) -> str: - result = await self.search_engine.run(query) - return result - - class SearchEngine(BaseModel): """A model for configuring and executing searches with different search engines. diff --git a/tests/metagpt/serialize_deserialize/test_sk_agent.py b/tests/metagpt/serialize_deserialize/test_sk_agent.py deleted file mode 100644 index 97c0ade99..000000000 --- a/tests/metagpt/serialize_deserialize/test_sk_agent.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- -# @Desc : -import pytest - -from metagpt.roles.sk_agent import SkAgent - - -@pytest.mark.asyncio -async def test_sk_agent_serdeser(): - role = SkAgent() - ser_role_dict = role.model_dump(exclude={"import_semantic_skill_from_directory", "import_skill"}) - assert "name" in ser_role_dict - assert "planner" in ser_role_dict - - new_role = SkAgent(**ser_role_dict) - assert new_role.name == "Sunshine" - assert len(new_role.actions) == 1