Summary
The SDK already has well-structured settings models (OpenHandsAgentSettings, ACPAgentSettings, ConversationSettings) with schema versioning, migration support (from_persisted()), and form-schema export (export_schema()). However, the agent-server never actually persists or loads these settings. The settings_router.py only serves schema metadata (GET /settings/agent-schema, GET /settings/conversation-schema) — it tells the frontend what fields exist but never reads or writes actual values.
This means:
- There is no settings file on disk
- The frontend cannot save or retrieve user preferences
- Every
StartConversationRequest must provide the full Agent configuration inline — there are no "use my saved settings" defaults
What's Needed
1. A settings file path in the agent-server Config
Add a configurable settings_path: Path (defaulting to e.g. workspace/settings/ or ~/.openhands/settings/) to the agent-server Config model so the server knows where to read/write settings files.
2. GET /settings/agent — Load persisted agent settings
Return the currently persisted AgentSettings values from disk. If no file exists, return the defaults from default_agent_settings(). Use AgentSettings.from_persisted(data) to handle any schema migrations on load.
3. PUT /settings/agent — Save agent settings to disk
Accept an AgentSettingsConfig payload (the discriminated union of OpenHandsAgentSettings | ACPAgentSettings), validate it via validate_agent_settings(), and persist it to disk using model_dump() with the current schema_version.
4. GET /settings/conversation — Load persisted conversation settings
Return the currently persisted ConversationSettings values from disk. If no file exists, return defaults. Use ConversationSettings.from_persisted(data) for migration support.
5. PUT /settings/conversation — Save conversation settings to disk
Accept a ConversationSettings payload, validate, and persist to disk.
6. Default settings injection into conversation creation
When StartConversationRequest is received without an explicit agent (or with partial config), the agent-server should load the persisted settings and use ConversationSettings.create_request() to fill in defaults. This closes the loop: settings saved via the UI automatically apply to new conversations.
Context
The SDK plumbing is ready:
ConversationSettings has schema_version, from_persisted(), create_request(), and model_dump()
AgentSettings (discriminated union) has from_persisted(), schema_version, migrations via _apply_persisted_migrations
OpenHandsAgentSettings.create_agent() and ACPAgentSettings.create_agent() build fully configured agent objects from settings
- The migration framework (
_AGENT_SETTINGS_MIGRATIONS, _CONVERSATION_SETTINGS_MIGRATIONS) supports forward-compatible schema evolution
This is a key requirement for the agent-server: "Settings are persisted to disk".
Summary
The SDK already has well-structured settings models (
OpenHandsAgentSettings,ACPAgentSettings,ConversationSettings) with schema versioning, migration support (from_persisted()), and form-schema export (export_schema()). However, the agent-server never actually persists or loads these settings. Thesettings_router.pyonly serves schema metadata (GET /settings/agent-schema,GET /settings/conversation-schema) — it tells the frontend what fields exist but never reads or writes actual values.This means:
StartConversationRequestmust provide the fullAgentconfiguration inline — there are no "use my saved settings" defaultsWhat's Needed
1. A settings file path in the agent-server
ConfigAdd a configurable
settings_path: Path(defaulting to e.g.workspace/settings/or~/.openhands/settings/) to the agent-serverConfigmodel so the server knows where to read/write settings files.2.
GET /settings/agent— Load persisted agent settingsReturn the currently persisted
AgentSettingsvalues from disk. If no file exists, return the defaults fromdefault_agent_settings(). UseAgentSettings.from_persisted(data)to handle any schema migrations on load.3.
PUT /settings/agent— Save agent settings to diskAccept an
AgentSettingsConfigpayload (the discriminated union ofOpenHandsAgentSettings | ACPAgentSettings), validate it viavalidate_agent_settings(), and persist it to disk usingmodel_dump()with the currentschema_version.4.
GET /settings/conversation— Load persisted conversation settingsReturn the currently persisted
ConversationSettingsvalues from disk. If no file exists, return defaults. UseConversationSettings.from_persisted(data)for migration support.5.
PUT /settings/conversation— Save conversation settings to diskAccept a
ConversationSettingspayload, validate, and persist to disk.6. Default settings injection into conversation creation
When
StartConversationRequestis received without an explicit agent (or with partial config), the agent-server should load the persisted settings and useConversationSettings.create_request()to fill in defaults. This closes the loop: settings saved via the UI automatically apply to new conversations.Context
The SDK plumbing is ready:
ConversationSettingshasschema_version,from_persisted(),create_request(), andmodel_dump()AgentSettings(discriminated union) hasfrom_persisted(),schema_version, migrations via_apply_persisted_migrationsOpenHandsAgentSettings.create_agent()andACPAgentSettings.create_agent()build fully configured agent objects from settings_AGENT_SETTINGS_MIGRATIONS,_CONVERSATION_SETTINGS_MIGRATIONS) supports forward-compatible schema evolutionThis is a key requirement for the agent-server: "Settings are persisted to disk".