2025-09-23 20:31:19 +08:00

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