Add ability to customize configuration model on per-agent basis (#8576)

This commit is contained in:
Chase 2025-06-22 05:43:17 -07:00 committed by GitHub
parent 711315c3b9
commit 4ee269c3f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 3 deletions

View File

@ -5,12 +5,12 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from openhands.controller.state.state import State
from openhands.core.config import AgentConfig
from openhands.events.action import Action
from openhands.events.action.message import SystemMessageAction
from openhands.utils.prompt import PromptManager
from litellm import ChatCompletionToolParam
from openhands.core.config import AgentConfig
from openhands.core.exceptions import (
AgentAlreadyRegisteredError,
AgentNotRegisteredError,
@ -33,10 +33,13 @@ class Agent(ABC):
_registry: dict[str, type['Agent']] = {}
sandbox_plugins: list[PluginRequirement] = []
config_model: type[AgentConfig] = AgentConfig
"""Class field that specifies the config model to use for the agent. Subclasses may override with a derived config model if needed."""
def __init__(
self,
llm: LLM,
config: 'AgentConfig',
config: AgentConfig,
):
self.llm = llm
self.config = config

View File

@ -5,6 +5,7 @@ from pydantic import BaseModel, Field, ValidationError
from openhands.core.config.condenser_config import CondenserConfig, NoOpCondenserConfig
from openhands.core.config.extended_config import ExtendedConfig
from openhands.core.logger import openhands_logger as logger
from openhands.utils.import_utils import get_impl
class AgentConfig(BaseModel):
@ -98,7 +99,27 @@ class AgentConfig(BaseModel):
try:
# Merge base config with overrides
merged = {**base_config.model_dump(), **overrides}
custom_config = cls.model_validate(merged)
if merged.get('classpath'):
# if an explicit classpath is given, try to load it and look up its config model class
from openhands.controller.agent import Agent
try:
agent_cls = get_impl(Agent, merged.get('classpath'))
custom_config = agent_cls.config_model.model_validate(merged)
except Exception as e:
logger.warning(
f"Failed to load custom agent class [{merged.get('classpath')}]: {e}. Using default config model."
)
custom_config = cls.model_validate(merged)
else:
# otherwise, try to look up the agent class by name (i.e. if it's a built-in)
# if that fails, just use the default AgentConfig class.
try:
agent_cls = Agent.get_cls(name)
custom_config = agent_cls.config_model.model_validate(merged)
except Exception as e:
# otherwise, just fall back to the default config model
custom_config = cls.model_validate(merged)
agent_mapping[name] = custom_config
except ValidationError as e:
logger.warning(