mirror of
https://github.com/OpenBMB/ChatDev.git
synced 2026-04-25 11:18:06 +00:00
133 lines
4.7 KiB
Python
133 lines
4.7 KiB
Python
import json
|
|
import yaml
|
|
import hashlib
|
|
import re
|
|
import time
|
|
from utils.other_utils import JsonFormat
|
|
from copy import deepcopy
|
|
from abc import ABC, abstractmethod
|
|
from model.query_manager import query_manager
|
|
from agent.agent_info.global_info import GlobalInfo
|
|
|
|
global_config = yaml.safe_load(open("./config/global.yaml", "r"))
|
|
|
|
class Agent(ABC):
|
|
def __init__(self, role, role_prompt, index, model="gpt", actions=[], policy=None, global_info:GlobalInfo =None, initial_dialog_history=None) -> None:
|
|
"""
|
|
Initialize the Agent object.
|
|
:param role: The name of the agent's role
|
|
:param role_prompt: The role prompt information
|
|
:param index: The index to distinguish different agent instances
|
|
:param global_info: Global configuration info, default is None
|
|
:param model: The model to be used (either 'gpt' or 'gpt4'), default is 'gpt'
|
|
:param actions: List of actions available to the agent, default is empty
|
|
:param initial_dialog_history: Initial dialog history, default is None
|
|
"""
|
|
super().__init__()
|
|
|
|
# Initialize model query function
|
|
self.model = model
|
|
self.query_func = None
|
|
self.query_func = self._get_query_function()
|
|
|
|
if not self.query_func:
|
|
raise ValueError(f"Model '{model}' not implemented")
|
|
|
|
# Other basic settings
|
|
self.json_format = JsonFormat(query_func=self.query_func)
|
|
self.role = role
|
|
self.role_prompt = role_prompt
|
|
self.system_prompt = self.role_prompt # Initial system prompt
|
|
self.policy = policy
|
|
self.index = index
|
|
self.hash = hashlib.md5(f"{index}{role}{role_prompt}{model}{time.ctime()}".encode()).hexdigest()
|
|
|
|
# Tools and file path settings
|
|
self.actions = actions
|
|
self.root_file_path = global_config["file_path"]["root_file_path"]
|
|
if global_info:
|
|
self.workspace_path = global_info.workpath
|
|
|
|
# Activation state and dialog history
|
|
self._activated = False
|
|
self.initial_dialog_history = initial_dialog_history or []
|
|
self.dialog_history = deepcopy(self.initial_dialog_history)
|
|
|
|
@property
|
|
def simplified_dialog_history(self):
|
|
self._simplified_dialog_history = []
|
|
for h in self.dialog_history:
|
|
if h.get("role") == "user":
|
|
# Mask user input
|
|
# "*Your previous reasoning was {}*”
|
|
masked_text = re.sub(r'\*.*?\*', '', h["content"])
|
|
self._simplified_dialog_history.append({"role": h["role"], "content": masked_text})
|
|
else:
|
|
self._simplified_dialog_history.append(h)
|
|
return self._simplified_dialog_history
|
|
|
|
@property
|
|
def unique_identifier(self):
|
|
"""Return a unique identifier for the Agent instance."""
|
|
return {
|
|
"index": self.index,
|
|
"role": self.role,
|
|
"hash": self.hash
|
|
}
|
|
def _get_query_function(self):
|
|
def query_func(messages, system_prompt=None):
|
|
return query_manager.query(self.model, messages, system_prompt)
|
|
return query_func
|
|
|
|
@abstractmethod
|
|
def activate(self, global_info, initial_dialog_history=None):
|
|
"""Activate the agent, enabling it to perform actions."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def deactivate(self):
|
|
"""Deactivate the agent."""
|
|
self._activated = False
|
|
|
|
def reset(self):
|
|
"""Reset the agent's state, clearing dialog history and deactivating it."""
|
|
self.dialog_history = []
|
|
self.initial_dialog_history = []
|
|
self.deactivate()
|
|
|
|
|
|
@abstractmethod
|
|
def _build_current_action(self, format_action, flag, answer, step_data):
|
|
"""Build the current workflow guiding the agent's actions."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def take_action(self, global_info, external_tools_enabled=True):
|
|
"""Let the agent take an action based on the current state."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _execute_action(self, action, global_info):
|
|
"""Execute a specific action."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _reasoning_operation(self, action, global_info) -> str:
|
|
"""Perform a reasoning operation."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _answer_operation(self, global_info) -> str:
|
|
"""Generate an answer based on the current state."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _tool_operation(self, action: json, global_info) -> str:
|
|
"""Perform an operation involving external tools."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _interaction_operation(self, code, env, global_info) -> str:
|
|
"""Handle operations related to agent interaction."""
|
|
pass
|