mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-15 14:11:14 +00:00
refactor(agent): Agent modular refactoring (#1487)
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
"""Indicator Assistant Agent."""
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
from ..actions.indicator_action import IndicatorAction
|
||||
import logging
|
||||
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import DynConfig, ProfileConfig
|
||||
from .actions.indicator_action import IndicatorAction
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -11,29 +12,48 @@ logger = logging.getLogger(__name__)
|
||||
class IndicatorAssistantAgent(ConversableAgent):
|
||||
"""Indicator Assistant Agent."""
|
||||
|
||||
name = "Indicator"
|
||||
profile: str = "Indicator"
|
||||
goal: str = (
|
||||
"Summarize answer summaries based on user questions from provided "
|
||||
"resource information or from historical conversation memories."
|
||||
)
|
||||
|
||||
constraints: List[str] = [
|
||||
"Prioritize the summary of answers to user questions from the improved resource"
|
||||
" text. If no relevant information is found, summarize it from the historical"
|
||||
" dialogue memory given. It is forbidden to make up your own.",
|
||||
"You need to first detect user's question that you need to answer with your "
|
||||
"summarization.",
|
||||
"Extract the provided text content used for summarization.",
|
||||
"Then you need to summarize the extracted text content.",
|
||||
"Output the content of summarization ONLY related to user's question. The "
|
||||
"output language must be the same to user's question language.",
|
||||
"If you think the provided text content is not related to user questions at "
|
||||
"all, ONLY output 'Did not find the information you want.'!!.",
|
||||
]
|
||||
desc: str = (
|
||||
"You can summarize provided text content according to user's questions "
|
||||
"and output the summarization."
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name=DynConfig(
|
||||
"Indicator",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_indicator_assistant_agent_profile_name",
|
||||
),
|
||||
role=DynConfig(
|
||||
"Indicator",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_indicator_assistant_agent_profile_role",
|
||||
),
|
||||
goal=DynConfig(
|
||||
"Summarize answer summaries based on user questions from provided "
|
||||
"resource information or from historical conversation memories.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_indicator_assistant_agent_profile_goal",
|
||||
),
|
||||
constraints=DynConfig(
|
||||
[
|
||||
"Prioritize the summary of answers to user questions from the "
|
||||
"improved resource text. If no relevant information is found, "
|
||||
"summarize it from the historical dialogue memory given. It is "
|
||||
"forbidden to make up your own.",
|
||||
"You need to first detect user's question that you need to answer "
|
||||
"with your summarization.",
|
||||
"Extract the provided text content used for summarization.",
|
||||
"Then you need to summarize the extracted text content.",
|
||||
"Output the content of summarization ONLY related to user's question. "
|
||||
"The output language must be the same to user's question language.",
|
||||
"If you think the provided text content is not related to user "
|
||||
"questions at all, ONLY output 'Did not find the information you "
|
||||
"want.'!!.",
|
||||
],
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_indicator_assistant_agent_profile_constraints",
|
||||
),
|
||||
desc=DynConfig(
|
||||
"You can summarize provided text content according to user's questions "
|
||||
"and output the summarization.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_indicator_assistant_agent_profile_desc",
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
1
dbgpt/agent/expand/actions/__init__.py
Normal file
1
dbgpt/agent/expand/actions/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Actions of expand Agents."""
|
106
dbgpt/agent/expand/actions/chart_action.py
Normal file
106
dbgpt/agent/expand/actions/chart_action.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""Chart Action for SQL execution and rendering."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from dbgpt._private.pydantic import BaseModel, Field, model_to_json
|
||||
from dbgpt.vis.tags.vis_chart import Vis, VisChart
|
||||
|
||||
from ...core.action.base import Action, ActionOutput
|
||||
from ...resource.resource_api import AgentResource, ResourceType
|
||||
from ...resource.resource_db_api import ResourceDbClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SqlInput(BaseModel):
|
||||
"""SQL input model."""
|
||||
|
||||
display_type: str = Field(
|
||||
...,
|
||||
description="The chart rendering method selected for SQL. If you don’t know "
|
||||
"what to output, just output 'response_table' uniformly.",
|
||||
)
|
||||
sql: str = Field(
|
||||
..., description="Executable sql generated for the current target/problem"
|
||||
)
|
||||
thought: str = Field(..., description="Summary of thoughts to the user")
|
||||
|
||||
|
||||
class ChartAction(Action[SqlInput]):
|
||||
"""Chart action class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create a chart action."""
|
||||
super().__init__()
|
||||
self._render_protocol = VisChart()
|
||||
|
||||
@property
|
||||
def resource_need(self) -> Optional[ResourceType]:
|
||||
"""Return the resource type needed for the action."""
|
||||
return ResourceType.DB
|
||||
|
||||
@property
|
||||
def render_protocol(self) -> Optional[Vis]:
|
||||
"""Return the render protocol."""
|
||||
return self._render_protocol
|
||||
|
||||
@property
|
||||
def out_model_type(self):
|
||||
"""Return the output model type."""
|
||||
return SqlInput
|
||||
|
||||
async def run(
|
||||
self,
|
||||
ai_message: str,
|
||||
resource: Optional[AgentResource] = None,
|
||||
rely_action_out: Optional[ActionOutput] = None,
|
||||
need_vis_render: bool = True,
|
||||
**kwargs,
|
||||
) -> ActionOutput:
|
||||
"""Perform the action."""
|
||||
try:
|
||||
param: SqlInput = self._input_convert(ai_message, SqlInput)
|
||||
except Exception as e:
|
||||
logger.exception(f"{str(e)}! \n {ai_message}")
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="The requested correctly structured answer could not be found.",
|
||||
)
|
||||
try:
|
||||
if not self.resource_loader:
|
||||
raise ValueError("ResourceLoader is not initialized!")
|
||||
resource_db_client: Optional[
|
||||
ResourceDbClient
|
||||
] = self.resource_loader.get_resource_api(
|
||||
self.resource_need, ResourceDbClient
|
||||
)
|
||||
if not resource_db_client:
|
||||
raise ValueError(
|
||||
"There is no implementation class bound to database resource "
|
||||
"execution!"
|
||||
)
|
||||
if not resource:
|
||||
raise ValueError("The data resource is not found!")
|
||||
data_df = await resource_db_client.query_to_df(resource.value, param.sql)
|
||||
if not self.render_protocol:
|
||||
raise ValueError("The rendering protocol is not initialized!")
|
||||
view = await self.render_protocol.display(
|
||||
chart=json.loads(model_to_json(param)), data_df=data_df
|
||||
)
|
||||
if not self.resource_need:
|
||||
raise ValueError("The resource type is not found!")
|
||||
return ActionOutput(
|
||||
is_exe_success=True,
|
||||
content=model_to_json(param),
|
||||
view=view,
|
||||
resource_type=self.resource_need.value,
|
||||
resource_value=resource.value,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception("Check your answers, the sql run failed!")
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content=f"Check your answers, the sql run failed!Reason:{str(e)}",
|
||||
)
|
148
dbgpt/agent/expand/actions/code_action.py
Normal file
148
dbgpt/agent/expand/actions/code_action.py
Normal file
@@ -0,0 +1,148 @@
|
||||
"""Code Action Module."""
|
||||
|
||||
import logging
|
||||
from typing import Optional, Union
|
||||
|
||||
from dbgpt.util.code_utils import UNKNOWN, execute_code, extract_code, infer_lang
|
||||
from dbgpt.util.utils import colored
|
||||
from dbgpt.vis.tags.vis_code import Vis, VisCode
|
||||
|
||||
from ...core.action.base import Action, ActionOutput
|
||||
from ...resource.resource_api import AgentResource
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CodeAction(Action[None]):
|
||||
"""Code Action Module."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create a code action."""
|
||||
super().__init__()
|
||||
self._render_protocol = VisCode()
|
||||
self._code_execution_config = {}
|
||||
|
||||
@property
|
||||
def render_protocol(self) -> Optional[Vis]:
|
||||
"""Return the render protocol."""
|
||||
return self._render_protocol
|
||||
|
||||
async def run(
|
||||
self,
|
||||
ai_message: str,
|
||||
resource: Optional[AgentResource] = None,
|
||||
rely_action_out: Optional[ActionOutput] = None,
|
||||
need_vis_render: bool = True,
|
||||
**kwargs,
|
||||
) -> ActionOutput:
|
||||
"""Perform the action."""
|
||||
try:
|
||||
code_blocks = extract_code(ai_message)
|
||||
if len(code_blocks) < 1:
|
||||
logger.info(
|
||||
f"No executable code found in answer,{ai_message}",
|
||||
)
|
||||
return ActionOutput(
|
||||
is_exe_success=False, content="No executable code found in answer."
|
||||
)
|
||||
elif len(code_blocks) > 1 and code_blocks[0][0] == UNKNOWN:
|
||||
# found code blocks, execute code and push "last_n_messages" back
|
||||
logger.info(
|
||||
f"Missing available code block type, unable to execute code,"
|
||||
f"{ai_message}",
|
||||
)
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="Missing available code block type, "
|
||||
"unable to execute code.",
|
||||
)
|
||||
exitcode, logs = self.execute_code_blocks(code_blocks)
|
||||
exit_success = exitcode == 0
|
||||
|
||||
content = (
|
||||
logs
|
||||
if exit_success
|
||||
else f"exitcode: {exitcode} (execution failed)\n {logs}"
|
||||
)
|
||||
|
||||
param = {
|
||||
"exit_success": exit_success,
|
||||
"language": code_blocks[0][0],
|
||||
"code": code_blocks,
|
||||
"log": logs,
|
||||
}
|
||||
if not self.render_protocol:
|
||||
raise NotImplementedError("The render_protocol should be implemented.")
|
||||
view = await self.render_protocol.display(content=param)
|
||||
return ActionOutput(
|
||||
is_exe_success=exit_success,
|
||||
content=content,
|
||||
view=view,
|
||||
thoughts=ai_message,
|
||||
observations=content,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception("Code Action Run Failed!")
|
||||
return ActionOutput(
|
||||
is_exe_success=False, content="Code execution exception," + str(e)
|
||||
)
|
||||
|
||||
def execute_code_blocks(self, code_blocks):
|
||||
"""Execute the code blocks and return the result."""
|
||||
logs_all = ""
|
||||
exitcode = -1
|
||||
for i, code_block in enumerate(code_blocks):
|
||||
lang, code = code_block
|
||||
if not lang:
|
||||
lang = infer_lang(code)
|
||||
print(
|
||||
colored(
|
||||
f"\n>>>>>>>> EXECUTING CODE BLOCK {i} "
|
||||
f"(inferred language is {lang})...",
|
||||
"red",
|
||||
),
|
||||
flush=True,
|
||||
)
|
||||
if lang in ["bash", "shell", "sh"]:
|
||||
exitcode, logs, image = execute_code(
|
||||
code, lang=lang, **self._code_execution_config
|
||||
)
|
||||
elif lang in ["python", "Python"]:
|
||||
if code.startswith("# filename: "):
|
||||
filename = code[11 : code.find("\n")].strip()
|
||||
else:
|
||||
filename = None
|
||||
exitcode, logs, image = execute_code(
|
||||
code,
|
||||
lang="python",
|
||||
filename=filename,
|
||||
**self._code_execution_config,
|
||||
)
|
||||
else:
|
||||
# In case the language is not supported, we return an error message.
|
||||
exitcode, logs, image = (
|
||||
1,
|
||||
f"unknown language {lang}",
|
||||
None,
|
||||
)
|
||||
# raise NotImplementedError
|
||||
if image is not None:
|
||||
self._code_execution_config["use_docker"] = image
|
||||
logs_all += "\n" + logs
|
||||
if exitcode != 0:
|
||||
return exitcode, logs_all
|
||||
return exitcode, logs_all
|
||||
|
||||
@property
|
||||
def use_docker(self) -> Union[bool, str, None]:
|
||||
"""Whether to use docker to execute the code.
|
||||
|
||||
Bool value of whether to use docker to execute the code,
|
||||
or str value of the docker image name to use, or None when code execution is
|
||||
disabled.
|
||||
"""
|
||||
return (
|
||||
None
|
||||
if self._code_execution_config is False
|
||||
else self._code_execution_config.get("use_docker")
|
||||
)
|
130
dbgpt/agent/expand/actions/dashboard_action.py
Normal file
130
dbgpt/agent/expand/actions/dashboard_action.py
Normal file
@@ -0,0 +1,130 @@
|
||||
"""Dashboard Action Module."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from dbgpt._private.pydantic import BaseModel, Field, model_to_dict
|
||||
from dbgpt.vis.tags.vis_dashboard import Vis, VisDashboard
|
||||
|
||||
from ...core.action.base import Action, ActionOutput
|
||||
from ...resource.resource_api import AgentResource, ResourceType
|
||||
from ...resource.resource_db_api import ResourceDbClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ChartItem(BaseModel):
|
||||
"""Chart item model."""
|
||||
|
||||
title: str = Field(
|
||||
...,
|
||||
description="The title of the current analysis chart.",
|
||||
)
|
||||
display_type: str = Field(
|
||||
...,
|
||||
description="The chart rendering method selected for SQL. If you don’t know "
|
||||
"what to output, just output 'response_table' uniformly.",
|
||||
)
|
||||
sql: str = Field(
|
||||
..., description="Executable sql generated for the current target/problem"
|
||||
)
|
||||
thought: str = Field(..., description="Summary of thoughts to the user")
|
||||
|
||||
def to_dict(self):
|
||||
"""Convert to dict."""
|
||||
return model_to_dict(self)
|
||||
|
||||
|
||||
class DashboardAction(Action[List[ChartItem]]):
|
||||
"""Dashboard action class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create a dashboard action."""
|
||||
super().__init__()
|
||||
self._render_protocol = VisDashboard()
|
||||
|
||||
@property
|
||||
def resource_need(self) -> Optional[ResourceType]:
|
||||
"""Return the resource type needed for the action."""
|
||||
return ResourceType.DB
|
||||
|
||||
@property
|
||||
def render_protocol(self) -> Optional[Vis]:
|
||||
"""Return the render protocol."""
|
||||
return self._render_protocol
|
||||
|
||||
@property
|
||||
def out_model_type(self):
|
||||
"""Return the output model type."""
|
||||
return List[ChartItem]
|
||||
|
||||
async def run(
|
||||
self,
|
||||
ai_message: str,
|
||||
resource: Optional[AgentResource] = None,
|
||||
rely_action_out: Optional[ActionOutput] = None,
|
||||
need_vis_render: bool = True,
|
||||
**kwargs,
|
||||
) -> ActionOutput:
|
||||
"""Perform the action."""
|
||||
try:
|
||||
input_param = self._input_convert(ai_message, List[ChartItem])
|
||||
except Exception as e:
|
||||
logger.exception(str(e))
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="The requested correctly structured answer could not be found.",
|
||||
)
|
||||
if not isinstance(input_param, list):
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="The requested correctly structured answer could not be found.",
|
||||
)
|
||||
chart_items: List[ChartItem] = input_param
|
||||
try:
|
||||
if not self.resource_loader:
|
||||
raise ValueError("Resource loader is not initialized!")
|
||||
resource_db_client: Optional[
|
||||
ResourceDbClient
|
||||
] = self.resource_loader.get_resource_api(
|
||||
self.resource_need, ResourceDbClient
|
||||
)
|
||||
if not resource_db_client:
|
||||
raise ValueError(
|
||||
"There is no implementation class bound to database resource "
|
||||
"execution!"
|
||||
)
|
||||
|
||||
if not resource:
|
||||
raise ValueError("Resource is not initialized!")
|
||||
|
||||
chart_params = []
|
||||
for chart_item in chart_items:
|
||||
chart_dict = {}
|
||||
try:
|
||||
sql_df = await resource_db_client.query_to_df(
|
||||
resource.value, chart_item.sql
|
||||
)
|
||||
chart_dict = chart_item.to_dict()
|
||||
|
||||
chart_dict["data"] = sql_df
|
||||
except Exception as e:
|
||||
logger.warning(f"Sql execute failed!{str(e)}")
|
||||
chart_dict["err_msg"] = str(e)
|
||||
chart_params.append(chart_dict)
|
||||
if not self.render_protocol:
|
||||
raise ValueError("The render protocol is not initialized!")
|
||||
view = await self.render_protocol.display(charts=chart_params)
|
||||
return ActionOutput(
|
||||
is_exe_success=True,
|
||||
content=json.dumps(
|
||||
[chart_item.to_dict() for chart_item in chart_items]
|
||||
),
|
||||
view=view,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception("Dashboard generate Failed!")
|
||||
return ActionOutput(
|
||||
is_exe_success=False, content=f"Dashboard action run failed!{str(e)}"
|
||||
)
|
157
dbgpt/agent/expand/actions/indicator_action.py
Normal file
157
dbgpt/agent/expand/actions/indicator_action.py
Normal file
@@ -0,0 +1,157 @@
|
||||
"""Indicator Action."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from dbgpt._private.pydantic import BaseModel, Field
|
||||
from dbgpt.vis.tags.vis_plugin import Vis, VisPlugin
|
||||
|
||||
from ...core.action.base import Action, ActionOutput
|
||||
from ...core.schema import Status
|
||||
from ...resource.resource_api import AgentResource, ResourceType
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IndicatorInput(BaseModel):
|
||||
"""Indicator input model."""
|
||||
|
||||
indicator_name: str = Field(
|
||||
...,
|
||||
description="The name of a indicator.",
|
||||
)
|
||||
api: str = Field(
|
||||
...,
|
||||
description="The api of a indicator.",
|
||||
)
|
||||
method: str = Field(
|
||||
...,
|
||||
description="The api of a indicator request method.",
|
||||
)
|
||||
args: dict = Field(
|
||||
default={"arg name1": "", "arg name2": ""},
|
||||
description="The tool selected for the current target, the parameter "
|
||||
"information required for execution",
|
||||
)
|
||||
thought: str = Field(..., description="Summary of thoughts to the user")
|
||||
|
||||
|
||||
class IndicatorAction(Action[IndicatorInput]):
|
||||
"""Indicator action class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create a indicator action."""
|
||||
super().__init__()
|
||||
self._render_protocol = VisPlugin()
|
||||
|
||||
@property
|
||||
def resource_need(self) -> Optional[ResourceType]:
|
||||
"""Return the resource type needed for the action."""
|
||||
return ResourceType.Knowledge
|
||||
|
||||
@property
|
||||
def render_protocol(self) -> Optional[Vis]:
|
||||
"""Return the render protocol."""
|
||||
return self._render_protocol
|
||||
|
||||
@property
|
||||
def out_model_type(self):
|
||||
"""Return the output model type."""
|
||||
return IndicatorInput
|
||||
|
||||
@property
|
||||
def ai_out_schema(self) -> Optional[str]:
|
||||
"""Return the AI output schema."""
|
||||
out_put_schema = {
|
||||
"indicator_name": "The name of a tool that can be used to answer the "
|
||||
"current question or solve the current task.",
|
||||
"api": "",
|
||||
"method": "",
|
||||
"args": {
|
||||
"arg name1": "Parameters in api definition",
|
||||
"arg name2": "Parameters in api definition",
|
||||
},
|
||||
"thought": "Summary of thoughts to the user",
|
||||
}
|
||||
|
||||
return f"""Please response in the following json format:
|
||||
{json.dumps(out_put_schema, indent=2, ensure_ascii=False)}
|
||||
Make sure the response is correct json and can be parsed by Python json.loads.
|
||||
"""
|
||||
|
||||
async def run(
|
||||
self,
|
||||
ai_message: str,
|
||||
resource: Optional[AgentResource] = None,
|
||||
rely_action_out: Optional[ActionOutput] = None,
|
||||
need_vis_render: bool = True,
|
||||
**kwargs,
|
||||
) -> ActionOutput:
|
||||
"""Perform the action."""
|
||||
import requests
|
||||
from requests.exceptions import HTTPError
|
||||
|
||||
try:
|
||||
input_param = self._input_convert(ai_message, IndicatorInput)
|
||||
except Exception as e:
|
||||
logger.exception((str(e)))
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="The requested correctly structured answer could not be found.",
|
||||
)
|
||||
if isinstance(input_param, list):
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="The requested correctly structured answer could not be found.",
|
||||
)
|
||||
param: IndicatorInput = input_param
|
||||
response_success = True
|
||||
result: Optional[str] = None
|
||||
try:
|
||||
status = Status.COMPLETE.value
|
||||
err_msg = None
|
||||
try:
|
||||
status = Status.RUNNING.value
|
||||
if param.method.lower() == "get":
|
||||
response = requests.get(param.api, params=param.args)
|
||||
elif param.method.lower() == "post":
|
||||
response = requests.post(param.api, data=param.args)
|
||||
else:
|
||||
response = requests.request(
|
||||
param.method.lower(), param.api, data=param.args
|
||||
)
|
||||
# Raise an HTTPError if the HTTP request returned an unsuccessful
|
||||
# status code
|
||||
response.raise_for_status()
|
||||
result = response.text
|
||||
except HTTPError as http_err:
|
||||
response_success = False
|
||||
print(f"HTTP error occurred: {http_err}")
|
||||
except Exception as e:
|
||||
response_success = False
|
||||
logger.exception(f"API [{param.indicator_name}] excute Failed!")
|
||||
status = Status.FAILED.value
|
||||
err_msg = f"API [{param.api}] request Failed!{str(e)}"
|
||||
|
||||
plugin_param = {
|
||||
"name": param.indicator_name,
|
||||
"args": param.args,
|
||||
"status": status,
|
||||
"logo": None,
|
||||
"result": result,
|
||||
"err_msg": err_msg,
|
||||
}
|
||||
|
||||
if not self.render_protocol:
|
||||
raise NotImplementedError("The render_protocol should be implemented.")
|
||||
view = await self.render_protocol.display(content=plugin_param)
|
||||
|
||||
return ActionOutput(
|
||||
is_exe_success=response_success, content=result, view=view
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception("Indicator Action Run Failed!")
|
||||
return ActionOutput(
|
||||
is_exe_success=False, content=f"Indicator action run failed!{str(e)}"
|
||||
)
|
157
dbgpt/agent/expand/actions/plugin_action.py
Normal file
157
dbgpt/agent/expand/actions/plugin_action.py
Normal file
@@ -0,0 +1,157 @@
|
||||
"""Plugin Action Module."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from dbgpt._private.pydantic import BaseModel, Field
|
||||
from dbgpt.vis.tags.vis_plugin import Vis, VisPlugin
|
||||
|
||||
from ...core.action.base import Action, ActionOutput
|
||||
from ...core.schema import Status
|
||||
from ...plugin.generator import PluginPromptGenerator
|
||||
from ...resource.resource_api import AgentResource, ResourceType
|
||||
from ...resource.resource_plugin_api import ResourcePluginClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PluginInput(BaseModel):
|
||||
"""Plugin input model."""
|
||||
|
||||
tool_name: str = Field(
|
||||
...,
|
||||
description="The name of a tool that can be used to answer the current question"
|
||||
" or solve the current task.",
|
||||
)
|
||||
args: dict = Field(
|
||||
default={"arg name1": "", "arg name2": ""},
|
||||
description="The tool selected for the current target, the parameter "
|
||||
"information required for execution",
|
||||
)
|
||||
thought: str = Field(..., description="Summary of thoughts to the user")
|
||||
|
||||
|
||||
class PluginAction(Action[PluginInput]):
|
||||
"""Plugin action class."""
|
||||
|
||||
def __init__(self):
|
||||
"""Create a plugin action."""
|
||||
super().__init__()
|
||||
self._render_protocol = VisPlugin()
|
||||
|
||||
@property
|
||||
def resource_need(self) -> Optional[ResourceType]:
|
||||
"""Return the resource type needed for the action."""
|
||||
return ResourceType.Plugin
|
||||
|
||||
@property
|
||||
def render_protocol(self) -> Optional[Vis]:
|
||||
"""Return the render protocol."""
|
||||
return self._render_protocol
|
||||
|
||||
@property
|
||||
def out_model_type(self):
|
||||
"""Return the output model type."""
|
||||
return PluginInput
|
||||
|
||||
@property
|
||||
def ai_out_schema(self) -> Optional[str]:
|
||||
"""Return the AI output schema."""
|
||||
out_put_schema = {
|
||||
"tool_name": "The name of a tool that can be used to answer the current "
|
||||
"question or solve the current task.",
|
||||
"args": {
|
||||
"arg name1": "arg value1",
|
||||
"arg name2": "arg value2",
|
||||
},
|
||||
"thought": "Summary of thoughts to the user",
|
||||
}
|
||||
|
||||
return f"""Please response in the following json format:
|
||||
{json.dumps(out_put_schema, indent=2, ensure_ascii=False)}
|
||||
Make sure the response is correct json and can be parsed by Python json.loads.
|
||||
"""
|
||||
|
||||
async def run(
|
||||
self,
|
||||
ai_message: str,
|
||||
resource: Optional[AgentResource] = None,
|
||||
rely_action_out: Optional[ActionOutput] = None,
|
||||
need_vis_render: bool = True,
|
||||
**kwargs,
|
||||
) -> ActionOutput:
|
||||
"""Perform the plugin action.
|
||||
|
||||
Args:
|
||||
ai_message (str): The AI message.
|
||||
resource (Optional[AgentResource], optional): The resource. Defaults to
|
||||
None.
|
||||
rely_action_out (Optional[ActionOutput], optional): The rely action output.
|
||||
Defaults to None.
|
||||
need_vis_render (bool, optional): Whether need visualization rendering.
|
||||
Defaults to True.
|
||||
"""
|
||||
plugin_generator: Optional[PluginPromptGenerator] = kwargs.get(
|
||||
"plugin_generator", None
|
||||
)
|
||||
if not plugin_generator:
|
||||
raise ValueError("No plugin generator found!")
|
||||
try:
|
||||
param: PluginInput = self._input_convert(ai_message, PluginInput)
|
||||
except Exception as e:
|
||||
logger.exception((str(e)))
|
||||
return ActionOutput(
|
||||
is_exe_success=False,
|
||||
content="The requested correctly structured answer could not be found.",
|
||||
)
|
||||
|
||||
try:
|
||||
if not self.resource_loader:
|
||||
raise ValueError("No resource_loader found!")
|
||||
resource_plugin_client: Optional[
|
||||
ResourcePluginClient
|
||||
] = self.resource_loader.get_resource_api(
|
||||
self.resource_need, ResourcePluginClient
|
||||
)
|
||||
if not resource_plugin_client:
|
||||
raise ValueError("No implementation of the use of plug-in resources!")
|
||||
response_success = True
|
||||
status = Status.RUNNING.value
|
||||
err_msg = None
|
||||
try:
|
||||
tool_result = await resource_plugin_client.execute_command(
|
||||
param.tool_name, param.args, plugin_generator
|
||||
)
|
||||
status = Status.COMPLETE.value
|
||||
except Exception as e:
|
||||
response_success = False
|
||||
logger.exception(f"Tool [{param.tool_name}] execute failed!")
|
||||
status = Status.FAILED.value
|
||||
err_msg = f"Tool [{param.tool_name}] execute failed! {str(e)}"
|
||||
tool_result = err_msg
|
||||
|
||||
plugin_param = {
|
||||
"name": param.tool_name,
|
||||
"args": param.args,
|
||||
"status": status,
|
||||
"logo": None,
|
||||
"result": tool_result,
|
||||
"err_msg": err_msg,
|
||||
}
|
||||
if not self.render_protocol:
|
||||
raise NotImplementedError("The render_protocol should be implemented.")
|
||||
|
||||
view = await self.render_protocol.display(content=plugin_param)
|
||||
|
||||
return ActionOutput(
|
||||
is_exe_success=response_success,
|
||||
content=tool_result,
|
||||
view=view,
|
||||
observations=tool_result,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception("Tool Action Run Failed!")
|
||||
return ActionOutput(
|
||||
is_exe_success=False, content=f"Tool action run failed!{str(e)}"
|
||||
)
|
@@ -1,12 +1,14 @@
|
||||
"""Code Assistant Agent."""
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from dbgpt.core import ModelMessageRoleType
|
||||
from dbgpt.util.string_utils import str_to_bool
|
||||
|
||||
from ..actions.code_action import CodeAction
|
||||
from ..core.agent import AgentMessage
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import DynConfig, ProfileConfig
|
||||
from .actions.code_action import CodeAction
|
||||
|
||||
CHECK_RESULT_SYSTEM_MESSAGE = (
|
||||
"You are an expert in analyzing the results of task execution. Your responsibility "
|
||||
@@ -42,54 +44,75 @@ CHECK_RESULT_SYSTEM_MESSAGE = (
|
||||
class CodeAssistantAgent(ConversableAgent):
|
||||
"""Code Assistant Agent."""
|
||||
|
||||
name: str = "Turing"
|
||||
profile: str = "CodeEngineer"
|
||||
goal: str = (
|
||||
"Solve tasks using your coding and language skills.\n"
|
||||
"In the following cases, suggest python code (in a python coding block) or "
|
||||
"shell script (in a sh coding block) for the user to execute.\n"
|
||||
" 1. When you need to collect info, use the code to output the info you "
|
||||
"need, for example, browse or search the web, download/read a file, print the "
|
||||
"content of a webpage or a file, get the current date/time, check the "
|
||||
"operating system. After sufficient info is printed and the task is ready to be"
|
||||
" solved based on your language skill, you can solve the task by yourself.\n"
|
||||
" 2. When you need to perform some task with code, use the code to perform "
|
||||
"the task and output the result. Finish the task smartly."
|
||||
)
|
||||
constraints: List[str] = [
|
||||
"The user cannot provide any other feedback or perform any other action beyond"
|
||||
" executing the code you suggest. The user can't modify your code. So do not "
|
||||
"suggest incomplete code which requires users to modify. Don't use a code block"
|
||||
" if it's not intended to be executed by the user.Don't ask users to copy and "
|
||||
"paste results. Instead, the 'Print' function must be used for output when "
|
||||
"relevant.",
|
||||
"When using code, you must indicate the script type in the code block. Please "
|
||||
"don't include multiple code blocks in one response.",
|
||||
"If you want the user to save the code in a file before executing it, put "
|
||||
"# filename: <filename> inside the code block as the first line.",
|
||||
"If you receive user input that indicates an error in the code execution, fix "
|
||||
"the error and output the complete code again. It is recommended to use the "
|
||||
"complete code rather than partial code or code changes. If the error cannot be"
|
||||
" fixed, or the task is not resolved even after the code executes successfully,"
|
||||
" analyze the problem, revisit your assumptions, gather additional information"
|
||||
" you need from historical conversation records, and consider trying a "
|
||||
"different approach.",
|
||||
"Unless necessary, give priority to solving problems with python code. If it "
|
||||
"involves downloading files or storing data locally, please use 'Print' to "
|
||||
"output the full file path of the stored data and a brief introduction to the "
|
||||
"data.",
|
||||
"The output content of the 'print' function will be passed to other LLM agents "
|
||||
"as dependent data. Please control the length of the output content of the "
|
||||
"'print' function. The 'print' function only outputs part of the key data "
|
||||
"information that is relied on, and is as concise as possible.",
|
||||
"The code is executed without user participation. It is forbidden to use "
|
||||
"methods that will block the process or need to be shut down, such as the "
|
||||
"plt.show() method of matplotlib.pyplot as plt.",
|
||||
"It is prohibited to fabricate non-existent data to achieve goals.",
|
||||
]
|
||||
desc: str = (
|
||||
"Can independently write and execute python/shell code to solve various"
|
||||
" problems"
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name=DynConfig(
|
||||
"Turing",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_code_assistant_agent_profile_name",
|
||||
),
|
||||
role=DynConfig(
|
||||
"CodeEngineer",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_code_assistant_agent_profile_role",
|
||||
),
|
||||
goal=DynConfig(
|
||||
"Solve tasks using your coding and language skills.\n"
|
||||
"In the following cases, suggest python code (in a python coding block) or "
|
||||
"shell script (in a sh coding block) for the user to execute.\n"
|
||||
" 1. When you need to collect info, use the code to output the info you "
|
||||
"need, for example, browse or search the web, download/read a file, print "
|
||||
"the content of a webpage or a file, get the current date/time, check the "
|
||||
"operating system. After sufficient info is printed and the task is ready "
|
||||
"to be solved based on your language skill, you can solve the task by "
|
||||
"yourself.\n"
|
||||
" 2. When you need to perform some task with code, use the code to "
|
||||
"perform the task and output the result. Finish the task smartly.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_code_assistant_agent_profile_goal",
|
||||
),
|
||||
constraints=DynConfig(
|
||||
[
|
||||
"The user cannot provide any other feedback or perform any other "
|
||||
"action beyond executing the code you suggest. The user can't modify "
|
||||
"your code. So do not suggest incomplete code which requires users to "
|
||||
"modify. Don't use a code block if it's not intended to be executed "
|
||||
"by the user.Don't ask users to copy and paste results. Instead, "
|
||||
"the 'Print' function must be used for output when relevant.",
|
||||
"When using code, you must indicate the script type in the code block. "
|
||||
"Please don't include multiple code blocks in one response.",
|
||||
"If you want the user to save the code in a file before executing it, "
|
||||
"put # filename: <filename> inside the code block as the first line.",
|
||||
"If you receive user input that indicates an error in the code "
|
||||
"execution, fix the error and output the complete code again. It is "
|
||||
"recommended to use the complete code rather than partial code or "
|
||||
"code changes. If the error cannot be fixed, or the task is not "
|
||||
"resolved even after the code executes successfully, analyze the "
|
||||
"problem, revisit your assumptions, gather additional information you "
|
||||
"need from historical conversation records, and consider trying a "
|
||||
"different approach.",
|
||||
"Unless necessary, give priority to solving problems with python "
|
||||
"code. If it involves downloading files or storing data locally, "
|
||||
"please use 'Print' to output the full file path of the stored data "
|
||||
"and a brief introduction to the data.",
|
||||
"The output content of the 'print' function will be passed to other "
|
||||
"LLM agents as dependent data. Please control the length of the "
|
||||
"output content of the 'print' function. The 'print' function only "
|
||||
"outputs part of the key data information that is relied on, "
|
||||
"and is as concise as possible.",
|
||||
"The code is executed without user participation. It is forbidden to "
|
||||
"use methods that will block the process or need to be shut down, "
|
||||
"such as the plt.show() method of matplotlib.pyplot as plt.",
|
||||
"It is prohibited to fabricate non-existent data to achieve goals.",
|
||||
],
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_code_assistant_agent_profile_constraints",
|
||||
),
|
||||
desc=DynConfig(
|
||||
"Can independently write and execute python/shell code to solve various"
|
||||
" problems",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_code_assistant_agent_profile_desc",
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@@ -1,37 +1,54 @@
|
||||
"""Dashboard Assistant Agent."""
|
||||
|
||||
from typing import List
|
||||
|
||||
from ..actions.dashboard_action import DashboardAction
|
||||
from ..core.agent import AgentMessage
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import DynConfig, ProfileConfig
|
||||
from ..resource.resource_db_api import ResourceDbClient
|
||||
from .actions.dashboard_action import DashboardAction
|
||||
|
||||
|
||||
class DashboardAssistantAgent(ConversableAgent):
|
||||
"""Dashboard Assistant Agent."""
|
||||
|
||||
name: str = "Visionary"
|
||||
|
||||
profile: str = "Reporter"
|
||||
goal: str = (
|
||||
"Read the provided historical messages, collect various analysis SQLs "
|
||||
"from them, and assemble them into professional reports."
|
||||
)
|
||||
constraints: List[str] = [
|
||||
"You are only responsible for collecting and sorting out the analysis SQL that"
|
||||
" already exists in historical messages, and do not generate any analysis sql "
|
||||
"yourself.",
|
||||
"In order to build a report with rich display types, you can appropriately "
|
||||
"adjust the display type of the charts you collect so that you can build a "
|
||||
"better report. Of course, you can choose from the following available "
|
||||
"display types: {display_type}",
|
||||
"Please read and completely collect all analysis sql in the historical "
|
||||
"conversation, and do not omit or modify the content of the analysis sql.",
|
||||
]
|
||||
desc: str = (
|
||||
"Observe and organize various analysis results and construct "
|
||||
"professional reports"
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name=DynConfig(
|
||||
"Visionary",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_name",
|
||||
),
|
||||
role=DynConfig(
|
||||
"Reporter",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_role",
|
||||
),
|
||||
goal=DynConfig(
|
||||
"Read the provided historical messages, collect various analysis SQLs "
|
||||
"from them, and assemble them into professional reports.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_goal",
|
||||
),
|
||||
constraints=DynConfig(
|
||||
[
|
||||
"You are only responsible for collecting and sorting out the analysis "
|
||||
"SQL that already exists in historical messages, and do not generate "
|
||||
"any analysis sql yourself.",
|
||||
"In order to build a report with rich display types, you can "
|
||||
"appropriately adjust the display type of the charts you collect so "
|
||||
"that you can build a better report. Of course, you can choose from "
|
||||
"the following available display types: {{ display_type }}",
|
||||
"Please read and completely collect all analysis sql in the "
|
||||
"historical conversation, and do not omit or modify the content of "
|
||||
"the analysis sql.",
|
||||
],
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_constraints",
|
||||
),
|
||||
desc=DynConfig(
|
||||
"Observe and organize various analysis results and construct "
|
||||
"professional reports",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_desc",
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@@ -2,14 +2,15 @@
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import List, Optional, Tuple, cast
|
||||
from typing import Optional, Tuple, cast
|
||||
|
||||
from ..actions.action import ActionOutput
|
||||
from ..actions.chart_action import ChartAction
|
||||
from ..core.action.base import ActionOutput
|
||||
from ..core.agent import AgentMessage
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import DynConfig, ProfileConfig
|
||||
from ..resource.resource_api import ResourceType
|
||||
from ..resource.resource_db_api import ResourceDbClient
|
||||
from .actions.chart_action import ChartAction
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -17,31 +18,53 @@ logger = logging.getLogger(__name__)
|
||||
class DataScientistAgent(ConversableAgent):
|
||||
"""Data Scientist Agent."""
|
||||
|
||||
name: str = "Edgar"
|
||||
profile: str = "DataScientist"
|
||||
goal: str = (
|
||||
"Use correct {dialect} SQL to analyze and solve tasks based on the data"
|
||||
" structure information of the database given in the resource."
|
||||
)
|
||||
constraints: List[str] = [
|
||||
"Please check the generated SQL carefully. Please strictly abide by the data "
|
||||
"structure definition given. It is prohibited to use non-existent fields and "
|
||||
"data values. Do not use fields from table A to table B. You can perform "
|
||||
"multi-table related queries.",
|
||||
"If the data and fields that need to be analyzed in the target are in different"
|
||||
" tables, it is recommended to use multi-table correlation queries first, and "
|
||||
"pay attention to the correlation between multiple table structures.",
|
||||
"It is forbidden to construct data by yourself as a query condition. If you "
|
||||
"want to query a specific field, if the value of the field is provided, then "
|
||||
"you can perform a group statistical query on the field.",
|
||||
"Please select an appropriate one from the supported display methods for data "
|
||||
"display. If no suitable display type is found, table display is used by "
|
||||
"default. Supported display types: \n {display_type}",
|
||||
]
|
||||
desc: str = (
|
||||
"Use database resources to conduct data analysis, analyze SQL, and "
|
||||
"provide recommended rendering methods."
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name=DynConfig(
|
||||
"Edgar",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_name",
|
||||
),
|
||||
role=DynConfig(
|
||||
"DataScientist",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_role",
|
||||
),
|
||||
goal=DynConfig(
|
||||
"Use correct {{ dialect }} SQL to analyze and solve tasks based on the data"
|
||||
" structure information of the database given in the resource.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_goal",
|
||||
),
|
||||
constraints=DynConfig(
|
||||
[
|
||||
"Please check the generated SQL carefully. Please strictly abide by "
|
||||
"the data structure definition given. It is prohibited to use "
|
||||
"non-existent fields and data values. Do not use fields from table A "
|
||||
"to table B. You can perform multi-table related queries.",
|
||||
"If the data and fields that need to be analyzed in the target are in "
|
||||
"different tables, it is recommended to use multi-table correlation "
|
||||
"queries first, and pay attention to the correlation between multiple "
|
||||
"table structures.",
|
||||
"It is forbidden to construct data by yourself as a query condition. "
|
||||
"If you want to query a specific field, if the value of the field is "
|
||||
"provided, then you can perform a group statistical query on the "
|
||||
"field.",
|
||||
"Please select an appropriate one from the supported display methods "
|
||||
"for data display. If no suitable display type is found, "
|
||||
"table display is used by default. Supported display types: \n"
|
||||
"{{ display_type }}",
|
||||
],
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_constraints",
|
||||
),
|
||||
desc=DynConfig(
|
||||
"Use database resources to conduct data analysis, analyze SQL, and provide "
|
||||
"recommended rendering methods.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_dashboard_assistant_agent_profile_desc",
|
||||
),
|
||||
)
|
||||
|
||||
max_retry_count: int = 5
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@@ -1,12 +1,14 @@
|
||||
"""Plugin Assistant Agent."""
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from ..actions.plugin_action import PluginAction
|
||||
import logging
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import DynConfig, ProfileConfig
|
||||
from ..plugin.generator import PluginPromptGenerator
|
||||
from ..resource.resource_api import ResourceType
|
||||
from ..resource.resource_plugin_api import ResourcePluginClient
|
||||
from .actions.plugin_action import PluginAction
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -16,23 +18,42 @@ class PluginAssistantAgent(ConversableAgent):
|
||||
|
||||
plugin_generator: Optional[PluginPromptGenerator] = None
|
||||
|
||||
name: str = "LuBan"
|
||||
profile: str = "ToolExpert"
|
||||
goal: str = (
|
||||
"Read and understand the tool information given in the resources below to "
|
||||
"understand their capabilities and how to use them,and choosing the right tools"
|
||||
" to achieve the user's goals."
|
||||
)
|
||||
constraints: List[str] = [
|
||||
"Please read the parameter definition of the tool carefully and extract the "
|
||||
"specific parameters required to execute the tool from the user goal.",
|
||||
"Please output the selected tool name and specific parameter information in "
|
||||
"json format according to the following required format. If there is an "
|
||||
"example, please refer to the sample format output.",
|
||||
]
|
||||
desc: str = (
|
||||
"You can use the following tools to complete the task objectives, tool "
|
||||
"information: {tool_infos}"
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name=DynConfig(
|
||||
"LuBan",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_plugin_assistant_agent_name",
|
||||
),
|
||||
role=DynConfig(
|
||||
"ToolExpert",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_plugin_assistant_agent_role",
|
||||
),
|
||||
goal=DynConfig(
|
||||
"Read and understand the tool information given in the resources "
|
||||
"below to understand their capabilities and how to use them,and choosing "
|
||||
"the right tools to achieve the user's goals.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_plugin_assistant_agent_goal",
|
||||
),
|
||||
constraints=DynConfig(
|
||||
[
|
||||
"Please read the parameter definition of the tool carefully and extract"
|
||||
" the specific parameters required to execute the tool from the user "
|
||||
"goal.",
|
||||
"Please output the selected tool name and specific parameter "
|
||||
"information in json format according to the following required format."
|
||||
" If there is an example, please refer to the sample format output.",
|
||||
],
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_plugin_assistant_agent_constraints",
|
||||
),
|
||||
desc=DynConfig(
|
||||
"You can use the following tools to complete the task objectives, "
|
||||
"tool information: {tool_infos}",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_plugin_assistant_agent_desc",
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -40,14 +61,14 @@ class PluginAssistantAgent(ConversableAgent):
|
||||
super().__init__(**kwargs)
|
||||
self._init_actions([PluginAction])
|
||||
|
||||
@property
|
||||
def introduce(self, **kwargs) -> str:
|
||||
"""Introduce the agent."""
|
||||
if not self.plugin_generator:
|
||||
raise ValueError("PluginGenerator is not loaded.")
|
||||
return self.desc.format(
|
||||
tool_infos=self.plugin_generator.generate_commands_string()
|
||||
)
|
||||
# @property
|
||||
# def introduce(self, **kwargs) -> str:
|
||||
# """Introduce the agent."""
|
||||
# if not self.plugin_generator:
|
||||
# raise ValueError("PluginGenerator is not loaded.")
|
||||
# return self.desc.format(
|
||||
# tool_infos=self.plugin_generator.generate_commands_string()
|
||||
# )
|
||||
|
||||
async def preload_resource(self):
|
||||
"""Preload the resource."""
|
||||
|
@@ -1,4 +1,5 @@
|
||||
"""Retrieve Summary Assistant Agent."""
|
||||
|
||||
import glob
|
||||
import json
|
||||
import logging
|
||||
@@ -9,9 +10,10 @@ from urllib.parse import urlparse
|
||||
from dbgpt.configs.model_config import PILOT_PATH
|
||||
from dbgpt.core import ModelMessageRoleType
|
||||
|
||||
from ..actions.action import Action, ActionOutput
|
||||
from ..core.action.base import Action, ActionOutput
|
||||
from ..core.agent import Agent, AgentMessage, AgentReviewInfo
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import ProfileConfig
|
||||
from ..resource.resource_api import AgentResource
|
||||
from ..util.cmp import cmp_string_equal
|
||||
|
||||
@@ -86,18 +88,7 @@ class RetrieveSummaryAssistantAgent(ConversableAgent):
|
||||
including suggesting python code blocks and debugging.
|
||||
"""
|
||||
|
||||
goal = (
|
||||
"You're an extraction expert. You need to extract Please complete this task "
|
||||
"step by step following instructions below:\n"
|
||||
" 1. You need to first ONLY extract user's question that you need to answer "
|
||||
"without ANY file paths and URLs. \n"
|
||||
" 2. Extract the provided file paths and URLs.\n"
|
||||
" 3. Construct the extracted file paths and URLs as a list of strings.\n"
|
||||
" 4. ONLY output the extracted results with the following json format: "
|
||||
"{response}."
|
||||
)
|
||||
|
||||
PROMPT_QA = (
|
||||
PROMPT_QA: str = (
|
||||
"You are a great summary writer to summarize the provided text content "
|
||||
"according to user questions.\n"
|
||||
"User's Question is: {input_question}\n\n"
|
||||
@@ -118,7 +109,7 @@ class RetrieveSummaryAssistantAgent(ConversableAgent):
|
||||
"If the provided text content CAN NOT ANSWER user's question, ONLY output "
|
||||
"'NO RELATIONSHIP.UPDATE TEXT CONTENT.'!!."
|
||||
)
|
||||
CHECK_RESULT_SYSTEM_MESSAGE = (
|
||||
CHECK_RESULT_SYSTEM_MESSAGE: str = (
|
||||
"You are an expert in analyzing the results of a summary task."
|
||||
"Your responsibility is to check whether the summary results can summarize the "
|
||||
"input provided by the user, and then make a judgment. You need to answer "
|
||||
@@ -131,20 +122,30 @@ class RetrieveSummaryAssistantAgent(ConversableAgent):
|
||||
"not summarized. TERMINATE"
|
||||
)
|
||||
|
||||
DEFAULT_DESCRIBE = (
|
||||
DEFAULT_DESCRIBE: str = (
|
||||
"Summarize provided content according to user's questions and "
|
||||
"the provided file paths."
|
||||
)
|
||||
|
||||
name = "RetrieveSummarizer"
|
||||
desc = DEFAULT_DESCRIBE
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name="RetrieveSummarizer",
|
||||
role="Assistant",
|
||||
goal="You're an extraction expert. You need to extract Please complete this "
|
||||
"task step by step following instructions below:\n"
|
||||
" 1. You need to first ONLY extract user's question that you need to answer "
|
||||
"without ANY file paths and URLs. \n"
|
||||
" 2. Extract the provided file paths and URLs.\n"
|
||||
" 3. Construct the extracted file paths and URLs as a list of strings.\n"
|
||||
" 4. ONLY output the extracted results with the following json format: "
|
||||
"{{ response }}.",
|
||||
desc=DEFAULT_DESCRIBE,
|
||||
)
|
||||
|
||||
chunk_token_size: int = 4000
|
||||
chunk_mode: str = "multi_lines"
|
||||
|
||||
_model = "gpt-3.5-turbo-16k"
|
||||
_max_tokens = _get_max_tokens(_model)
|
||||
context_max_tokens = _max_tokens * 0.8
|
||||
_model: str = "gpt-3.5-turbo-16k"
|
||||
_max_tokens: int = _get_max_tokens(_model)
|
||||
context_max_tokens: int = int(_max_tokens * 0.8)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -174,12 +175,14 @@ class RetrieveSummaryAssistantAgent(ConversableAgent):
|
||||
reply_message: AgentMessage = self._init_reply_message(
|
||||
received_message=received_message
|
||||
)
|
||||
await self._system_message_assembly(
|
||||
received_message.content, reply_message.context
|
||||
)
|
||||
# 1.Think about how to do things
|
||||
llm_reply, model_name = await self.thinking(
|
||||
self._load_thinking_messages(received_message, sender, rely_messages)
|
||||
await self._load_thinking_messages(
|
||||
received_message,
|
||||
sender,
|
||||
rely_messages,
|
||||
context=reply_message.get_dict_context(),
|
||||
)
|
||||
)
|
||||
|
||||
if not llm_reply:
|
||||
@@ -454,16 +457,16 @@ class RetrieveSummaryAssistantAgent(ConversableAgent):
|
||||
" set to False."
|
||||
)
|
||||
must_break_at_empty_line = False
|
||||
chunks.append(prev) if len(
|
||||
prev
|
||||
) > 10 else None # don't add chunks less than 10 characters
|
||||
(
|
||||
chunks.append(prev) if len(prev) > 10 else None
|
||||
) # don't add chunks less than 10 characters
|
||||
lines = lines[cnt:]
|
||||
lines_tokens = lines_tokens[cnt:]
|
||||
sum_tokens = sum(lines_tokens)
|
||||
text_to_chunk = "\n".join(lines)
|
||||
chunks.append(text_to_chunk) if len(
|
||||
text_to_chunk
|
||||
) > 10 else None # don't add chunks less than 10 characters
|
||||
(
|
||||
chunks.append(text_to_chunk) if len(text_to_chunk) > 10 else None
|
||||
) # don't add chunks less than 10 characters
|
||||
return chunks
|
||||
|
||||
def _extract_text_from_pdf(self, file: str) -> str:
|
||||
|
@@ -1,9 +1,10 @@
|
||||
"""Summary Assistant Agent."""
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
from ..actions.blank_action import BlankAction
|
||||
import logging
|
||||
|
||||
from ..core.action.blank_action import BlankAction
|
||||
from ..core.base_agent import ConversableAgent
|
||||
from ..core.profile import DynConfig, ProfileConfig
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -11,29 +12,48 @@ logger = logging.getLogger(__name__)
|
||||
class SummaryAssistantAgent(ConversableAgent):
|
||||
"""Summary Assistant Agent."""
|
||||
|
||||
name: str = "Aristotle"
|
||||
profile: str = "Summarizer"
|
||||
goal: str = (
|
||||
"Summarize answer summaries based on user questions from provided "
|
||||
"resource information or from historical conversation memories."
|
||||
)
|
||||
|
||||
constraints: List[str] = [
|
||||
"Prioritize the summary of answers to user questions from the improved resource"
|
||||
" text. If no relevant information is found, summarize it from the historical "
|
||||
"dialogue memory given. It is forbidden to make up your own.",
|
||||
"You need to first detect user's question that you need to answer with your"
|
||||
" summarization.",
|
||||
"Extract the provided text content used for summarization.",
|
||||
"Then you need to summarize the extracted text content.",
|
||||
"Output the content of summarization ONLY related to user's question. The "
|
||||
"output language must be the same to user's question language.",
|
||||
"If you think the provided text content is not related to user questions at "
|
||||
"all, ONLY output 'Did not find the information you want.'!!.",
|
||||
]
|
||||
desc: str = (
|
||||
"You can summarize provided text content according to user's questions"
|
||||
" and output the summarization."
|
||||
profile: ProfileConfig = ProfileConfig(
|
||||
name=DynConfig(
|
||||
"Aristotle",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_summary_assistant_agent_profile_name",
|
||||
),
|
||||
role=DynConfig(
|
||||
"Summarizer",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_summary_assistant_agent_profile_role",
|
||||
),
|
||||
goal=DynConfig(
|
||||
"Summarize answer summaries based on user questions from provided "
|
||||
"resource information or from historical conversation memories.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_summary_assistant_agent_profile_goal",
|
||||
),
|
||||
constraints=DynConfig(
|
||||
[
|
||||
"Prioritize the summary of answers to user questions from the improved "
|
||||
"resource text. If no relevant information is found, summarize it from "
|
||||
"the historical dialogue memory given. It is forbidden to make up your "
|
||||
"own.",
|
||||
"You need to first detect user's question that you need to answer with "
|
||||
"your summarization.",
|
||||
"Extract the provided text content used for summarization.",
|
||||
"Then you need to summarize the extracted text content.",
|
||||
"Output the content of summarization ONLY related to user's question. "
|
||||
"The output language must be the same to user's question language.",
|
||||
"If you think the provided text content is not related to user "
|
||||
"questions at all, ONLY output 'Did not find the information you "
|
||||
"want.'!!.",
|
||||
],
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_summary_assistant_agent_profile_constraints",
|
||||
),
|
||||
desc=DynConfig(
|
||||
"You can summarize provided text content according to user's questions"
|
||||
" and output the summarization.",
|
||||
category="agent",
|
||||
key="dbgpt_agent_expand_summary_assistant_agent_profile_desc",
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
Reference in New Issue
Block a user