Skip to content
Merged
12 changes: 6 additions & 6 deletions examples/01_standalone_sdk/46_agent_settings.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Create, serialize, and deserialize AgentSettings, then build a working agent.
"""Create, serialize, and deserialize LLMAgentSettings, then build a working agent.

Demonstrates:
1. Configuring an agent entirely through AgentSettings (LLM, tools, condenser).
1. Configuring an agent entirely through LLMAgentSettings (LLM, tools, condenser).
2. Serializing settings to JSON and restoring them.
3. Building an Agent from settings via ``create_agent()``.
4. Running a short conversation to prove the settings take effect.
Expand All @@ -13,7 +13,7 @@

from pydantic import SecretStr

from openhands.sdk import LLM, AgentSettings, Conversation, Tool
from openhands.sdk import LLM, Conversation, LLMAgentSettings, Tool
from openhands.sdk.settings import CondenserSettings
from openhands.tools.file_editor import FileEditorTool
from openhands.tools.terminal import TerminalTool
Expand All @@ -23,7 +23,7 @@
api_key = os.getenv("LLM_API_KEY")
assert api_key is not None, "LLM_API_KEY environment variable is not set."

settings = AgentSettings(
settings = LLMAgentSettings(
llm=LLM(
model=os.getenv("LLM_MODEL", "anthropic/claude-sonnet-4-5-20250929"),
api_key=SecretStr(api_key),
Expand All @@ -42,7 +42,7 @@
print(json.dumps(payload, indent=2, default=str)[:800], "…")
print()

restored = AgentSettings.model_validate(payload)
restored = LLMAgentSettings.model_validate(payload)
assert restored.condenser.enabled is True
assert restored.condenser.max_size == 50
assert len(restored.tools) == 2
Expand Down Expand Up @@ -73,7 +73,7 @@

# ── 4. Different settings → different behavior ───────────────────────────
# Now create settings with ONLY the terminal tool and condenser disabled.
terminal_only_settings = AgentSettings(
terminal_only_settings = LLMAgentSettings(
llm=settings.llm,
tools=[Tool(name=TerminalTool.name)],
condenser=CondenserSettings(enabled=False),
Expand Down
13 changes: 11 additions & 2 deletions openhands-agent-server/openhands/agent_server/settings_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@

from fastapi import APIRouter

from openhands.sdk.settings import AgentSettings, ConversationSettings, SettingsSchema
from openhands.sdk.settings import (
ConversationSettings,
SettingsSchema,
export_agent_settings_schema,
)


settings_router = APIRouter(prefix="/settings", tags=["Settings"])


@lru_cache(maxsize=1)
def _get_agent_settings_schema() -> SettingsSchema:
return AgentSettings.export_schema()
# ``AgentSettings`` is now a discriminated union over
# ``LLMAgentSettings`` and ``ACPAgentSettings``; the combined
# schema tags sections with a ``variant`` so the frontend can
# show LLM-only or ACP-only sections based on the active
# ``agent_kind`` value.
return export_agent_settings_schema()


@lru_cache(maxsize=1)
Expand Down
12 changes: 12 additions & 0 deletions openhands-sdk/openhands/sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@
)
from openhands.sdk.plugin import Plugin
from openhands.sdk.settings import (
ACPAgentSettings,
AgentSettings,
AgentSettingsConfig,
CondenserSettings,
ConversationSettings,
LLMAgentSettings,
SettingsChoice,
SettingsFieldSchema,
SettingsSchema,
SettingsSectionSchema,
VerificationSettings,
default_agent_settings,
export_agent_settings_schema,
export_settings_schema,
validate_agent_settings,
)
from openhands.sdk.settings.metadata import (
SettingProminence,
Expand Down Expand Up @@ -140,7 +146,13 @@
"CondenserSettings",
"ConversationSettings",
"VerificationSettings",
"ACPAgentSettings",
"AgentSettings",
"AgentSettingsConfig",
"LLMAgentSettings",
"default_agent_settings",
"export_agent_settings_schema",
"validate_agent_settings",
"SettingsChoice",
"SettingProminence",
"SettingsFieldMetadata",
Expand Down
24 changes: 24 additions & 0 deletions openhands-sdk/openhands/sdk/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,57 @@
from .model import (
AGENT_SETTINGS_SCHEMA_VERSION,
CONVERSATION_SETTINGS_SCHEMA_VERSION,
ACPAgentSettings,
AgentKind,
AgentSettings,
AgentSettingsConfig,
CondenserSettings,
ConversationSettings,
LLMAgentSettings,
SettingsChoice,
SettingsFieldSchema,
SettingsSchema,
SettingsSectionSchema,
VerificationSettings,
create_agent_from_settings,
default_agent_settings,
export_agent_settings_schema,
export_settings_schema,
validate_agent_settings,
)

_MODEL_EXPORTS = {
"AGENT_SETTINGS_SCHEMA_VERSION",
"CONVERSATION_SETTINGS_SCHEMA_VERSION",
"ACPAgentSettings",
"AgentKind",
"AgentSettings",
"AgentSettingsConfig",
"CondenserSettings",
"ConversationSettings",
"LLMAgentSettings",
"SettingsChoice",
"SettingsFieldSchema",
"SettingsSchema",
"SettingsSectionSchema",
"VerificationSettings",
"create_agent_from_settings",
"default_agent_settings",
"export_agent_settings_schema",
"export_settings_schema",
"validate_agent_settings",
}

__all__ = [
"AGENT_SETTINGS_SCHEMA_VERSION",
"CONVERSATION_SETTINGS_SCHEMA_VERSION",
"ACPAgentSettings",
"AgentKind",
"AgentSettings",
"AgentSettingsConfig",
"CondenserSettings",
"ConversationSettings",
"LLMAgentSettings",
"SETTINGS_METADATA_KEY",
"SETTINGS_SECTION_METADATA_KEY",
"SettingProminence",
Expand All @@ -57,8 +77,12 @@
"SettingsSectionMetadata",
"SettingsSectionSchema",
"VerificationSettings",
"create_agent_from_settings",
"default_agent_settings",
"export_agent_settings_schema",
"export_settings_schema",
"field_meta",
"validate_agent_settings",
]


Expand Down
5 changes: 5 additions & 0 deletions openhands-sdk/openhands/sdk/settings/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@ class SettingProminence(str, Enum):
class SettingsSectionMetadata(BaseModel):
key: str
label: str | None = None
variant: str | None = None


class SettingsFieldMetadata(BaseModel):
label: str | None = None
prominence: SettingProminence = SettingProminence.MINOR
depends_on: tuple[str, ...] = ()
variant: str | None = None
"""When set, the field only applies to the named ``AgentSettings``
variant (``"llm"`` or ``"acp"``). Fields with ``variant=None`` are
shown regardless of the active ``agent_kind``."""


def field_meta(
Expand Down
Loading
Loading