Fix Pydantic class-based config deprecation warnings (#9279)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Graham Neubig
2025-06-23 15:10:38 -04:00
committed by GitHub
parent a156d5d243
commit 7b0f880860
16 changed files with 55 additions and 52 deletions

View File

@@ -1,6 +1,6 @@
from __future__ import annotations
from pydantic import BaseModel, Field, ValidationError
from pydantic import BaseModel, ConfigDict, Field, ValidationError
from openhands.core.config.condenser_config import CondenserConfig, NoOpCondenserConfig
from openhands.core.config.extended_config import ExtendedConfig
@@ -47,7 +47,7 @@ class AgentConfig(BaseModel):
extended: ExtendedConfig = Field(default_factory=lambda: ExtendedConfig({}))
"""Extended configuration for the agent."""
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
@classmethod
def from_toml_section(cls, data: dict) -> dict[str, AgentConfig]:

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Literal, cast
from pydantic import BaseModel, Field, ValidationError
from pydantic import BaseModel, ConfigDict, Field, ValidationError
from openhands.core import logger
from openhands.core.config.llm_config import LLMConfig
@@ -13,7 +13,7 @@ class NoOpCondenserConfig(BaseModel):
type: Literal['noop'] = Field('noop')
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class ObservationMaskingCondenserConfig(BaseModel):
@@ -26,7 +26,7 @@ class ObservationMaskingCondenserConfig(BaseModel):
ge=1,
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class BrowserOutputCondenserConfig(BaseModel):
@@ -55,7 +55,7 @@ class RecentEventsCondenserConfig(BaseModel):
default=100, description='Maximum number of events to keep.', ge=1
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class LLMSummarizingCondenserConfig(BaseModel):
@@ -82,7 +82,7 @@ class LLMSummarizingCondenserConfig(BaseModel):
description='Maximum length of the event representations to be passed to the LLM.',
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class AmortizedForgettingCondenserConfig(BaseModel):
@@ -102,7 +102,7 @@ class AmortizedForgettingCondenserConfig(BaseModel):
ge=0,
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class LLMAttentionCondenserConfig(BaseModel):
@@ -125,7 +125,7 @@ class LLMAttentionCondenserConfig(BaseModel):
ge=0,
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class StructuredSummaryCondenserConfig(BaseModel):
@@ -152,7 +152,7 @@ class StructuredSummaryCondenserConfig(BaseModel):
description='Maximum length of the event representations to be passed to the LLM.',
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class CondenserPipelineConfig(BaseModel):
@@ -167,7 +167,7 @@ class CondenserPipelineConfig(BaseModel):
description='List of condenser configurations to be used in the pipeline.',
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
# Type alias for convenience

View File

@@ -1,4 +1,4 @@
from pydantic import BaseModel, Field, ValidationError
from pydantic import BaseModel, ConfigDict, Field, ValidationError
class KubernetesConfig(BaseModel):
@@ -62,7 +62,7 @@ class KubernetesConfig(BaseModel):
description='Run the runtime sandbox container in privileged mode for use with docker-in-docker',
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
@classmethod
def from_toml_section(cls, data: dict) -> dict[str, 'KubernetesConfig']:

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
import os
from typing import Any
from pydantic import BaseModel, Field, SecretStr, ValidationError
from pydantic import BaseModel, ConfigDict, Field, SecretStr, ValidationError
from openhands.core.logger import LOG_DIR
from openhands.core.logger import openhands_logger as logger
@@ -92,7 +92,7 @@ class LLMConfig(BaseModel):
description='Safety settings for models that support them (like Mistral AI and Gemini)',
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
@classmethod
def from_toml_section(cls, data: dict) -> dict[str, LLMConfig]:

View File

@@ -2,7 +2,7 @@ import os
from typing import TYPE_CHECKING
from urllib.parse import urlparse
from pydantic import BaseModel, Field, ValidationError, model_validator
from pydantic import BaseModel, ConfigDict, Field, ValidationError, model_validator
if TYPE_CHECKING:
from openhands.core.config.openhands_config import OpenHandsConfig
@@ -72,7 +72,7 @@ class MCPConfig(BaseModel):
stdio_servers: list[MCPStdioServerConfig] = Field(default_factory=list)
shttp_servers: list[MCPSHTTPServerConfig] = Field(default_factory=list)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
@staticmethod
def _normalize_servers(servers_data: list[dict | str]) -> list[dict]:

View File

@@ -1,7 +1,7 @@
import os
from typing import Any, ClassVar
from pydantic import BaseModel, Field, SecretStr
from pydantic import BaseModel, ConfigDict, Field, SecretStr
from openhands.core import logger
from openhands.core.config.agent_config import AgentConfig
@@ -114,7 +114,7 @@ class OpenHandsConfig(BaseModel):
defaults_dict: ClassVar[dict] = {}
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
def get_llm_config(self, name: str = 'llm') -> LLMConfig:
"""'llm' is the name for default config (for backward compatibility prior to 0.8)."""

View File

@@ -1,6 +1,6 @@
import os
from pydantic import BaseModel, Field, ValidationError, model_validator
from pydantic import BaseModel, ConfigDict, Field, ValidationError, model_validator
class SandboxConfig(BaseModel):
@@ -88,7 +88,7 @@ class SandboxConfig(BaseModel):
description="Volume mounts in the format 'host_path:container_path[:mode]', e.g. '/my/host/dir:/workspace:rw'. Multiple mounts can be specified using commas, e.g. '/path1:/workspace/path1,/path2:/workspace/path2:ro'",
)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
@classmethod
def from_toml_section(cls, data: dict) -> dict[str, 'SandboxConfig']:

View File

@@ -1,4 +1,4 @@
from pydantic import BaseModel, Field, ValidationError
from pydantic import BaseModel, ConfigDict, Field, ValidationError
class SecurityConfig(BaseModel):
@@ -12,7 +12,7 @@ class SecurityConfig(BaseModel):
confirmation_mode: bool = Field(default=False)
security_analyzer: str | None = Field(default=None)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
@classmethod
def from_toml_section(cls, data: dict) -> dict[str, 'SecurityConfig']:

View File

@@ -5,6 +5,7 @@ from typing import Annotated, Any, Coroutine, Literal, overload
from pydantic import (
BaseModel,
ConfigDict,
Field,
SecretStr,
WithJsonSchema,
@@ -34,10 +35,10 @@ class ProviderToken(BaseModel):
user_id: str | None = Field(default=None)
host: str | None = Field(default=None)
model_config = {
'frozen': True, # Makes the entire model immutable
'validate_assignment': True,
}
model_config = ConfigDict(
frozen=True, # Makes the entire model immutable
validate_assignment=True,
)
@classmethod
def from_value(cls, token_value: ProviderToken | dict[str, str]) -> ProviderToken:
@@ -62,10 +63,10 @@ class CustomSecret(BaseModel):
secret: SecretStr = Field(default_factory=lambda: SecretStr(''))
description: str = Field(default='')
model_config = {
'frozen': True, # Makes the entire model immutable
'validate_assignment': True,
}
model_config = ConfigDict(
frozen=True, # Makes the entire model immutable
validate_assignment=True,
)
@classmethod
def from_value(cls, secret_value: CustomSecret | dict[str, str]) -> CustomSecret:

View File

@@ -4,7 +4,7 @@ from fastmcp import Client
from fastmcp.client.transports import SSETransport, StreamableHttpTransport
from mcp import McpError
from mcp.types import CallToolResult
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field
from openhands.core.config.mcp_config import MCPSHTTPServerConfig, MCPSSEServerConfig
from openhands.core.logger import openhands_logger as logger
@@ -16,14 +16,13 @@ class MCPClient(BaseModel):
A collection of tools that connects to an MCP server and manages available tools through the Model Context Protocol.
"""
model_config = ConfigDict(arbitrary_types_allowed=True)
client: Optional[Client] = None
description: str = 'MCP client tools for server interaction'
tools: list[MCPClientTool] = Field(default_factory=list)
tool_map: dict[str, MCPClientTool] = Field(default_factory=dict)
class Config:
arbitrary_types_allowed = True
async def _initialize_and_list_tools(self) -> None:
"""Initialize session and populate tool map."""
if not self.client:

View File

@@ -1,4 +1,5 @@
from mcp.types import Tool
from pydantic import ConfigDict
class MCPClientTool(Tool):
@@ -9,8 +10,7 @@ class MCPClientTool(Tool):
by the MCPClient for each operation.
"""
class Config:
arbitrary_types_allowed = True
model_config = ConfigDict(arbitrary_types_allowed=True)
def to_param(self) -> dict:
"""Convert tool to function call format."""

View File

@@ -7,7 +7,7 @@ from datetime import datetime, timezone
from fastapi import APIRouter, Depends, status
from fastapi.responses import JSONResponse
from jinja2 import Environment, FileSystemLoader
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field
from openhands.core.config.llm_config import LLMConfig
from openhands.core.logger import openhands_logger as logger
@@ -88,7 +88,7 @@ class InitSessionRequest(BaseModel):
if os.getenv('ALLOW_SET_CONVERSATION_ID', '0') == '1':
conversation_id: str = Field(default_factory=lambda: uuid.uuid4().hex)
model_config = {'extra': 'forbid'}
model_config = ConfigDict(extra='forbid')
class ConversationResponse(BaseModel):

View File

@@ -1,4 +1,4 @@
from pydantic import Field
from pydantic import ConfigDict, Field
from openhands.integrations.provider import CUSTOM_SECRETS_TYPE, PROVIDER_TOKEN_TYPE
from openhands.integrations.service_types import ProviderType
@@ -18,6 +18,6 @@ class ConversationInitData(Settings):
conversation_instructions: str | None = Field(default=None)
git_provider: ProviderType | None = Field(default=None)
model_config = {
'arbitrary_types_allowed': True,
}
model_config = ConfigDict(
arbitrary_types_allowed=True,
)

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from pydantic import (
BaseModel,
ConfigDict,
SecretStr,
)
@@ -39,7 +40,7 @@ class GETSettingsModel(Settings):
llm_api_key_set: bool
search_api_key_set: bool = False
model_config = {'use_enum_values': True}
model_config = ConfigDict(use_enum_values=True)
class CustomSecretWithoutValueModel(BaseModel):

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from pydantic import (
BaseModel,
ConfigDict,
Field,
SecretStr,
SerializationInfo,
@@ -45,9 +46,9 @@ class Settings(BaseModel):
email: str | None = None
email_verified: bool | None = None
model_config = {
'validate_assignment': True,
}
model_config = ConfigDict(
validate_assignment=True,
)
@field_serializer('llm_api_key', 'search_api_key')
def api_key_serializer(self, api_key: SecretStr | None, info: SerializationInfo):

View File

@@ -3,6 +3,7 @@ from typing import Any
from pydantic import (
BaseModel,
ConfigDict,
Field,
SerializationInfo,
field_serializer,
@@ -31,11 +32,11 @@ class UserSecrets(BaseModel):
default_factory=lambda: MappingProxyType({})
)
model_config = {
'frozen': True,
'validate_assignment': True,
'arbitrary_types_allowed': True,
}
model_config = ConfigDict(
frozen=True,
validate_assignment=True,
arbitrary_types_allowed=True,
)
@field_serializer('provider_tokens')
def provider_tokens_serializer(