Skip to content

Commit 7948984

Browse files
feat(settings): add enable_sub_agents toggle to LLMAgentSettings (#2948)
Co-authored-by: openhands <openhands@all-hands.dev>
1 parent ab0e17b commit 7948984

3 files changed

Lines changed: 28 additions & 2 deletions

File tree

openhands-sdk/openhands/sdk/settings/model.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,17 @@ class LLMAgentSettings(BaseModel):
646646
).model_dump()
647647
},
648648
)
649+
enable_sub_agents: bool = Field(
650+
default=False,
651+
description="Enable sub-agent delegation via TaskToolSet.",
652+
json_schema_extra={
653+
SETTINGS_METADATA_KEY: SettingsFieldMetadata(
654+
label="Enable sub-agents",
655+
prominence=SettingProminence.MAJOR,
656+
variant="llm",
657+
).model_dump()
658+
},
659+
)
649660
mcp_config: MCPConfig | None = Field(
650661
default=None,
651662
description="MCP server configuration for the agent.",

openhands-tools/openhands/tools/preset/default.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ def register_default_tools(enable_browser: bool = True) -> None:
3535

3636
def get_default_tools(
3737
enable_browser: bool = True,
38+
enable_sub_agents: bool = False,
3839
) -> list[Tool]:
3940
"""Get the default set of tool specifications for the standard experience.
4041
4142
Args:
4243
enable_browser: Whether to include browser tools.
44+
enable_sub_agents: Whether to include the TaskToolSet for
45+
sub-agent delegation.
4346
"""
4447
register_default_tools(enable_browser=enable_browser)
4548

@@ -57,6 +60,10 @@ def get_default_tools(
5760
from openhands.tools.browser_use import BrowserToolSet
5861

5962
tools.append(Tool(name=BrowserToolSet.name))
63+
if enable_sub_agents:
64+
from openhands.tools.task import TaskToolSet
65+
66+
tools.append(Tool(name=TaskToolSet.name))
6067
return tools
6168

6269

tests/sdk/test_settings.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,20 @@ def test_llm_agent_settings_export_schema_groups_sections() -> None:
5656

5757
# -- general section (top-level scalar fields) --
5858
general_fields = {f.key: f for f in sections["general"].fields}
59-
assert set(general_fields) == {"agent", "tools", "mcp_config"}
59+
assert set(general_fields) == {
60+
"agent",
61+
"tools",
62+
"enable_sub_agents",
63+
"mcp_config",
64+
}
6065
assert general_fields["agent"].default == "CodeActAgent"
6166
assert general_fields["agent"].prominence is SettingProminence.MAJOR
6267
assert general_fields["tools"].value_type == "array"
6368
assert general_fields["tools"].default == []
6469
assert general_fields["tools"].prominence is SettingProminence.MAJOR
70+
assert general_fields["enable_sub_agents"].value_type == "boolean"
71+
assert general_fields["enable_sub_agents"].default is False
72+
assert general_fields["enable_sub_agents"].prominence is SettingProminence.MAJOR
6573

6674
# -- llm section --
6775
llm_fields = {f.key: f for f in sections["llm"].fields}
@@ -237,7 +245,7 @@ def test_export_agent_settings_schema_emits_variant_tagged_sections() -> None:
237245
general = by_keyvariant.get(("general", None))
238246
assert general is not None
239247
general_keys = {f.key for f in general.fields}
240-
assert general_keys == {"agent", "tools", "mcp_config"}
248+
assert general_keys == {"agent", "tools", "enable_sub_agents", "mcp_config"}
241249
# No agent_kind field — each variant has its own settings page and
242250
# injects the discriminator on save.
243251
assert "agent_kind" not in general_keys

0 commit comments

Comments
 (0)