Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions sdk/guides/agent-file-based.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: File-Based Agents
description: Define specialized sub-agents as simple Markdown files with YAML frontmatter — no Python code required.

Check warning on line 3 in sdk/guides/agent-file-based.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

sdk/guides/agent-file-based.mdx#L3

Did you really mean 'frontmatter'?
---

import RunExampleCode from "/sdk/shared-snippets/how-to-run-example.mdx";
Expand All @@ -13,7 +13,7 @@

## Agent File Format

An agent is a single `.md` file with YAML frontmatter and a Markdown body:

Check warning on line 16 in sdk/guides/agent-file-based.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

sdk/guides/agent-file-based.mdx#L16

Did you really mean 'frontmatter'?

```markdown icon="markdown"
---
Expand All @@ -40,9 +40,9 @@
Keep feedback concise and actionable. For each issue, suggest a fix.
```

The YAML frontmatter configures the agent. The Markdown body becomes the agent's system prompt.

Check warning on line 43 in sdk/guides/agent-file-based.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

sdk/guides/agent-file-based.mdx#L43

Did you really mean 'frontmatter'?

### Frontmatter Fields

Check warning on line 45 in sdk/guides/agent-file-based.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

sdk/guides/agent-file-based.mdx#L45

Did you really mean 'Frontmatter'?

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
Expand Down Expand Up @@ -101,15 +101,42 @@

## Built-in Agents

The SDK ships with built-in agents that are automatically loaded at the beginning of each conversation and are available to the user.
The `openhands-tools` package ships with built-in sub-agents as Markdown files in `openhands/tools/preset/subagents/`.
They can be registered via `register_builtins_agents()` and become available for delegation tasks.

By default, agents include `FinishTool` and `ThinkTool`; they are appended after tool filtering.
By default, all agents include `finish` tool and the `think` tool.

The table below summarizes all available built-in agents:
### Available Built-in Sub-Agents

| Agent | Tools | Description |
|--------|-------|-------|
| **default** | `terminal`, `file_editor`, `task_tracker`, `browser_tool_set` | general purpose agent |
| **default** | `terminal`, `file_editor`, `task_tracker`, `browser_tool_set` | General-purpose agent. Used as the fallback when no agent name is specified. |
| **default cli mode** | `terminal`, `file_editor`, `task_tracker` | Same as `default` but without browser tools (used in CLI mode). |
| **explore** | `terminal` | Read-only codebase exploration agent. Finds files, searches code, reads source — never creates or modifies anything. |
| **bash** | `terminal` | Command execution specialist. Runs shell commands, builds, tests, and git operations. |

In CLI mode, the `default` agent (with browser tools) is replaced by the `default cli mode` agent. In non-CLI mode, `default cli mode` is filtered out.

### Registering Built-in Sub-Agents

Call `register_builtins_agents()` to register all built-in sub-agents. This is typically done once before creating a conversation:

```python icon="python" focus={3-4, 6-7}
from openhands.tools.preset.default import register_builtins_agents

# Register built-in sub-agents (default, explore, bash)
register_builtins_agents()

# Or in CLI mode (swaps default for default cli mode — no browser)
register_builtins_agents(cli_mode=True)
```

<Warning>
Registration order is critical when programmatically registering agents that share a name with a built-in agent. The system is designed to skip registration if a name is already taken. Therefore, if you register your custom agents before the built-in agents are loaded, your custom versions will take precedence.

Conversely, if the built-in agents are loaded first, they will take precedence, and any subsequent registration of a custom agent with the same name will be ignored.
</Warning>


## Overall Priority

Expand All @@ -120,8 +147,7 @@
| 1 (highest) | **Programmatic** `register_agent()` | Registered first, never overwritten |
| 2 | **Plugin agents** (`Plugin.agents`) | Loaded from plugin `agents/` directories |
| 3 | **Project-level** file-based agents | `.agents/agents/*.md` or `.openhands/agents/*.md` |
| 4 | **User-level** file-based agents | `~/.agents/agents/*.md` or `~/.openhands/agents/*.md` |
| 5 (lowest) | **Built-in agents** | SDK built-in agents |
| 4 (lowest) | **User-level** file-based agents | `~/.agents/agents/*.md` or `~/.openhands/agents/*.md` |

## Auto-Registration

Expand All @@ -134,7 +160,7 @@
print(f"Registered {len(agent_names)} agents: {agent_names}")
```

This scans both project-level and user-level directories, deduplicates by name, and registers each agent as a delegate that can be spawned by the orchestrator.

Check warning on line 163 in sdk/guides/agent-file-based.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

sdk/guides/agent-file-based.mdx#L163

Did you really mean 'deduplicates'?

## Manual Loading

Expand Down Expand Up @@ -186,7 +212,7 @@
```

The factory:
- Maps tool names from the frontmatter to `Tool` objects

Check warning on line 215 in sdk/guides/agent-file-based.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

sdk/guides/agent-file-based.mdx#L215

Did you really mean 'frontmatter'?
- Appends the Markdown body to the parent system message via `AgentContext(system_message_suffix=...)`
- Respects the `model` field (`"inherit"` keeps the parent LLM; an explicit model name creates a copy)

Expand Down
Loading