mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
from pydantic import (
|
|
BaseModel,
|
|
Field,
|
|
SecretStr,
|
|
SerializationInfo,
|
|
field_serializer,
|
|
model_validator,
|
|
)
|
|
from pydantic.json import pydantic_encoder
|
|
|
|
from openhands.core.config.llm_config import LLMConfig
|
|
from openhands.core.config.utils import load_app_config
|
|
from openhands.storage.data_models.user_secrets import UserSecrets
|
|
|
|
|
|
class Settings(BaseModel):
|
|
"""
|
|
Persisted settings for OpenHands sessions
|
|
"""
|
|
|
|
language: str | None = None
|
|
agent: str | None = None
|
|
max_iterations: int | None = None
|
|
security_analyzer: str | None = None
|
|
confirmation_mode: bool | None = None
|
|
llm_model: str | None = None
|
|
llm_api_key: SecretStr | None = None
|
|
llm_base_url: str | None = None
|
|
remote_runtime_resource_factor: int | None = None
|
|
# Planned to be removed from settings
|
|
secrets_store: UserSecrets = Field(default_factory=UserSecrets, frozen=True)
|
|
enable_default_condenser: bool = True
|
|
enable_sound_notifications: bool = False
|
|
user_consents_to_analytics: bool | None = None
|
|
sandbox_base_container_image: str | None = None
|
|
sandbox_runtime_container_image: str | None = None
|
|
|
|
model_config = {
|
|
'validate_assignment': True,
|
|
}
|
|
|
|
@field_serializer('llm_api_key')
|
|
def llm_api_key_serializer(self, llm_api_key: SecretStr, info: SerializationInfo):
|
|
"""Custom serializer for the LLM API key.
|
|
|
|
To serialize the API key instead of ********, set expose_secrets to True in the serialization context.
|
|
"""
|
|
context = info.context
|
|
if context and context.get('expose_secrets', False):
|
|
return llm_api_key.get_secret_value()
|
|
|
|
return pydantic_encoder(llm_api_key) if llm_api_key else None
|
|
|
|
@model_validator(mode='before')
|
|
@classmethod
|
|
def convert_provider_tokens(cls, data: dict | object) -> dict | object:
|
|
"""Convert provider tokens from JSON format to UserSecrets format."""
|
|
if not isinstance(data, dict):
|
|
return data
|
|
|
|
secrets_store = data.get('secrets_store')
|
|
if not isinstance(secrets_store, dict):
|
|
return data
|
|
|
|
custom_secrets = secrets_store.get('custom_secrets')
|
|
tokens = secrets_store.get('provider_tokens')
|
|
|
|
secret_store = UserSecrets(provider_tokens={}, custom_secrets={})
|
|
|
|
if isinstance(tokens, dict):
|
|
converted_store = UserSecrets(provider_tokens=tokens)
|
|
secret_store = secret_store.model_copy(
|
|
update={'provider_tokens': converted_store.provider_tokens}
|
|
)
|
|
else:
|
|
secret_store.model_copy(update={'provider_tokens': tokens})
|
|
|
|
if isinstance(custom_secrets, dict):
|
|
converted_store = UserSecrets(custom_secrets=custom_secrets)
|
|
secret_store = secret_store.model_copy(
|
|
update={'custom_secrets': converted_store.custom_secrets}
|
|
)
|
|
else:
|
|
secret_store = secret_store.model_copy(
|
|
update={'custom_secrets': custom_secrets}
|
|
)
|
|
data['secret_store'] = secret_store
|
|
return data
|
|
|
|
@field_serializer('secrets_store')
|
|
def secrets_store_serializer(self, secrets: UserSecrets, info: SerializationInfo):
|
|
"""Custom serializer for secrets store."""
|
|
|
|
"""Force invalidate secret store"""
|
|
return {
|
|
'provider_tokens': {}
|
|
}
|
|
|
|
@staticmethod
|
|
def from_config() -> Settings | None:
|
|
app_config = load_app_config()
|
|
llm_config: LLMConfig = app_config.get_llm_config()
|
|
if llm_config.api_key is None:
|
|
# If no api key has been set, we take this to mean that there is no reasonable default
|
|
return None
|
|
security = app_config.security
|
|
settings = Settings(
|
|
language='en',
|
|
agent=app_config.default_agent,
|
|
max_iterations=app_config.max_iterations,
|
|
security_analyzer=security.security_analyzer,
|
|
confirmation_mode=security.confirmation_mode,
|
|
llm_model=llm_config.model,
|
|
llm_api_key=llm_config.api_key,
|
|
llm_base_url=llm_config.base_url,
|
|
remote_runtime_resource_factor=app_config.sandbox.remote_runtime_resource_factor,
|
|
)
|
|
return settings
|