Files
OpenHands/opendevin/agent.py
Robert Brennan eb4a261880 Create generic LLM client using LiteLLM (#114)
* add generic llm client

* fix lint errors

* fix lint issues

* a potential suggestion for llm wrapper to keep all the function sigatures for ide

* use completion partial

* fix resp

* remove unused args

* add back truncation logic

* fix add_event

* fix merge issues

* more merge issues fixed

* fix codeact agent

* remove dead code

* remove import

* unused imports

* fix ruff

* update requirements

* mypy fixes

* more lint fixes

* fix browser errors

* fix up observation conversion

* fix format of error

* change max iter default back to 100

* fix kill action

* fix docker cleanup

* add RUN_AS_DEVIN flag

* fix condense

* revert some files

* unused imports

---------

Co-authored-by: Xingyao Wang <xingyao6@illinois.edu>
Co-authored-by: Robert Brennan <rbren@Roberts-MacBook-Pro.local>
2024-03-26 12:10:23 +08:00

97 lines
2.9 KiB
Python

from abc import ABC, abstractmethod
from typing import List, Dict, Type, TYPE_CHECKING
if TYPE_CHECKING:
from opendevin.action import Action
from opendevin.state import State
from opendevin.llm.llm import LLM
class Agent(ABC):
"""
This abstract base class is an general interface for an agent dedicated to
executing a specific instruction and allowing human interaction with the
agent during execution.
It tracks the execution status and maintains a history of interactions.
:param instruction: The instruction for the agent to execute.
:param model_name: The litellm name of the model to use for the agent.
"""
_registry: Dict[str, Type["Agent"]] = {}
def __init__(
self,
llm: LLM,
):
self.instruction = ""
self.llm = llm
self._complete = False
@property
def complete(self) -> bool:
"""
Indicates whether the current instruction execution is complete.
Returns:
- complete (bool): True if execution is complete; False otherwise.
"""
return self._complete
@abstractmethod
def step(self, state: "State") -> "Action":
"""
Starts the execution of the assigned instruction. This method should
be implemented by subclasses to define the specific execution logic.
"""
pass
@abstractmethod
def search_memory(self, query: str) -> List[str]:
"""
Searches the agent's memory for information relevant to the given query.
Parameters:
- query (str): The query to search for in the agent's memory.
Returns:
- response (str): The response to the query.
"""
pass
def reset(self) -> None:
"""
Resets the agent's execution status and clears the history. This method can be used
to prepare the agent for restarting the instruction or cleaning up before destruction.
"""
self.instruction = ""
self._complete = False
@classmethod
def register(cls, name: str, agent_cls: Type["Agent"]):
"""
Registers an agent class in the registry.
Parameters:
- name (str): The name to register the class under.
- agent_cls (Type['Agent']): The class to register.
"""
if name in cls._registry:
raise ValueError(f"Agent class already registered under '{name}'.")
cls._registry[name] = agent_cls
@classmethod
def get_cls(cls, name: str) -> Type["Agent"]:
"""
Retrieves an agent class from the registry.
Parameters:
- name (str): The name of the class to retrieve
Returns:
- agent_cls (Type['Agent']): The class registered under the specified name.
"""
if name not in cls._registry:
raise ValueError(f"No agent class registered under '{name}'.")
return cls._registry[name]