forked from eosphoros-ai/DB-GPT
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(agent): Multi agent sdk (eosphoros-ai#976)
Co-authored-by: xtyuns <[email protected]> Co-authored-by: Fangyin Cheng <[email protected]> Co-authored-by: csunny <[email protected]> Co-authored-by: qidanrui <[email protected]>
- Loading branch information
Showing
79 changed files
with
6,356 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ __pycache__/ | |
*.so | ||
|
||
message/ | ||
|
||
dbgpt/util/extensions/ | ||
.env* | ||
.vscode | ||
.idea | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1 @@ | ||
from .db.my_plugin_db import MyPluginEntity, MyPluginDao | ||
from .db.plugin_hub_db import PluginHubEntity, PluginHubDao | ||
|
||
from .commands.command import execute_command, get_command | ||
from .commands.generator import PluginPromptGenerator | ||
from .commands.disply_type.show_chart_gen import static_message_img_path | ||
|
||
from .common.schema import Status, PluginStorageType | ||
|
||
from .commands.command_mange import ApiCall | ||
from .commands.command import execute_command | ||
from .common.schema import PluginStorageType |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
from __future__ import annotations | ||
|
||
import dataclasses | ||
from collections import defaultdict | ||
from dataclasses import asdict, dataclass, fields | ||
from typing import Any, Dict, List, Optional, Union | ||
|
||
from ..memory.gpts_memory import GptsMemory | ||
from dbgpt.core import LLMClient | ||
from dbgpt.core.interface.llm import ModelMetadata | ||
|
||
|
||
class Agent: | ||
""" | ||
An interface for AI agent. | ||
An agent can communicate with other agents and perform actions. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
name: str, | ||
memory: GptsMemory, | ||
describe: str, | ||
): | ||
""" | ||
Args: | ||
name (str): name of the agent. | ||
""" | ||
self._name = name | ||
self._describe = describe | ||
|
||
# the agent's collective memory | ||
self._memory = memory | ||
|
||
@property | ||
def name(self): | ||
"""Get the name of the agent.""" | ||
return self._name | ||
|
||
@property | ||
def memory(self): | ||
return self._memory | ||
|
||
@property | ||
def describe(self): | ||
"""Get the name of the agent.""" | ||
return self._describe | ||
|
||
async def a_send( | ||
self, | ||
message: Union[Dict, str], | ||
recipient: Agent, | ||
reviewer: Agent, | ||
request_reply: Optional[bool] = True, | ||
is_recovery: Optional[bool] = False, | ||
): | ||
"""(Abstract async method) Send a message to another agent.""" | ||
|
||
async def a_receive( | ||
self, | ||
message: Optional[Dict], | ||
sender: Agent, | ||
reviewer: Agent, | ||
request_reply: Optional[bool] = None, | ||
silent: Optional[bool] = False, | ||
is_recovery: Optional[bool] = False, | ||
): | ||
"""(Abstract async method) Receive a message from another agent.""" | ||
|
||
async def a_review(self, message: Union[Dict, str], censored: Agent): | ||
""" | ||
Args: | ||
message: | ||
censored: | ||
Returns: | ||
""" | ||
|
||
def reset(self): | ||
"""(Abstract method) Reset the agent.""" | ||
|
||
async def a_generate_reply( | ||
self, | ||
message: Optional[Dict], | ||
sender: Agent, | ||
reviewer: Agent, | ||
silent: Optional[bool] = False, | ||
**kwargs, | ||
) -> Union[str, Dict, None]: | ||
"""(Abstract async method) Generate a reply based on the received messages. | ||
Args: | ||
messages (Optional[Dict]): a dict of messages received from other agents. | ||
sender: sender of an Agent instance. | ||
Returns: | ||
str or dict or None: the generated reply. If None, no reply is generated. | ||
""" | ||
|
||
async def a_reasoning_reply( | ||
self, messages: Optional[List[Dict]] | ||
) -> Union[str, Dict, None]: | ||
""" | ||
Based on the requirements of the current agent, reason about the current task goal through LLM | ||
Args: | ||
message: | ||
Returns: | ||
str or dict or None: the generated reply. If None, no reply is generated. | ||
""" | ||
|
||
async def a_action_reply( | ||
self, | ||
messages: Optional[str], | ||
sender: Agent, | ||
**kwargs, | ||
) -> Union[str, Dict, None]: | ||
""" | ||
Parse the inference results for the current target and execute the inference results using the current agent's executor | ||
Args: | ||
messages (list[dict]): a list of messages received. | ||
sender: sender of an Agent instance. | ||
**kwargs: | ||
Returns: | ||
str or dict or None: the agent action reply. If None, no reply is generated. | ||
""" | ||
|
||
async def a_verify_reply( | ||
self, | ||
message: Optional[Dict], | ||
sender: Agent, | ||
reviewer: Agent, | ||
**kwargs, | ||
) -> Union[str, Dict, None]: | ||
""" | ||
Verify whether the current execution results meet the target expectations | ||
Args: | ||
messages: | ||
sender: | ||
**kwargs: | ||
Returns: | ||
""" | ||
|
||
|
||
@dataclass | ||
class AgentResource: | ||
type: str | ||
name: str | ||
introduce: str | ||
|
||
@staticmethod | ||
def from_dict(d: Dict[str, Any]) -> Optional[AgentResource]: | ||
if d is None: | ||
return None | ||
return AgentResource( | ||
type=d.get("type"), | ||
name=d.get("name"), | ||
introduce=d.get("introduce"), | ||
) | ||
|
||
def to_dict(self) -> Dict[str, Any]: | ||
return dataclasses.asdict(self) | ||
|
||
|
||
@dataclass | ||
class AgentContext: | ||
conv_id: str | ||
llm_provider: LLMClient | ||
|
||
gpts_name: Optional[str] = None | ||
resource_db: Optional[AgentResource] = None | ||
resource_knowledge: Optional[AgentResource] = None | ||
resource_internet: Optional[AgentResource] = None | ||
llm_models: Optional[List[Union[ModelMetadata, str]]] = None | ||
model_priority: Optional[dict] = None | ||
agents: Optional[List[str]] = None | ||
|
||
max_chat_round: Optional[int] = 100 | ||
max_retry_round: Optional[int] = 10 | ||
max_new_tokens: Optional[int] = 1024 | ||
temperature: Optional[float] = 0.5 | ||
allow_format_str_template: Optional[bool] = False | ||
|
||
def to_dict(self) -> Dict[str, Any]: | ||
return dataclasses.asdict(self) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from collections import defaultdict | ||
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Type, Union | ||
|
||
from .agent import Agent | ||
from .expand.code_assistant_agent import CodeAssistantAgent | ||
from .expand.dashboard_assistant_agent import DashboardAssistantAgent | ||
from .expand.data_scientist_agent import DataScientistAgent | ||
from .expand.sql_assistant_agent import SQLAssistantAgent | ||
|
||
|
||
def get_all_subclasses(cls): | ||
all_subclasses = [] | ||
direct_subclasses = cls.__subclasses__() | ||
all_subclasses.extend(direct_subclasses) | ||
|
||
for subclass in direct_subclasses: | ||
all_subclasses.extend(get_all_subclasses(subclass)) | ||
return all_subclasses | ||
|
||
|
||
class AgentsMange: | ||
def __init__(self): | ||
self._agents = defaultdict() | ||
|
||
def register_agent(self, cls): | ||
self._agents[cls.NAME] = cls | ||
|
||
def get_by_name(self, name: str) -> Optional[Type[Agent]]: | ||
if name not in self._agents: | ||
raise ValueError(f"Agent:{name} not register!") | ||
return self._agents[name] | ||
|
||
def get_describe_by_name(self, name: str) -> Optional[Type[Agent]]: | ||
return self._agents[name].DEFAULT_DESCRIBE | ||
|
||
def all_agents(self): | ||
result = {} | ||
for name, cls in self._agents.items(): | ||
result[name] = cls.DEFAULT_DESCRIBE | ||
return result | ||
|
||
|
||
agent_mange = AgentsMange() | ||
|
||
agent_mange.register_agent(CodeAssistantAgent) | ||
agent_mange.register_agent(DashboardAssistantAgent) | ||
agent_mange.register_agent(DataScientistAgent) | ||
agent_mange.register_agent(SQLAssistantAgent) |
Oops, something went wrong.