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
107 changes: 107 additions & 0 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 All @@ -53,6 +53,10 @@
| `skills` | No | `[]` | List of skill names for this agent (see [Skill Loading Precedence](/overview/skills#skill-loading-precedence) for resolution order). |
| `max_iteration_per_run` | No | `None`| Maximum iterations per run. Must be strictly positive, or `None` for the default value. |
| `color` | No | `None` | [Rich color name](https://rich.readthedocs.io/en/stable/appendix/colors.html) (e.g., `"blue"`, `"green"`) used by visualizers to style this agent's output in terminal panels |
| `mcp_servers` | No | `None` | MCP server configurations for this agent (see [MCP Servers](#mcp-servers)) |
| `hooks` | No | `None` | Hook configuration for lifecycle events (see [Hooks](#hooks)) |
| `permission_mode` | No | `None` | Controls how the subagent handles action confirmations (see [Permission Mode](#permission-mode)) |
| `profile_store_dir` | No | `None` | Custom directory path for LLM profiles when using a named `model` |

### `<example>` Tags

Expand Down Expand Up @@ -162,23 +166,23 @@
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 169 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#L169

Did you really mean 'deduplicates'?

## Manual Loading

For more control, load and register agents explicitly:

```python icon="python" focus={3-6, 8-14}
from pathlib import Path

Check warning on line 176 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#L176

Did you really mean 'pathlib'?

from openhands.sdk import load_agents_from_dir, register_agent, agent_definition_to_factory

# Load from a specific directory
agents_dir = Path("agents")

Check warning on line 181 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#L181

Did you really mean 'agents_dir'?
agent_definitions = load_agents_from_dir(agents_dir)

Check warning on line 182 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#L182

Did you really mean 'agent_definitions'?

# Register each agent
for agent_def in agent_definitions:

Check warning on line 185 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#L185

Did you really mean 'agent_def'?

Check warning on line 185 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#L185

Did you really mean 'agent_definitions'?
register_agent(
name=agent_def.name,
factory_func=agent_definition_to_factory(agent_def),
Expand Down Expand Up @@ -214,7 +218,7 @@
```

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

Check warning on line 221 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#L221

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 All @@ -225,8 +229,8 @@
```python icon="python" focus={3, 4}
from openhands.sdk.subagent import load_project_agents, load_user_agents

project_agents = load_project_agents("/path/to/project")

Check warning on line 232 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#L232

Did you really mean 'project_agents'?
user_agents = load_user_agents() # scans ~/.agents/agents/ and ~/.openhands/agents/

Check warning on line 233 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#L233

Did you really mean 'user_agents'?
```

## Using with Delegation
Expand Down Expand Up @@ -310,6 +314,109 @@
Always include a usage example with expected output when documenting functions or APIs.
```

## Advanced Features

### MCP Servers

File-based agents can define [MCP server configurations](/sdk/guides/mcp) inline, giving them access to external tools without any Python code:

```markdown icon="markdown"
---
name: web-researcher
description: Researches topics using web fetching capabilities.
tools:
- file_editor
mcp_servers:
fetch:
command: uvx
args:
- mcp-server-fetch
filesystem:
command: npx
args:
- -y
- "@modelcontextprotocol/server-filesystem"
---

You are a web researcher with access to fetch and filesystem tools.
Use the fetch tool to retrieve web content and save findings to files.
```

The `mcp_servers` field uses the same format as the [MCP configuration](/sdk/guides/mcp) — each key is a server name, and the value contains `command` and `args` for launching the server.

### Hooks

File-based agents can define [lifecycle hooks](/sdk/guides/hooks) that run at specific points during execution:

```markdown icon="markdown"
---
name: audited-agent
description: An agent with audit logging hooks.
tools:
- terminal
- file_editor
hooks:
pre_tool_use:
- matcher: "terminal"
hooks:
- command: "./scripts/validate_command.sh"
timeout: 10
post_tool_use:
- matcher: "*"
hooks:
- command: "./scripts/log_tool_usage.sh"
timeout: 5
---

You are an audited agent. All your actions are logged for compliance.
```

**Hook event types:**
- `pre_tool_use` — Runs before tool execution (can block with exit code 2)
- `post_tool_use` — Runs after tool execution
- `user_prompt_submit` — Runs before processing user messages
- `session_start` / `session_end` — Run when conversation starts/ends
- `stop` — Runs when agent tries to finish (can block)

Each hook matcher supports:
- `"*"` — Matches all tools
- Exact name — e.g., `"terminal"` matches only that tool
- Regex patterns — e.g., `"/file_.*/"` matches tools starting with `file_`

For more details on hooks, see the [Hooks guide](/sdk/guides/hooks).

### Permission Mode

Control how a file-based agent handles action confirmations with the `permission_mode` field:

```markdown icon="markdown"
---
name: autonomous-agent
description: Runs without requiring user confirmation.
tools:
- terminal
- file_editor
permission_mode: never_confirm
---

You are an autonomous agent that executes tasks without manual approval.
```

**Available modes:**
| Mode | Behavior |
|------|----------|
| `always_confirm` | Requires user approval for **all** actions |
| `never_confirm` | Executes all actions without approval |
| `confirm_risky` | Only requires approval for actions above a risk threshold (requires a [security analyzer](/sdk/guides/security)) |

When `permission_mode` is omitted (or set to `None`), the subagent inherits the confirmation policy from its parent conversation.

<Note>
Permission mode is particularly useful for specialized sub-agents. For example, a "read-only explorer" agent might use `never_confirm` since it only reads files, while a "deploy" agent might use `always_confirm` for safety.
</Note>

For more details on security and confirmation policies, see the [Security guide](/sdk/guides/security).

## Agents in Plugins

> Plugins bundle agents, tools, skills, and MCP servers into reusable packages.
Expand Down
Loading