@@ -168,8 +168,6 @@ which then merges both analyses into a single consolidated report.
168168
169169import os
170170
171- from pydantic import SecretStr
172-
173171from openhands.sdk import (
174172 LLM ,
175173 Agent,
@@ -179,36 +177,32 @@ from openhands.sdk import (
179177 get_logger,
180178)
181179from openhands.sdk.context import Skill
180+ from openhands.sdk.subagent import register_agent
182181from openhands.sdk.tool import register_tool
183182from openhands.tools.delegate import (
184183 DelegateTool,
185184 DelegationVisualizer,
186- register_agent,
187185)
188- from openhands.tools.preset.default import get_default_tools
186+ from openhands.tools.preset.default import get_default_tools, register_builtins_agents
189187
190188
191189ONLY_RUN_SIMPLE_DELEGATION = False
192190
193191logger = get_logger(__name__ )
194192
195193# Configure LLM and agent
196- # You can get an API key from https://app.all-hands.dev/settings/api-keys
197- api_key = os.getenv(" LLM_API_KEY" )
198- assert api_key is not None , " LLM_API_KEY environment variable is not set."
199- model = os.getenv(" LLM_MODEL" , " anthropic/claude-sonnet-4-5-20250929" )
200194llm = LLM(
201- model = model ,
202- api_key = SecretStr(api_key ),
195+ model = os.getenv( " LLM_MODEL " , " anthropic/claude-sonnet-4-5-20250929 " ) ,
196+ api_key = os.getenv( " LLM_API_KEY " ),
203197 base_url = os.environ.get(" LLM_BASE_URL" , None ),
204198 usage_id = " agent" ,
205199)
206200
207201cwd = os.getcwd()
208202
209- register_tool( " DelegateTool " , DelegateTool )
210- tools = get_default_tools( enable_browser = False )
211- tools.append(Tool( name = " DelegateTool " ) )
203+ tools = get_default_tools( enable_browser = True )
204+ tools.append(Tool( name = DelegateTool.name) )
205+ register_builtins_agents( )
212206
213207main_agent = Agent(
214208 llm = llm,
@@ -220,7 +214,7 @@ conversation = Conversation(
220214 visualizer = DelegationVisualizer(name = " Delegator" ),
221215)
222216
223- task_message = (
217+ conversation.send_message (
224218 " Forget about coding. Let's switch to travel planning. "
225219 " Let's plan a trip to London. I have two issues I need to solve: "
226220 " Lodging: what are the best areas to stay at while keeping budget in mind? "
@@ -231,7 +225,6 @@ task_message = (
231225 " They should keep it short. After getting the results, merge both analyses "
232226 " into a single consolidated report.\n\n "
233227)
234- conversation.send_message(task_message)
235228conversation.run()
236229
237230conversation.send_message(
@@ -240,18 +233,57 @@ conversation.send_message(
240233conversation.run()
241234
242235# Report cost for simple delegation example
243- cost_1 = conversation.conversation_stats.get_combined_metrics().accumulated_cost
244- print (f " EXAMPLE_COST (simple delegation): { cost_1 } " )
236+ cost_simple = conversation.conversation_stats.get_combined_metrics().accumulated_cost
237+ print (f " EXAMPLE_COST (simple delegation): { cost_simple } " )
245238
246239print (" Simple delegation example done!" , " \n " * 20 )
247240
248-
249- # -------- Agent Delegation Second Part: User-Defined Agent Types --------
250-
251241if ONLY_RUN_SIMPLE_DELEGATION :
242+ # For CI: always emit the EXAMPLE_COST marker before exiting.
243+ print (f " EXAMPLE_COST: { cost_simple} " )
252244 exit (0 )
253245
254246
247+ # -------- Agent Delegation Second Part: Built-in Agent Types (Explore + Bash) --------
248+
249+ main_agent = Agent(
250+ llm = llm,
251+ tools = [Tool(name = DelegateTool.name)],
252+ )
253+ conversation = Conversation(
254+ agent = main_agent,
255+ workspace = cwd,
256+ visualizer = DelegationVisualizer(name = " Delegator (builtins)" ),
257+ )
258+
259+ builtin_task_message = (
260+ " Demonstrate SDK built-in sub-agent types. "
261+ " 1) Spawn an 'explore' sub-agent and ask it to list the markdown files in "
262+ " openhands-sdk/openhands/sdk/subagent/builtins/ and summarize what each "
263+ " built-in agent type is for (based on the file contents). "
264+ " 2) Spawn a 'bash' sub-agent and ask it to run `python --version` in the "
265+ " terminal and return the exact output. "
266+ " 3) Merge both results into a short report. "
267+ " Do not use internet access."
268+ )
269+
270+ print (" =" * 100 )
271+ print (" Demonstrating built-in agent delegation (explore + bash)..." )
272+ print (" =" * 100 )
273+
274+ conversation.send_message(builtin_task_message)
275+ conversation.run()
276+
277+ # Report cost for builtin agent types example
278+ cost_builtin = conversation.conversation_stats.get_combined_metrics().accumulated_cost
279+ print (f " EXAMPLE_COST (builtin agents): { cost_builtin} " )
280+
281+ print (" Built-in agent delegation example done!" , " \n " * 20 )
282+
283+
284+ # -------- Agent Delegation Third Part: User-Defined Agent Types --------
285+
286+
255287def create_lodging_planner (llm : LLM ) -> Agent:
256288 """ Create a lodging planner focused on London stays."""
257289 skills = [
@@ -349,13 +381,15 @@ conversation.send_message(
349381conversation.run()
350382
351383# Report cost for user-defined agent types example
352- cost_2 = conversation.conversation_stats.get_combined_metrics().accumulated_cost
353- print (f " EXAMPLE_COST (user-defined agents): { cost_2} " )
384+ cost_user_defined = (
385+ conversation.conversation_stats.get_combined_metrics().accumulated_cost
386+ )
387+ print (f " EXAMPLE_COST (user-defined agents): { cost_user_defined} " )
354388
355389print (" All done!" )
356390
357391# Full example cost report for CI workflow
358- print (f " EXAMPLE_COST: { cost_1 + cost_2 } " )
392+ print (f " EXAMPLE_COST: { cost_simple + cost_builtin + cost_user_defined } " )
359393```
360394
361395<RunExampleCode path_to_script = " examples/01_standalone_sdk/25_agent_delegation.py" />
0 commit comments